diff --git a/packages/web/components/templates/homeFeed/EditItemModals.tsx b/packages/web/components/templates/homeFeed/EditItemModals.tsx new file mode 100644 index 000000000..3642bbf07 --- /dev/null +++ b/packages/web/components/templates/homeFeed/EditItemModals.tsx @@ -0,0 +1,425 @@ +import { + ModalRoot, + ModalContent, + ModalOverlay, +} from '../../elements/ModalPrimitives' +import { VStack, HStack, Box } from '../../elements/LayoutPrimitives' +import { Button } from '../../elements/Button' +import { StyledText } from '../../elements/StyledText' + +import { FormInput } from '../../elements/FormElements' +import { useCallback, useState } from 'react' +import { LibraryItem } from '../../../lib/networking/queries/useGetLibraryItemsQuery' +import { StyledTextArea } from '../../elements/StyledTextArea' +import { updatePageMutation } from '../../../lib/networking/mutations/updatePageMutation' +import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers' +import dayjs, { Dayjs } from 'dayjs' +import { X } from 'phosphor-react' +import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery' + +type EditLibraryItemModalProps = { + onOpenChange: (open: boolean) => void + item: LibraryItem + updateItem: (item: LibraryItem) => Promise +} + +export function EditLibraryItemModal( + props: EditLibraryItemModalProps +): JSX.Element { + const onSave = useCallback( + ( + title: string, + author: string | undefined, + description: string, + savedAt: Dayjs, + publishedAt: Dayjs | undefined + ) => { + ;(async () => { + if (title !== '') { + const res = await updatePageMutation({ + pageId: props.item.node.id, + title, + description, + byline: author, + // savedAt: savedAt.toISOString(), + }) + + if (res) { + await props.updateItem({ + cursor: props.item.cursor, + node: { + ...props.item.node, + title: title, + author: author, + description: description, + }, + }) + showSuccessToast('Link updated succesfully', { + position: 'bottom-right', + }) + props.onOpenChange(false) + } else { + showErrorToast('There was an error updating your link', { + position: 'bottom-right', + }) + } + } else { + showErrorToast('Title must be a non-empty value', { + position: 'bottom-right', + }) + } + })() + }, + [] + ) + + return ( + + ) +} + +type EditArticleModalProps = { + onOpenChange: (open: boolean) => void + article: ArticleAttributes + updateArticle: ( + title: string, + author: string | undefined, + description: string, + savedAt: string, + publishedAt: string | undefined + ) => void +} + +export function EditArticleModal(props: EditArticleModalProps): JSX.Element { + const onSave = useCallback( + ( + title: string, + author: string | undefined, + description: string, + savedAt: Dayjs, + publishedAt: Dayjs | undefined + ) => { + ;(async () => { + if (title !== '') { + const res = await updatePageMutation({ + pageId: props.article.id, + title, + description, + byline: author, + // savedAt: savedAt.toISOString(), + }) + if (res) { + props.updateArticle( + title, + author, + description, + savedAt.toISOString(), + publishedAt ? publishedAt.toISOString() : undefined + ) + showSuccessToast('Link updated succesfully', { + position: 'bottom-right', + }) + props.onOpenChange(false) + } else { + showErrorToast('There was an error updating your link', { + position: 'bottom-right', + }) + } + } else { + showErrorToast('Title must be a non-empty value', { + position: 'bottom-right', + }) + } + })() + }, + [] + ) + + return ( + + ) +} + +type EditItemModalProps = { + title: string + author: string | undefined + description: string + + savedAt: Dayjs + publishedAt: Dayjs | undefined + onOpenChange: (open: boolean) => void + + onSave: ( + title: string, + author: string | undefined, + description: string, + savedAt: Dayjs, + publishedAt: Dayjs | undefined + ) => void +} + +function EditItemModal(props: EditItemModalProps): JSX.Element { + const [title, setTitle] = useState(props.title) + const [author, setAuthor] = useState(props.author) + const [savedAt, setSavedAt] = useState(props.savedAt) + const [publishedAt, setPublishedAt] = useState(props.publishedAt) + const [description, setDescription] = useState(props.description) + + const titleStyle = { + mt: '22px', + mb: '2px', + fontFamily: 'SF Pro Display', + fontWeight: '600', + fontSize: '9px', + color: '#898989', + } + + return ( + + + { + // remove focus from modal + ;(document.activeElement as HTMLElement).blur() + }} + > + +
+ +
{ + event.preventDefault() + }} + > + + + SAVED AT: + { + const dateStr = event.target.value + setSavedAt(dayjs(dateStr)) + }} + css={{ + mt: '1px', + borderRadius: '5px', + border: '1px solid #D9D9D9', + fontFamily: 'Inter', + fontWeight: '500', + fontSize: '12px', + height: '30px', + p: '5px', + color: '#3D3D3D', + '&:focus': { + outline: 'none !important', + border: '1px solid $omnivoreCtaYellow', + }, + }} + /> + + + PUBLISHED AT + { + const dateStr = event.target.value + setPublishedAt(dayjs(dateStr)) + }} + css={{ + mt: '1px', + borderRadius: '5px', + border: '1px solid #D9D9D9', + fontFamily: 'Inter', + fontWeight: '500', + fontSize: '12px', + height: '30px', + p: '5px', + color: '#3D3D3D', + '&:focus': { + outline: 'none !important', + border: '1px solid $omnivoreCtaYellow', + }, + }} + /> + + + TITLE + setTitle(event.target.value)} + css={{ + borderRadius: '5px', + border: '1px solid #D9D9D9', + width: '100%', + fontFamily: 'Inter', + fontWeight: '500', + fontSize: '12px', + height: '30px', + p: '5px', + color: '#3D3D3D', + '&:focus': { + outline: 'none !important', + border: '1px solid $omnivoreCtaYellow', + }, + }} + /> + AUTHOR + setAuthor(event.target.value)} + css={{ + borderRadius: '5px', + border: '1px solid #D9D9D9', + width: '100%', + fontFamily: 'Inter', + fontWeight: '500', + fontSize: '12px', + height: '30px', + p: '5px', + color: '#3D3D3D', + '&:focus': { + outline: 'none !important', + border: '1px solid $omnivoreCtaYellow', + }, + }} + /> + DESCRIPTION + + setDescription(event.target.value)} + maxLength={4000} + /> + + + + + +
+ + + + ) +} + +type HeaderProps = { + onOpenChange: (open: boolean) => void +} + +function Header(props: HeaderProps): JSX.Element { + return ( + + + Edit Title & Description + + + + + + ) +}