'use client'; import { ComponentProps, useMemo } from 'react'; import { getPathComponents, PATH_ROOT, pathForAdminPhotoEdit, pathForTag, } from '@/app/paths'; import { deletePhotoAction, syncPhotoAction, toggleFavoritePhotoAction, toggleHidePhotoAction, } from '@/photo/actions'; import { Photo, deleteConfirmationTextForPhoto, downloadFileNameForPhoto, } from '@/photo'; import { isPathFavs, isPhotoFav, TAG_HIDDEN } from '@/tag'; import { usePathname } from 'next/navigation'; import { BiTrash } from 'react-icons/bi'; import MoreMenu from '@/components/more/MoreMenu'; import { useAppState } from '@/state/AppState'; import { RevalidatePhoto } from '@/photo/InfinitePhotoScroll'; import { MdOutlineFileDownload } from 'react-icons/md'; import MoreMenuItem from '@/components/more/MoreMenuItem'; import IconGrSync from '@/components/icons/IconGrSync'; import InsightsIndicatorDot from './insights/InsightsIndicatorDot'; import IconFavs from '@/components/icons/IconFavs'; import IconEdit from '@/components/icons/IconEdit'; import { photoNeedsToBeSynced } from '@/photo/sync'; import { KEY_COMMANDS } from '@/photo/key-commands'; import { useAppText } from '@/i18n/state/client'; import IconHidden from '@/components/icons/IconHidden'; export default function AdminPhotoMenu({ photo, revalidatePhoto, includeFavorite = true, showKeyCommands, ...props }: Omit, 'sections'> & { photo: Photo revalidatePhoto?: RevalidatePhoto includeFavorite?: boolean showKeyCommands?: boolean }) { const { isUserSignedIn, registerAdminUpdate } = useAppState(); const appText = useAppText(); const path = usePathname(); const pathComponents = getPathComponents(path); const isOnPhotoDetail = pathComponents.photoId === photo.id; const isFav = isPhotoFav(photo); const shouldRedirectFav = isPathFavs(path) && isFav; const shouldRedirectDelete = isOnPhotoDetail; const redirectPathOnHideToggle = isOnPhotoDetail ? photo.hidden ? pathForTag(TAG_HIDDEN) : PATH_ROOT : undefined; const sectionMain = useMemo(() => { const items: ComponentProps[] = [{ label: appText.admin.edit, icon: , href: pathForAdminPhotoEdit(photo.id), ...showKeyCommands && { keyCommand: KEY_COMMANDS.edit }, }]; if (includeFavorite) { items.push({ label: isFav ? appText.admin.unfavorite : appText.admin.favorite, icon: , action: () => toggleFavoritePhotoAction( photo.id, shouldRedirectFav, ).then(() => revalidatePhoto?.(photo.id)), ...showKeyCommands && { keyCommand: isFav ? KEY_COMMANDS.unfavorite : KEY_COMMANDS.favorite, }, }); } items.push({ label: photo.hidden ? appText.admin.unhide : appText.admin.hide, icon: , action: () => toggleHidePhotoAction( photo.id, redirectPathOnHideToggle, ) .then(() => revalidatePhoto?.(photo.id)), ...showKeyCommands && { keyCommand: KEY_COMMANDS.toggleHide, }, }); items.push({ label: appText.admin.download, icon: , href: photo.url, hrefDownloadName: downloadFileNameForPhoto(photo), ...showKeyCommands && { keyCommand: KEY_COMMANDS.download }, }); items.push({ label: appText.admin.sync, labelComplex: {appText.admin.sync} {photoNeedsToBeSynced(photo) && } , icon: , action: () => syncPhotoAction(photo.id) .then(() => revalidatePhoto?.(photo.id)), ...showKeyCommands && { keyCommand: KEY_COMMANDS.sync }, }); return items; }, [ appText, photo, showKeyCommands, includeFavorite, isFav, shouldRedirectFav, redirectPathOnHideToggle, revalidatePhoto, ]); const sectionDelete: ComponentProps[] = useMemo(() => [{ label: appText.admin.delete, icon: , className: 'text-error *:hover:text-error', color: 'red', action: () => { if (confirm(deleteConfirmationTextForPhoto(photo, appText))) { return deletePhotoAction( photo.id, photo.url, shouldRedirectDelete, ).then(() => { revalidatePhoto?.(photo.id, true); registerAdminUpdate?.(); }); } }, ...showKeyCommands && { keyCommandModifier: KEY_COMMANDS.delete[0], keyCommand: KEY_COMMANDS.delete[1], }, }], [ appText, photo, showKeyCommands, revalidatePhoto, shouldRedirectDelete, registerAdminUpdate, ]); const sections = useMemo(() => [sectionMain, sectionDelete] , [sectionMain, sectionDelete]); return ( isUserSignedIn ? : null ); }