import { DragDropContext, Draggable, type DraggableProvided, Droppable, type DroppableProvided, } from '@hello-pangea/dnd'; import { ActionIcon, Box, Button, Card, Group, Popover, Stack, Text, TextInput, } from '@mantine/core'; import { isNotEmpty, useForm } from '@mantine/form'; import { useDebouncedValue, useDisclosure } from '@mantine/hooks'; import { DeleteItemModal, ManagementPill } from 'components'; import { useCommonHooks, useMutationAPI } from 'hooks'; import { useEffect, useState } from 'react'; import { FaChevronLeft } from 'react-icons/fa'; import { FiPlus } from 'react-icons/fi'; import { buttonClasses, cardClasses, popoverClasses, textClasses, textInputClasses, } from 'styles'; import type { Bookmark, BookmarkGroup } from 'types'; import BookmarkSettingsItem from './BookmarkSettingsItem'; import DebouncedBookmarkItem from './DebouncedBookmarkItem'; function DebouncedGroupSettingsItem({ bookmarkGroup, bookmarks, searchTerm, }: { bookmarkGroup: BookmarkGroup; bookmarks: Bookmark[]; searchTerm: string; }) { const { isMobile, handleDelete, reorder, theme } = useCommonHooks(); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); const [popoverOpened, setPopoverOpened] = useState(false); const { mutateAsync } = useMutationAPI(); const [group, setGroup] = useState(bookmarkGroup); const [update, setUpdate] = useState({}); const [debounced] = useDebouncedValue(update, 1000); const [newBookmark, setNewBookmark] = useState({ id: undefined, name: '', url: '', category: group.categoryName, index: 0, enabled: 1, }); const form = useForm({ initialValues: newBookmark, validate: { name: isNotEmpty('Name is required'), url: isNotEmpty('URL is required'), }, }); const [bookmarkList, setBookmarkList] = useState(bookmarks); const [isOpen, setIsOpen] = useState(false); function onDragEnd(result: any) { if (!result.destination) { return; } if (result.destination.index === result.source.index) { return; } const items = reorder(bookmarkList, result.source.index, result.destination.index); setBookmarkList( items.map((item: any, index: number) => { return { ...item, index: index, }; }), ); } useEffect(() => { if (Object.keys(debounced).length) { mutateAsync({ method: 'PATCH', endpoint: 'api/bookmarkCategories', body: debounced, }); setUpdate({}); } }, [debounced]); useEffect(() => { if (update !== group && Object.keys(update).length) { setGroup(update); } }, [update]); useEffect(() => { if (bookmarkList && bookmarkList !== bookmarks) { mutateAsync({ method: 'PATCH', endpoint: 'api/bookmarkOrder', body: bookmarkList }); } }, [bookmarkList]); return ( { bookmarks.length > 0 && handleDelete(bookmarks, 'api/bookmarks'); handleDelete(group, 'api/bookmarkCategories'); }} title='Delete message' body={ Are you sure you want to delete this bookmark group? {`"${group.categoryName}"`} This will also delete all bookmarks in this group! This action cannot be undone! } /> { setUpdate({ ...group, categoryName: event.target.value, }); }} styles={ theme.textShadowsEnabled ? { label: { boxShadow: '2px 2px var(--mantine-color-border-0)' }, } : undefined } /> { setUpdate({ ...group, filterName: event.target.value, }); }} styles={ theme.textShadowsEnabled ? { label: { boxShadow: '2px 2px var(--mantine-color-border-0)' }, } : undefined } /> {bookmarks.length} ) => { setUpdate({ ...group, enabled: event.target.checked ? 1 : 0, }); }} openModal={openModal} /> {(provided: DroppableProvided) => ( {bookmarks.map((bookmark: Bookmark) => ( {(provided: DraggableProvided) => ( {(bookmark.name.toLowerCase().includes(searchTerm) || bookmark.url.toLowerCase().includes(searchTerm)) && searchTerm && ( )} )} ))} {provided.placeholder} )}
{ mutateAsync({ method: 'POST', endpoint: 'api/bookmarks', body: { ...values, index: bookmarks.length }, }); setPopoverOpened(false); form.reset(); })} >
); } export default DebouncedGroupSettingsItem;