✨(frontend) enhance document grid
- Updated the layout and styling of the DocsGrid and DocsGridItem components for improved responsiveness and visual consistency. - Added a new background prop to the UserAvatar component for customizable user avatars. - Enhanced the DocsGridActions component to include a share option, allowing users to share documents easily. - Refactored SVG assets for pinned and simple documents to improve their dimensions and visual representation. - Improved the SimpleDocItem component to display document update times and access indicators more effectively. - Adjusted padding and spacing across various components to enhance overall user experience.
This commit is contained in:
committed by
Anthony LC
parent
72f234027c
commit
78b5e2c1cc
@@ -19,7 +19,8 @@ export const SeparatedSection = ({
|
|||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
$css={css`
|
$css={css`
|
||||||
padding: ${spacings['base']} 0;
|
width: 100%;
|
||||||
|
padding: ${spacings['sm']} 0;
|
||||||
${showSeparator &&
|
${showSeparator &&
|
||||||
css`
|
css`
|
||||||
border-bottom: 1px solid ${colors?.['greyscale-200']};
|
border-bottom: 1px solid ${colors?.['greyscale-200']};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<svg width="28" height="34" viewBox="0 0 28 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="32" height="36" viewBox="0 0 32 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect x="2.01394" y="1.23611" width="25.9722" height="33.5278" rx="3.54167" fill="white"/>
|
<rect x="2.01394" y="1.23611" width="25.9722" height="33.5278" rx="3.54167" fill="white"/>
|
||||||
<rect x="2.01394" y="1.23611" width="25.9722" height="33.5278" rx="3.54167" stroke="#DCDCFC" stroke-width="0.472222"/>
|
<rect x="2.01394" y="1.23611" width="25.9722" height="33.5278" rx="3.54167" stroke="#E3E3FD" stroke-width="0.472222"/>
|
||||||
<path d="M6.5 8.55556H15" stroke="#6A6AF4" stroke-width="1.88889" stroke-linecap="round"/>
|
<path d="M6.5 8.55554H15" stroke="#6A6AF4" stroke-width="1.88889" stroke-linecap="round"/>
|
||||||
<path d="M6.5 11.3889H23.5M6.5 14.2222H23.5M6.5 17.0556H23.5M6.5 19.8889H23.5M6.5 22.7222H20.6667" stroke="#CACAFB" stroke-width="1.88889" stroke-linecap="round"/>
|
<path d="M6.5 11.3889H23.5M6.5 14.2222H23.5M6.5 17.0556H23.5M6.5 19.8889H23.5M6.5 22.7222H20.6667" stroke="#CACAFB" stroke-width="1.88889" stroke-linecap="round"/>
|
||||||
<rect x="7" y="10" width="16" height="16" rx="8" fill="#6A6AF4"/>
|
<rect x="7" y="10" width="16" height="16" rx="8" fill="#6A6AF4"/>
|
||||||
<rect x="7" y="10" width="16" height="16" rx="8" stroke="white" stroke-width="1.5"/>
|
<rect x="7" y="10" width="16" height="16" rx="8" stroke="white" stroke-width="1.5"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 853 B After Width: | Height: | Size: 853 B |
@@ -1,6 +1,6 @@
|
|||||||
<svg width="28" height="34" viewBox="0 0 28 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="32" height="36" viewBox="0 0 32 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect x="1.01394" y="0.236111" width="25.9722" height="33.5278" rx="3.54167" fill="white"/>
|
<rect x="2.01394" y="1.23611" width="25.9722" height="33.5278" rx="3.54167" fill="white"/>
|
||||||
<rect x="1.01394" y="0.236111" width="25.9722" height="33.5278" rx="3.54167" stroke="#DCDCFC" stroke-width="0.472222"/>
|
<rect x="2.01394" y="1.23611" width="25.9722" height="33.5278" rx="3.54167" stroke="#E3E3FD" stroke-width="0.472222"/>
|
||||||
<path d="M5.5 7.55554H14" stroke="#6A6AF4" stroke-width="1.88889" stroke-linecap="round"/>
|
<path d="M6.5 8.55554H15" stroke="#6A6AF4" stroke-width="1.88889" stroke-linecap="round"/>
|
||||||
<path d="M5.5 10.3889H22.5M5.5 13.2222H22.5M5.5 16.0556H22.5M5.5 18.8889H22.5M5.5 21.7222H22.5M5.5 24.5556H22.5M5.5 27.3889H22.5M5.5 30.2222H22.5M5.5 33.0556H22.5" stroke="#CACAFB" stroke-width="1.88889" stroke-linecap="round"/>
|
<path d="M6.5 11.3889H23.5M6.5 14.2222H23.5M6.5 17.0556H23.5M6.5 19.8889H23.5M6.5 22.7222H20.6667" stroke="#CACAFB" stroke-width="1.88889" stroke-linecap="round"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 635 B After Width: | Height: | Size: 568 B |
@@ -29,15 +29,16 @@ const getColorFromName = (name: string) => {
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
user: User;
|
user: User;
|
||||||
|
background?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UserAvatar = ({ user }: Props) => {
|
export const UserAvatar = ({ user, background }: Props) => {
|
||||||
const name = user.full_name || user.email || '?';
|
const name = user.full_name || user.email || '?';
|
||||||
const splitName = name?.split(' ');
|
const splitName = name?.split(' ');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
$background={getColorFromName(name)}
|
$background={background || getColorFromName(name)}
|
||||||
$width="24px"
|
$width="24px"
|
||||||
$height="24px"
|
$height="24px"
|
||||||
$direction="row"
|
$direction="row"
|
||||||
|
|||||||
@@ -53,37 +53,44 @@ export const DocsGrid = ({
|
|||||||
return (
|
return (
|
||||||
<Box $position="relative" $width="100%" $maxWidth="960px">
|
<Box $position="relative" $width="100%" $maxWidth="960px">
|
||||||
<DocsGridLoader isLoading={isRefetching} />
|
<DocsGridLoader isLoading={isRefetching} />
|
||||||
<Card data-testid="docs-grid" $padding="md">
|
<Card
|
||||||
|
data-testid="docs-grid"
|
||||||
|
$padding={{
|
||||||
|
top: 'base',
|
||||||
|
horizontal: isDesktop ? 'md' : 'xs',
|
||||||
|
bottom: 'md',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Text
|
<Text
|
||||||
as="h4"
|
as="h4"
|
||||||
$size="h4"
|
$size="h4"
|
||||||
$weight="700"
|
$variation="1000"
|
||||||
$margin={{ top: '0px', bottom: 'xs' }}
|
$margin={{ top: '0px', bottom: '10px' }}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Box>
|
<Box $gap="6px">
|
||||||
<Box
|
<Box
|
||||||
$direction="row"
|
$direction="row"
|
||||||
$padding="xs"
|
$padding={{ horizontal: 'xs' }}
|
||||||
$gap="20px"
|
$gap="20px"
|
||||||
data-testid="docs-grid-header"
|
data-testid="docs-grid-header"
|
||||||
>
|
>
|
||||||
<Box $flex={6} $padding="3xs">
|
<Box $flex={6} $padding="3xs">
|
||||||
<Text $size="xs" $variation="600">
|
<Text $size="xs" $variation="600" $weight="500">
|
||||||
{t('Name')}
|
{t('Name')}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
{isDesktop && (
|
{isDesktop && (
|
||||||
<Box $flex={1.3} $padding="3xs">
|
<Box $flex={2} $padding="3xs">
|
||||||
<Text $size="xs" $variation="600">
|
<Text $size="xs" $weight="500" $variation="600">
|
||||||
{t('Updated at')}
|
{t('Updated at')}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box $flex={1} $align="flex-end" $padding="3xs" />
|
<Box $flex={1.15} $align="flex-end" $padding="3xs" />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Body */}
|
{/* Body */}
|
||||||
|
|||||||
@@ -13,11 +13,16 @@ import { useDeleteFavoriteDoc } from '../../doc-management/api/useDeleteFavorite
|
|||||||
|
|
||||||
interface DocsGridActionsProps {
|
interface DocsGridActionsProps {
|
||||||
doc: Doc;
|
doc: Doc;
|
||||||
|
openShareModal?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DocsGridActions = ({ doc }: DocsGridActionsProps) => {
|
export const DocsGridActions = ({
|
||||||
|
doc,
|
||||||
|
openShareModal,
|
||||||
|
}: DocsGridActionsProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const deleteModal = useModal();
|
const deleteModal = useModal();
|
||||||
|
|
||||||
const removeFavoriteDoc = useDeleteFavoriteDoc({
|
const removeFavoriteDoc = useDeleteFavoriteDoc({
|
||||||
listInvalideQueries: [KEY_LIST_DOC],
|
listInvalideQueries: [KEY_LIST_DOC],
|
||||||
});
|
});
|
||||||
@@ -38,6 +43,13 @@ export const DocsGridActions = ({ doc }: DocsGridActionsProps) => {
|
|||||||
},
|
},
|
||||||
testId: `docs-grid-actions-${doc.is_favorite ? 'unpin' : 'pin'}-${doc.id}`,
|
testId: `docs-grid-actions-${doc.is_favorite ? 'unpin' : 'pin'}-${doc.id}`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: t('Share'),
|
||||||
|
icon: 'group',
|
||||||
|
callback: () => openShareModal?.(),
|
||||||
|
testId: `docs-grid-actions-share-${doc.id}`,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: t('Remove'),
|
label: t('Remove'),
|
||||||
icon: 'delete',
|
icon: 'delete',
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const DocsGridItem = ({ doc }: DocsGridItemProps) => {
|
|||||||
$align="center"
|
$align="center"
|
||||||
$gap="20px"
|
$gap="20px"
|
||||||
role="row"
|
role="row"
|
||||||
$padding={{ vertical: 'xs', horizontal: 'sm' }}
|
$padding={{ vertical: '2xs', horizontal: isDesktop ? 'base' : 'xs' }}
|
||||||
$css={css`
|
$css={css`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -46,7 +46,7 @@ export const DocsGridItem = ({ doc }: DocsGridItemProps) => {
|
|||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<StyledLink
|
<StyledLink
|
||||||
$css="flex: 7; align-items: center;"
|
$css="flex: 8; align-items: center;"
|
||||||
href={`/docs/${doc.id}`}
|
href={`/docs/${doc.id}`}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
@@ -57,19 +57,19 @@ export const DocsGridItem = ({ doc }: DocsGridItemProps) => {
|
|||||||
<SimpleDocItem isPinned={doc.is_favorite} doc={doc} />
|
<SimpleDocItem isPinned={doc.is_favorite} doc={doc} />
|
||||||
</Box>
|
</Box>
|
||||||
{isDesktop && (
|
{isDesktop && (
|
||||||
<Box $flex={1.3}>
|
<Box $flex={2}>
|
||||||
<Text $variation="500" $size="xs">
|
<Text $variation="600" $size="xs">
|
||||||
{DateTime.fromISO(doc.updated_at).toRelative()}
|
{DateTime.fromISO(doc.updated_at).toRelative()}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
<Box
|
<Box
|
||||||
$flex={1}
|
$flex={1.15}
|
||||||
$direction="row"
|
$direction="row"
|
||||||
$align="center"
|
$align="center"
|
||||||
$justify="flex-end"
|
$justify="flex-end"
|
||||||
$gap="10px"
|
$gap="32px"
|
||||||
>
|
>
|
||||||
{isDesktop && isPublic && (
|
{isDesktop && isPublic && (
|
||||||
<Button
|
<Button
|
||||||
@@ -79,6 +79,7 @@ export const DocsGridItem = ({ doc }: DocsGridItemProps) => {
|
|||||||
handleShareClick();
|
handleShareClick();
|
||||||
}}
|
}}
|
||||||
size="nano"
|
size="nano"
|
||||||
|
fullWidth
|
||||||
icon={<Icon $variation="000" iconName="public" />}
|
icon={<Icon $variation="000" iconName="public" />}
|
||||||
>
|
>
|
||||||
{isShared ? sharedCount : undefined}
|
{isShared ? sharedCount : undefined}
|
||||||
@@ -91,6 +92,7 @@ export const DocsGridItem = ({ doc }: DocsGridItemProps) => {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
handleShareClick();
|
handleShareClick();
|
||||||
}}
|
}}
|
||||||
|
fullWidth
|
||||||
color="tertiary"
|
color="tertiary"
|
||||||
size="nano"
|
size="nano"
|
||||||
icon={<Icon $variation="800" $theme="primary" iconName="group" />}
|
icon={<Icon $variation="800" $theme="primary" iconName="group" />}
|
||||||
@@ -105,13 +107,14 @@ export const DocsGridItem = ({ doc }: DocsGridItemProps) => {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
handleShareClick();
|
handleShareClick();
|
||||||
}}
|
}}
|
||||||
|
fullWidth
|
||||||
size="nano"
|
size="nano"
|
||||||
icon={<Icon $variation="000" iconName="corporate_fare" />}
|
icon={<Icon $variation="000" iconName="corporate_fare" />}
|
||||||
>
|
>
|
||||||
{sharedCount}
|
{sharedCount}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<DocsGridActions doc={doc} />
|
<DocsGridActions doc={doc} openShareModal={handleShareClick} />
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{shareModal.isOpen && (
|
{shareModal.isOpen && (
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { DateTime } from 'luxon';
|
||||||
import { css } from 'styled-components';
|
import { css } from 'styled-components';
|
||||||
|
|
||||||
import { Box, Icon, Text } from '@/components';
|
import { Box, Icon, Text } from '@/components';
|
||||||
@@ -20,14 +21,12 @@ const ItemTextCss = css`
|
|||||||
type SimpleDocItemProps = {
|
type SimpleDocItemProps = {
|
||||||
doc: Doc;
|
doc: Doc;
|
||||||
isPinned?: boolean;
|
isPinned?: boolean;
|
||||||
subText?: string;
|
|
||||||
showAccesses?: boolean;
|
showAccesses?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SimpleDocItem = ({
|
export const SimpleDocItem = ({
|
||||||
doc,
|
doc,
|
||||||
isPinned = false,
|
isPinned = false,
|
||||||
subText,
|
|
||||||
showAccesses = false,
|
showAccesses = false,
|
||||||
}: SimpleDocItemProps) => {
|
}: SimpleDocItemProps) => {
|
||||||
const { spacingsTokens } = useCunninghamTheme();
|
const { spacingsTokens } = useCunninghamTheme();
|
||||||
@@ -51,7 +50,7 @@ export const SimpleDocItem = ({
|
|||||||
>
|
>
|
||||||
{isPinned ? <PinnedDocumentIcon /> : <SimpleFileIcon />}
|
{isPinned ? <PinnedDocumentIcon /> : <SimpleFileIcon />}
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box $justify="center">
|
||||||
<Text
|
<Text
|
||||||
aria-describedby="doc-title"
|
aria-describedby="doc-title"
|
||||||
aria-label={doc.title}
|
aria-label={doc.title}
|
||||||
@@ -62,23 +61,34 @@ export const SimpleDocItem = ({
|
|||||||
>
|
>
|
||||||
{doc.title}
|
{doc.title}
|
||||||
</Text>
|
</Text>
|
||||||
<Box $direction="row" $align="center" $gap={spacings['3xs']}>
|
{(!isDesktop || showAccesses) && (
|
||||||
{(!isDesktop || showAccesses) && (
|
<Box
|
||||||
<>
|
$direction="row"
|
||||||
{isPublic && <Icon iconName="public" $size="16px" />}
|
$align="center"
|
||||||
{isShared && <Icon iconName="group" $size="16px" />}
|
$gap={spacings['3xs']}
|
||||||
{isSharedOrPublic && accessCount > 0 && (
|
$margin={{ top: '-2px' }}
|
||||||
<Text $size="12px">{accessCount}</Text>
|
>
|
||||||
)}
|
{isPublic && (
|
||||||
{isSharedOrPublic && <Text $size="12px">·</Text>}
|
<Icon iconName="public" $size="16px" $variation="600" />
|
||||||
</>
|
)}
|
||||||
)}
|
{isShared && (
|
||||||
|
<Icon iconName="group" $size="16px" $variation="600" />
|
||||||
<Text $size="xs" $variation="500" $weight="500" $css={ItemTextCss}>
|
)}
|
||||||
{subText ??
|
{isSharedOrPublic && accessCount > 0 && (
|
||||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vel ante libero. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed imperdiet neque quam, sed euismod metus mollis ut. '}
|
<Text $size="12px" $weight="bold" $variation="600">
|
||||||
</Text>
|
{accessCount}
|
||||||
</Box>
|
</Text>
|
||||||
|
)}
|
||||||
|
{isSharedOrPublic && (
|
||||||
|
<Text $size="12px" $variation="600">
|
||||||
|
·
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
<Text $variation="600" $size="xs">
|
||||||
|
{DateTime.fromISO(doc.updated_at).toRelative()}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user