refactor(doc-item): IDocItem-Typ durch Doc-Modell aus API ersetzen
This commit is contained in:
parent
8ad250f227
commit
a5e32d0d39
@ -15,14 +15,14 @@ export type DocQuery = {
|
|||||||
name?: string | undefined
|
name?: string | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDocuments({ id, name }: DocQuery): Promise<Doc[]> {
|
export function getDocuments(query: DocQuery | undefined = undefined): Promise<Doc[]> {
|
||||||
let documents = _documents;
|
let documents = _documents;
|
||||||
|
|
||||||
if (id)
|
if (query?.id)
|
||||||
documents = documents.filter(d => d.id = id)
|
documents = documents.filter(d => d.id === query.id);
|
||||||
|
|
||||||
if (name)
|
if (query?.name)
|
||||||
documents = documents.filter(d => d.name = name)
|
documents = documents.filter(d => d.name === query.name);
|
||||||
|
|
||||||
return Promise.resolve(documents);
|
return Promise.resolve(documents);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,27 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { _posts } from 'src/_mock';
|
import { _posts } from 'src/_mock';
|
||||||
import { CONFIG } from 'src/config-global';
|
import { CONFIG } from 'src/config-global';
|
||||||
|
import { Doc, getDocuments } from 'src/api/document-service';
|
||||||
|
|
||||||
import { DocSearchView } from 'src/sections/document/view';
|
import { DocSearchView } from 'src/sections/document/view';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
const [docs, setDocs] = useState<Doc[]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getDocuments({}).then((res) => {
|
||||||
|
setDocs(res);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<title>{`Document Search - ${CONFIG.appName}`}</title>
|
<title>{`Document Search - ${CONFIG.appName}`}</title>
|
||||||
|
|
||||||
<DocSearchView posts={_posts} />
|
<DocSearchView docs={docs} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,202 +10,187 @@ import Avatar from '@mui/material/Avatar';
|
|||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
|
|
||||||
import { fDate } from 'src/utils/format-time';
|
import { fDate } from 'src/utils/format-time';
|
||||||
import { fShortenNumber } from 'src/utils/format-number';
|
|
||||||
|
import { Doc } from 'src/api/document-service';
|
||||||
|
|
||||||
import { Iconify } from 'src/components/iconify';
|
import { Iconify } from 'src/components/iconify';
|
||||||
import { SvgColor } from 'src/components/svg-color';
|
import { SvgColor } from 'src/components/svg-color';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export type IDocItem = {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
coverUrl: string;
|
|
||||||
totalViews: number;
|
|
||||||
description: string;
|
|
||||||
totalShares: number;
|
|
||||||
totalComments: number;
|
|
||||||
totalFavorites: number;
|
|
||||||
postedAt: string | number | null;
|
|
||||||
author: {
|
|
||||||
name: string;
|
|
||||||
avatarUrl: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function DocItem({
|
export function DocItem({
|
||||||
sx,
|
sx,
|
||||||
doc,
|
doc,
|
||||||
long,
|
long,
|
||||||
large,
|
large,
|
||||||
...other
|
...other
|
||||||
}: CardProps & {
|
}: CardProps & {
|
||||||
doc: IDocItem;
|
doc: Doc;
|
||||||
long: boolean;
|
long: boolean;
|
||||||
large: boolean;
|
large: boolean;
|
||||||
}) {
|
}) {
|
||||||
const renderAvatar = (
|
const renderAvatar = (
|
||||||
<Avatar
|
<Avatar
|
||||||
alt={doc.author.name}
|
alt={doc.addedWho}
|
||||||
src={doc.author.avatarUrl}
|
src={doc.addedWho}
|
||||||
sx={{
|
sx={{
|
||||||
left: 24,
|
left: 24,
|
||||||
zIndex: 9,
|
zIndex: 9,
|
||||||
bottom: -24,
|
bottom: -24,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
...((large || long) && {
|
...((large || long) && {
|
||||||
top: 24,
|
top: 24,
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderTitle = (
|
const renderTitle = (
|
||||||
<Link
|
<Link
|
||||||
color="inherit"
|
color="inherit"
|
||||||
variant="subtitle2"
|
variant="subtitle2"
|
||||||
underline="hover"
|
underline="hover"
|
||||||
sx={{
|
sx={{
|
||||||
height: 44,
|
height: 44,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
WebkitLineClamp: 2,
|
WebkitLineClamp: 2,
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
WebkitBoxOrient: 'vertical',
|
WebkitBoxOrient: 'vertical',
|
||||||
...(large && { typography: 'h5', height: 60 }),
|
...(large && { typography: 'h5', height: 60 }),
|
||||||
...((large || long) && {
|
...((large || long) && {
|
||||||
color: 'common.white',
|
color: 'common.white',
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
>
|
|
||||||
{doc.title}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderInfo = (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
mt: 3,
|
|
||||||
gap: 1.5,
|
|
||||||
display: 'flex',
|
|
||||||
flexWrap: 'wrap',
|
|
||||||
color: 'text.disabled',
|
|
||||||
justifyContent: 'flex-end',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{[
|
|
||||||
{ number: doc.totalComments, icon: 'solar:chat-round-dots-bold' },
|
|
||||||
{ number: doc.totalViews, icon: 'solar:eye-bold' },
|
|
||||||
{ number: doc.totalShares, icon: 'solar:share-bold' },
|
|
||||||
].map((info, _index) => (
|
|
||||||
<Box
|
|
||||||
key={_index}
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
...((large || long) && {
|
|
||||||
opacity: 0.64,
|
|
||||||
color: 'common.white',
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Iconify width={16} icon={info.icon as IconifyName} sx={{ mr: 0.5 }} />
|
{doc.name}
|
||||||
<Typography variant="caption">{fShortenNumber(info.number)}</Typography>
|
</Link>
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderInfo = (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
mt: 3,
|
||||||
|
gap: 1.5,
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
color: 'text.disabled',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{[
|
||||||
|
{ data: doc.addedWho, icon: 'solar:chat-round-dots-bold' },
|
||||||
|
{ data: doc.changedWho, icon: 'solar:eye-bold' },
|
||||||
|
{ data: doc.changedWhen, icon: 'solar:share-bold' },
|
||||||
|
].map((info, _index) => (
|
||||||
|
<Box
|
||||||
|
key={_index}
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
...((large || long) && {
|
||||||
|
opacity: 0.64,
|
||||||
|
color: 'common.white',
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Iconify width={16} icon={info.icon as IconifyName} sx={{ mr: 0.5 }} />
|
||||||
|
<Typography variant="caption">{info.data?.toString()}</Typography>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
);
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderCover = (
|
const renderCover = (
|
||||||
<Box
|
<Box
|
||||||
component="img"
|
component="img"
|
||||||
alt={doc.title}
|
alt={doc.name}
|
||||||
src={doc.coverUrl}
|
src={doc.name}
|
||||||
sx={{
|
sx={{
|
||||||
top: 0,
|
top: 0,
|
||||||
width: 1,
|
width: 1,
|
||||||
height: 1,
|
height: 1,
|
||||||
objectFit: 'cover',
|
objectFit: 'cover',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderDate = (
|
const renderDate = (
|
||||||
<Typography
|
<Typography
|
||||||
variant="caption"
|
variant="caption"
|
||||||
component="div"
|
component="div"
|
||||||
sx={{
|
sx={{
|
||||||
mb: 1,
|
mb: 1,
|
||||||
color: 'text.disabled',
|
color: 'text.disabled',
|
||||||
...((large || long) && {
|
...((large || long) && {
|
||||||
opacity: 0.48,
|
opacity: 0.48,
|
||||||
color: 'common.white',
|
color: 'common.white',
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{fDate(doc.postedAt)}
|
{fDate(doc.addedWhen)}
|
||||||
</Typography>
|
</Typography>
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderShape = (
|
const renderShape = (
|
||||||
<SvgColor
|
<SvgColor
|
||||||
src="/assets/icons/shape-avatar.svg"
|
src="/assets/icons/shape-avatar.svg"
|
||||||
sx={{
|
sx={{
|
||||||
left: 0,
|
left: 0,
|
||||||
width: 88,
|
width: 88,
|
||||||
zIndex: 9,
|
zIndex: 9,
|
||||||
height: 36,
|
height: 36,
|
||||||
bottom: -16,
|
bottom: -16,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
color: 'background.paper',
|
color: 'background.paper',
|
||||||
...((large || long) && { display: 'none' }),
|
...((large || long) && { display: 'none' }),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card sx={sx} {...other}>
|
<Card sx={sx} {...other}>
|
||||||
<Box
|
<Box
|
||||||
sx={(theme) => ({
|
sx={(theme) => ({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
pt: 'calc(100% * 3 / 4)',
|
pt: 'calc(100% * 3 / 4)',
|
||||||
...((large || long) && {
|
...((large || long) && {
|
||||||
pt: 'calc(100% * 4 / 3)',
|
pt: 'calc(100% * 4 / 3)',
|
||||||
'&:after': {
|
'&:after': {
|
||||||
top: 0,
|
top: 0,
|
||||||
content: "''",
|
content: "''",
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bgcolor: varAlpha(theme.palette.grey['900Channel'], 0.72),
|
bgcolor: varAlpha(theme.palette.grey['900Channel'], 0.72),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
...(large && {
|
...(large && {
|
||||||
pt: {
|
pt: {
|
||||||
xs: 'calc(100% * 4 / 3)',
|
xs: 'calc(100% * 4 / 3)',
|
||||||
sm: 'calc(100% * 3 / 4.66)',
|
sm: 'calc(100% * 3 / 4.66)',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{renderShape}
|
{renderShape}
|
||||||
{renderAvatar}
|
{renderAvatar}
|
||||||
{renderCover}
|
{renderCover}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={(theme) => ({
|
sx={(theme) => ({
|
||||||
p: theme.spacing(6, 3, 3, 3),
|
p: theme.spacing(6, 3, 3, 3),
|
||||||
...((large || long) && {
|
...((large || long) && {
|
||||||
width: 1,
|
width: 1,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
}),
|
}),
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{renderDate}
|
{renderDate}
|
||||||
{renderTitle}
|
{renderTitle}
|
||||||
{renderInfo}
|
{renderInfo}
|
||||||
</Box>
|
</Box>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,14 +4,14 @@ import TextField from '@mui/material/TextField';
|
|||||||
import InputAdornment from '@mui/material/InputAdornment';
|
import InputAdornment from '@mui/material/InputAdornment';
|
||||||
import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete';
|
import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete';
|
||||||
|
|
||||||
import { Iconify } from 'src/components/iconify';
|
import { Doc } from 'src/api/document-service';
|
||||||
|
|
||||||
import type { IDocItem } from './doc-item';
|
import { Iconify } from 'src/components/iconify';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
type DocSearchProps = {
|
type DocSearchProps = {
|
||||||
posts: IDocItem[];
|
posts: Doc[];
|
||||||
sx?: SxProps<Theme>;
|
sx?: SxProps<Theme>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ export function DocSearch({ posts, sx }: DocSearchProps) {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
options={posts}
|
options={posts}
|
||||||
getOptionLabel={(post) => post.title}
|
getOptionLabel={(post) => post.name}
|
||||||
isOptionEqualToValue={(option, value) => option.id === value.id}
|
isOptionEqualToValue={(option, value) => option.id === value.id}
|
||||||
renderInput={(params) => (
|
renderInput={(params) => (
|
||||||
<TextField
|
<TextField
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import Button from '@mui/material/Button';
|
|||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import Pagination from '@mui/material/Pagination';
|
import Pagination from '@mui/material/Pagination';
|
||||||
|
|
||||||
|
import { Doc } from 'src/api/document-service';
|
||||||
import { DashboardContent } from 'src/layouts/dashboard';
|
import { DashboardContent } from 'src/layouts/dashboard';
|
||||||
import { Filter, getAttributesAsync } from 'src/api/attribute-service';
|
import { Filter, getAttributesAsync } from 'src/api/attribute-service';
|
||||||
|
|
||||||
@ -17,15 +18,13 @@ import { TextFilter } from '../text-filter';
|
|||||||
import CreateFilterModal from './create-filter-modal';
|
import CreateFilterModal from './create-filter-modal';
|
||||||
import { DecimalFilter, IntFilter } from '../num-filter';
|
import { DecimalFilter, IntFilter } from '../num-filter';
|
||||||
import { DateFilter, DateTimeFilter, TimeFilter } from '../date-filter';
|
import { DateFilter, DateTimeFilter, TimeFilter } from '../date-filter';
|
||||||
|
|
||||||
import type { IDocItem } from '../doc-item';
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
posts: IDocItem[];
|
docs: Doc[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DocSearchView({ posts }: Props) {
|
export function DocSearchView({ docs }: Props) {
|
||||||
const [sortBy, setSortBy] = useState('latest');
|
const [sortBy, setSortBy] = useState('latest');
|
||||||
|
|
||||||
const [filters, setFilters] = useState<Filter[]>([])
|
const [filters, setFilters] = useState<Filter[]>([])
|
||||||
@ -51,7 +50,7 @@ export function DocSearchView({ posts }: Props) {
|
|||||||
// justifyContent: 'space-between',
|
// justifyContent: 'space-between',
|
||||||
// }}
|
// }}
|
||||||
// >
|
// >
|
||||||
// <DocSearch posts={posts} />
|
// <DocSearch docs={docs} />
|
||||||
// <DocSort
|
// <DocSort
|
||||||
// sortBy={sortBy}
|
// sortBy={sortBy}
|
||||||
// onSort={handleSort}
|
// onSort={handleSort}
|
||||||
@ -145,20 +144,20 @@ export function DocSearchView({ posts }: Props) {
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
{posts.map((post, index) => {
|
{docs.map((doc, index) => {
|
||||||
const large = false;
|
const large = false;
|
||||||
const long = false;
|
const long = false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid
|
<Grid
|
||||||
key={post.id}
|
key={doc.id}
|
||||||
size={{
|
size={{
|
||||||
xs: 12,
|
xs: 12,
|
||||||
sm: large ? 12 : 6,
|
sm: large ? 12 : 6,
|
||||||
md: large ? 6 : 3,
|
md: large ? 6 : 3,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DocItem doc={post} long={long} large={large} />
|
<DocItem doc={doc} long={long} large={large} />
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user