diff --git a/packages/web/components/elements/images/LibraryGridLayoutIcon.tsx b/packages/web/components/elements/images/LibraryGridLayoutIcon.tsx new file mode 100644 index 000000000..afa40677a --- /dev/null +++ b/packages/web/components/elements/images/LibraryGridLayoutIcon.tsx @@ -0,0 +1,21 @@ +type LibraryGridLayoutIconProps = { + color: string +} + +export function LibraryGridLayoutIcon(props: LibraryGridLayoutIconProps): JSX.Element { + return ( + + + + + + + + + + + + + + ) +} \ No newline at end of file diff --git a/packages/web/components/elements/images/LibraryListLayoutIcon.tsx b/packages/web/components/elements/images/LibraryListLayoutIcon.tsx new file mode 100644 index 000000000..01e413815 --- /dev/null +++ b/packages/web/components/elements/images/LibraryListLayoutIcon.tsx @@ -0,0 +1,13 @@ +type LibraryListLayoutIconProps = { + color: string +} + +export function LibraryListLayoutIcon(props: LibraryListLayoutIconProps): JSX.Element { + return ( + + + + + + ) +} \ No newline at end of file diff --git a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx new file mode 100644 index 000000000..01b13b9f8 --- /dev/null +++ b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx @@ -0,0 +1,178 @@ +import { Box, VStack, HStack, SpanBox } from '../../elements/LayoutPrimitives' +import { CoverImage } from '../../elements/CoverImage' +import { StyledText } from '../../elements/StyledText' +import { authoredByText } from '../ArticleSubtitle' +import { MoreOptionsIcon } from '../../elements/images/MoreOptionsIcon' +import { theme } from '../../tokens/stitches.config' +import { CardMenu } from '../CardMenu' +import { LabelChip } from '../../elements/LabelChip' +import { ProgressBar } from '../../elements/ProgressBar' +import type { LinkedItemCardProps } from './CardTypes' + +export function LibraryGridCard(props: LinkedItemCardProps): JSX.Element { + return ( + { + props.handleAction('showDetail') + }} + > + {props.item.image && ( + { + ;(e.target as HTMLElement).style.display = 'none' + }} + /> + )} + + + + {/* { + // This is here to prevent menu click events from bubbling + // up and causing us to "click" on the link item. + e.stopPropagation() + }} + > + + } + actionHandler={props.handleAction} + /> + */} + + {/* + + {props.item.author && ( + + {authoredByText(props.item.author)} + + )} + + {props.originText} + + + */} + + + + {props.item.description} + + + + + {props.item.labels?.map(({ name, color }, index) => ( + + ))} + + + + ) +} + +type CardTitleProps = { + title: string +} + +function CardTitle(props: CardTitleProps): JSX.Element { + return ( + + {props.title} + + ) +} diff --git a/packages/web/components/templates/library/LibraryAvatar.tsx b/packages/web/components/templates/library/LibraryAvatar.tsx new file mode 100644 index 000000000..e653036f3 --- /dev/null +++ b/packages/web/components/templates/library/LibraryAvatar.tsx @@ -0,0 +1,62 @@ +import { SpanBox, VStack } from '../../elements/LayoutPrimitives' +import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery' + +import { styled } from '../../tokens/stitches.config' +import { Root, Image, Fallback } from '@radix-ui/react-avatar' + +type AvatarProps = { + viewer?: UserBasicData +} + +export function LibraryAvatar(props: AvatarProps): JSX.Element { + return ( + + + + {props.viewer?.profile.pictureUrl + ? + : {props.viewer?.name.charAt(0) ?? ''} + } + + + {/* This spacer is to help align with items in the search box */} + + + ) +} + +const StyledAvatar = styled(Root, { + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + verticalAlign: 'middle', + overflow: 'hidden', + userSelect: 'none', +}) + +const StyledImage = styled(Image, { + width: '100%', + height: '100%', + objectFit: 'cover', + + '&:hover': { + opacity: '48%', + }, +}) + +const StyledFallback = styled(Fallback, { + width: '100%', + height: '100%', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + fontSize: '20px', + backgroundColor: '$omnivoreCtaYellow', + color: '#595959', +}) diff --git a/packages/web/components/templates/library/LibraryContainer.tsx b/packages/web/components/templates/library/LibraryContainer.tsx new file mode 100644 index 000000000..47d0d883b --- /dev/null +++ b/packages/web/components/templates/library/LibraryContainer.tsx @@ -0,0 +1,35 @@ +import { Box, HStack, SpanBox, VStack } from './../../elements/LayoutPrimitives' +import { useGetViewerQuery } from '../../../lib/networking/queries/useGetViewerQuery' +import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences' +import { LibraryMenu } from './LibraryMenu' +import { LibraryAvatar } from './LibraryAvatar' +import { LibrarySearchBar } from './LibrarySearchBar' +import { LibraryList } from './LibraryList' +import { LibraryHeadline } from './LibraryHeadline' + + +export function LibraryContainer(): JSX.Element { + useGetUserPreferences() + + const { viewerData } = useGetViewerQuery() + + return ( + <> + + + + + + + + + + + + + + + + + ) +} \ No newline at end of file diff --git a/packages/web/components/templates/library/LibraryHeadline.tsx b/packages/web/components/templates/library/LibraryHeadline.tsx new file mode 100644 index 000000000..28c2e22c9 --- /dev/null +++ b/packages/web/components/templates/library/LibraryHeadline.tsx @@ -0,0 +1,23 @@ +import { HStack } from '../../elements/LayoutPrimitives' +import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences' +import { StyledText } from '../../elements/StyledText' +import { theme } from '../../tokens/stitches.config' +import { LibraryListLayoutIcon } from '../../elements/images/LibraryListLayoutIcon' +import { LibraryGridLayoutIcon } from '../../elements/images/LibraryGridLayoutIcon' +import { Button } from '../../elements/Button' + + +export function LibraryHeadline(): JSX.Element { + useGetUserPreferences() + + return ( + + Home + + + + + + + ) +} \ No newline at end of file diff --git a/packages/web/components/templates/library/LibraryList.tsx b/packages/web/components/templates/library/LibraryList.tsx new file mode 100644 index 000000000..f0b55a805 --- /dev/null +++ b/packages/web/components/templates/library/LibraryList.tsx @@ -0,0 +1,114 @@ +import { Box } from '../../elements/LayoutPrimitives' +import { useGetViewerQuery } from '../../../lib/networking/queries/useGetViewerQuery' +import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences' +import { useMemo, useState } from 'react' +import { useGetLibraryItemsQuery } from '../../../lib/networking/queries/useGetLibraryItemsQuery' +import { LinkedItemCardAction } from '../../patterns/LibraryCards/CardTypes' +import { LibraryGridCard } from '../../patterns/LibraryCards/LibraryGridCard' + +export type LayoutType = 'LIST_LAYOUT' | 'GRID_LAYOUT' + + +export function LibraryList(): JSX.Element { + useGetUserPreferences() + + const [layout, setLayout] = useState('GRID_LAYOUT') + const { viewerData } = useGetViewerQuery() + + + const defaultQuery = { + limit: 50, + sortDescending: true, + searchQuery: undefined, + } + + const { itemsPages, size, setSize, isValidating, performActionOnItem } = + useGetLibraryItemsQuery(defaultQuery) + + const libraryItems = useMemo(() => { + const items = + itemsPages?.flatMap((ad) => { + return ad.search.edges + }) || [] + return items + }, [itemsPages, performActionOnItem]) + + return ( + + {/* // {!isValidating && items.length == 0 ? ( + // { + + // }} + // /> + // ) : ( */} + + {libraryItems.map((linkedItem) => ( + div': { + bg: '$libraryBackground', + }, + '&:focus': { + '> div': { + bg: '$grayBgActive', + }, + }, + '&:hover': { + '> div': { + bg: '$grayBgActive', + }, + }, + }} + > + {viewerData?.me && ( + { + + }} + /> + )} + + ))} + + {/* Extra padding at bottom to give space for scrolling */} + + + ) +} \ No newline at end of file diff --git a/packages/web/components/templates/library/LibraryMenu.tsx b/packages/web/components/templates/library/LibraryMenu.tsx new file mode 100644 index 000000000..baf771a7b --- /dev/null +++ b/packages/web/components/templates/library/LibraryMenu.tsx @@ -0,0 +1,14 @@ +import { VStack } from '../../elements/LayoutPrimitives' +import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences' +import { Menubar } from '../Menu' + + +export function LibraryMenu(): JSX.Element { + useGetUserPreferences() + + return ( + + + + ) +} \ No newline at end of file diff --git a/packages/web/components/templates/library/LibrarySearchBar.tsx b/packages/web/components/templates/library/LibrarySearchBar.tsx new file mode 100644 index 000000000..8831e7fdf --- /dev/null +++ b/packages/web/components/templates/library/LibrarySearchBar.tsx @@ -0,0 +1,97 @@ +import { Box, HStack, SpanBox, VStack } from './../../elements/LayoutPrimitives' +import { useGetViewerQuery } from '../../../lib/networking/queries/useGetViewerQuery' +import { useRouter } from 'next/router' +import { useGetUserPreferences } from '../../../lib/networking/queries/useGetUserPreferences' +import { useState } from 'react' +import { FormInput } from '../../elements/FormElements' +import { Button } from '../../elements/Button' +import { X } from 'phosphor-react' +import { theme } from '../../tokens/stitches.config' + + +export function LibrarySearchBar(): JSX.Element { + useGetUserPreferences() + + + const router = useRouter() + const [searchTerm, setSearchTerm] = useState('') + const { viewerData } = useGetViewerQuery() + + return ( + <> + + +
{ + event.preventDefault() + // props.applySearchQuery(searchTerm || '') + // inputRef.current?.blur() + }} + > + { + // event.target.select() + // setFocused(true) + // }} + // onBlur={() => { + // setFocused(false) + // }} + // onChange={(event) => { + // setSearchTerm(event.target.value) + // }} + /> + + {searchTerm && ( + + + + + + )} +
+ +
+ + ) +} \ No newline at end of file diff --git a/packages/web/pages/library.tsx b/packages/web/pages/library.tsx new file mode 100644 index 000000000..839ff3251 --- /dev/null +++ b/packages/web/pages/library.tsx @@ -0,0 +1,5 @@ +import { LibraryContainer } from '../components/templates/library/LibraryContainer' + +export default function Library(): JSX.Element { + return +}