From c7c70b17670d479f978e44947fc0c2d2fc7e9b5a Mon Sep 17 00:00:00 2001 From: Sonny Date: Sun, 3 Nov 2024 18:38:11 +0100 Subject: [PATCH] feat: recreate collection list/item --- .../components/dashboard/link/link_item.tsx | 4 +- .../item/collection_item.module.css | 44 +++++++++++++++ .../collection/item/collection_item.tsx | 47 ++++++++++++++++ .../list/collection_list.module.css | 24 ++++++++ .../collection/list/collection_list.tsx | 56 +++++++++++++++++++ .../components/dashboard/dashboard_aside.tsx | 19 +++++++ 6 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 inertia/mantine/components/dashboard/collection/item/collection_item.module.css create mode 100644 inertia/mantine/components/dashboard/collection/item/collection_item.tsx create mode 100644 inertia/mantine/components/dashboard/collection/list/collection_list.module.css create mode 100644 inertia/mantine/components/dashboard/collection/list/collection_list.tsx create mode 100644 inertia/mantine/components/dashboard/dashboard_aside.tsx diff --git a/inertia/components/dashboard/link/link_item.tsx b/inertia/components/dashboard/link/link_item.tsx index 4cca453..d37e82d 100644 --- a/inertia/components/dashboard/link/link_item.tsx +++ b/inertia/components/dashboard/link/link_item.tsx @@ -54,7 +54,7 @@ function LinkItemURL({ url }: { url: Link['url'] }) { } return ( - + {origin} {text} @@ -62,7 +62,7 @@ function LinkItemURL({ url }: { url: Link['url'] }) { } catch (error) { console.error('error', error); return ( - + {url} ); diff --git a/inertia/mantine/components/dashboard/collection/item/collection_item.module.css b/inertia/mantine/components/dashboard/collection/item/collection_item.module.css new file mode 100644 index 0000000..9c16cf0 --- /dev/null +++ b/inertia/mantine/components/dashboard/collection/item/collection_item.module.css @@ -0,0 +1,44 @@ +.link { + width: 100%; + max-width: 100%; + display: flex; + align-items: center; + text-decoration: none; + font-size: var(--mantine-font-size-sm); + color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1)); + padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm); + border-radius: var(--mantine-radius-sm); + font-weight: 500; + + @mixin hover { + background-color: light-dark( + var(--mantine-color-gray-0), + var(--mantine-color-dark-6) + ); + color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); + + .linkIcon { + color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); + } + } + + &[data-active] { + &, + &:hover { + background-color: var(--mantine-color-blue-light); + color: var(--mantine-color-blue-light-color); + + .linkIcon { + color: var(--mantine-color-blue-light-color); + } + } + } +} + +.linkIcon { + color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2)); + margin-right: var(--mantine-spacing-sm); + width: rem(25px); + height: rem(25px); + min-width: rem(25px); +} diff --git a/inertia/mantine/components/dashboard/collection/item/collection_item.tsx b/inertia/mantine/components/dashboard/collection/item/collection_item.tsx new file mode 100644 index 0000000..acac98c --- /dev/null +++ b/inertia/mantine/components/dashboard/collection/item/collection_item.tsx @@ -0,0 +1,47 @@ +import { Link } from '@inertiajs/react'; +import { route } from '@izzyjs/route/client'; +import { Text } from '@mantine/core'; +import { useEffect, useRef } from 'react'; +import { AiFillFolderOpen, AiOutlineFolder } from 'react-icons/ai'; +import useActiveCollection from '~/hooks/use_active_collection'; +import { appendCollectionId } from '~/lib/navigation'; +import { CollectionWithLinks } from '~/types/app'; +import classes from './collection_item.module.css'; + +export default function CollectionItem({ + collection, +}: { + collection: CollectionWithLinks; +}) { + const itemRef = useRef(null); + const { activeCollection } = useActiveCollection(); + const isActiveCollection = collection.id === activeCollection?.id; + const FolderIcon = isActiveCollection ? AiFillFolderOpen : AiOutlineFolder; + + useEffect(() => { + if (collection.id === activeCollection?.id) { + itemRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + } + }, [collection.id, activeCollection?.id]); + + const linksCount = activeCollection?.links.length ?? 0; + return ( + + + + {collection.name} + + {linksCount > 0 && ( + + — {linksCount} + + )} + + ); +} diff --git a/inertia/mantine/components/dashboard/collection/list/collection_list.module.css b/inertia/mantine/components/dashboard/collection/list/collection_list.module.css new file mode 100644 index 0000000..fb28f67 --- /dev/null +++ b/inertia/mantine/components/dashboard/collection/list/collection_list.module.css @@ -0,0 +1,24 @@ +.sideMenu { + height: 100%; + width: 100%; + display: flex; + gap: 0.35em; + flex-direction: column; +} + +.listContainer { + height: 100%; + min-height: 0; + display: flex; + flex-direction: column; +} + +.collectionList { + padding: 1px; + padding-right: 5px; + display: flex; + flex: 1; + gap: 0.35em; + flex-direction: column; + overflow: auto; +} diff --git a/inertia/mantine/components/dashboard/collection/list/collection_list.tsx b/inertia/mantine/components/dashboard/collection/list/collection_list.tsx new file mode 100644 index 0000000..4dd8bf3 --- /dev/null +++ b/inertia/mantine/components/dashboard/collection/list/collection_list.tsx @@ -0,0 +1,56 @@ +import { Box, ScrollArea, Text } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import useActiveCollection from '~/hooks/use_active_collection'; +import useCollections from '~/hooks/use_collections'; +import useShortcut from '~/hooks/use_shortcut'; +import CollectionItem from '~/mantine/components/dashboard/collection/item/collection_item'; +import styles from './collection_list.module.css'; + +export default function CollectionList() { + const { t } = useTranslation('common'); + const { collections } = useCollections(); + const { activeCollection, setActiveCollection } = useActiveCollection(); + + const goToPreviousCollection = () => { + const currentCategoryIndex = collections.findIndex( + ({ id }) => id === activeCollection?.id + ); + if (currentCategoryIndex === -1 || currentCategoryIndex === 0) return; + + setActiveCollection(collections[currentCategoryIndex - 1]); + }; + + const goToNextCollection = () => { + const currentCategoryIndex = collections.findIndex( + ({ id }) => id === activeCollection?.id + ); + if ( + currentCategoryIndex === -1 || + currentCategoryIndex === collections.length - 1 + ) + return; + + setActiveCollection(collections[currentCategoryIndex + 1]); + }; + + useShortcut('ARROW_UP', goToPreviousCollection); + useShortcut('ARROW_DOWN', goToNextCollection); + + return ( + + +
+ + {t('collection.collections', { count: collections.length })} •{' '} + {collections.length} + + + {collections.map((collection) => ( + + ))} + +
+
+
+ ); +} diff --git a/inertia/mantine/components/dashboard/dashboard_aside.tsx b/inertia/mantine/components/dashboard/dashboard_aside.tsx new file mode 100644 index 0000000..c5d37ca --- /dev/null +++ b/inertia/mantine/components/dashboard/dashboard_aside.tsx @@ -0,0 +1,19 @@ +import { AppShell, Burger, Group, ScrollArea, Text } from '@mantine/core'; +import CollectionList from '~/mantine/components/dashboard/collection/list/collection_list'; + +interface DashboardAsideProps { + isOpen: boolean; + toggle: () => void; +} + +export const DashboardAside = ({ isOpen, toggle }: DashboardAsideProps) => ( + + + Collections + + + + + + +);