diff --git a/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx new file mode 100644 index 000000000..015e7d96c --- /dev/null +++ b/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx @@ -0,0 +1,354 @@ +import { + Box, + VStack, + HStack, + SpanBox, + Blockquote, +} from '../../elements/LayoutPrimitives' +import { LabelChip } from '../../elements/LabelChip' +import type { LinkedItemCardProps } from './CardTypes' +import { CoverImage } from '../../elements/CoverImage' +import dayjs from 'dayjs' +import relativeTime from 'dayjs/plugin/relativeTime' +import { Fragment, useMemo, useState } from 'react' +import { + CaretCircleDown, + CaretDown, + CaretUp, + DotsThreeVertical, +} from 'phosphor-react' +import Link from 'next/link' +import { CardMenu } from '../CardMenu' +import { + AuthorInfoStyle, + DescriptionStyle, + MenuStyle, + MetaStyle, + TitleStyle, +} from './LibraryCardStyles' +import { Separator } from '../../elements/Separator' +import { styled } from '@stitches/react' +import { Dropdown, DropdownOption } from '../../elements/DropdownElements' +import { StyledText } from '../../elements/StyledText' +import { Highlight } from '../../../lib/networking/fragments/highlightFragment' +import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery' +import { + LibraryItem, + LibraryItemNode, +} from '../../../lib/networking/queries/useGetLibraryItemsQuery' +import { useRouter } from 'next/router' +import { Label } from '../../../lib/networking/fragments/labelFragment' +import { Button } from '../../elements/Button' +import { theme } from '../../tokens/stitches.config' + +dayjs.extend(relativeTime) + +const timeAgo = (date: string | undefined): string => { + if (!date) { + return '' + } + return dayjs(date).fromNow() +} + +export const GridSeparator = styled(Box, { + height: '1px', + marginTop: '15px', + backgroundColor: '$thBorderColor', +}) + +type LibraryHighlightGridCardProps = { + viewer: UserBasicData + item: LibraryItemNode +} + +// Component +export function LibraryHighlightGridCard( + props: LibraryHighlightGridCardProps +): JSX.Element { + const [isHovered, setIsHovered] = useState(false) + const [expanded, setExpanded] = useState(false) + + const higlightCount = props.item.highlights?.length ?? 0 + + return ( + { + setIsHovered(true) + }} + onMouseLeave={() => { + setIsHovered(false) + }} + > + {!expanded && ( + + + {timeAgo(props.item.savedAt)} + {` `} + {props.item.wordsCount ?? 0 > 0 + ? ` • ${Math.max( + 1, + Math.round((props.item.wordsCount ?? 0) / 235) + )} min read` + : null} + {props.item.highlights?.length ?? 0 > 0 + ? ` • ${props.item.highlights?.length} highlights` + : null} + + + )} + + + {props.item.title} + + {expanded && ( + <> + + + {(props.item.highlights ?? []).map((highlight) => ( + + ))} + + + )} + + {!expanded ? ( + + ) : ( + + )} + + + + ) +} + +type HighlightItemCardProps = { + highlight: Highlight + viewer: UserBasicData | undefined + item: LibraryItemNode +} + +const StyledQuote = styled(Blockquote, { + margin: '0px', + fontSize: '16px', + fontFamily: '$inter', + lineHeight: '1.50', + color: '$thHighContrast', + paddingLeft: '15px', + borderLeft: '2px solid $omnivoreCtaYellow', +}) + +function HighlightItemCard(props: HighlightItemCardProps): JSX.Element { + const router = useRouter() + const [hover, setHover] = useState(false) + const [isEditing, setIsEditing] = useState(false) + + const lines = useMemo( + () => props.highlight.quote.split('\n'), + [props.highlight.quote] + ) + + return ( + setHover(true)} + onMouseLeave={() => setHover(false)} + > + { + if (router && props.viewer) { + const dest = `/${props.viewer}/${props.item.slug}#${props.highlight.id}` + router.push(dest) + } + event.preventDefault() + }} + > + + + {lines.map((line: string, index: number) => ( + + {line} + {index !== lines.length - 1 && ( + <> +
+
+ + )} +
+ ))} +
+
+ + + {props.highlight.labels?.map((label: Label, index: number) => ( + + ))} + + + setIsEditing(true)} + > + {props.highlight.annotation + ? props.highlight.annotation + : 'Add your notes...'} + +
+ + + +
+ ) +} + +function HighlightsMenu(): JSX.Element { + return ( + + + + } + > + { + console.log('copy') + }} + title="Copy" + /> + { + console.log('labels') + }} + title="Labels" + /> + { + console.log('delete') + }} + title="Delete" + /> + + ) +} diff --git a/packages/web/components/templates/article/HighlightHoverCard.tsx b/packages/web/components/templates/article/HighlightHoverCard.tsx new file mode 100644 index 000000000..ccaa5a3cd --- /dev/null +++ b/packages/web/components/templates/article/HighlightHoverCard.tsx @@ -0,0 +1,37 @@ +import { Box } from '../../elements/LayoutPrimitives' +import { theme } from '../../tokens/stitches.config' +import { Highlight } from '../../../lib/networking/fragments/highlightFragment' +import { HighlightView } from '../../patterns/HighlightView' + +type PageCoordinates = { + pageX: number + pageY: number +} + +type HighlightHoverCardProps = { + highlight: Highlight + anchorCoordinates: PageCoordinates +} + +export function HighlightHoverCard( + props: HighlightHoverCardProps +): JSX.Element { + return ( + + + + ) +}