From 2b3356a49b97e74d7c3b4295661c737e59d3429d Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Fri, 9 Feb 2024 14:12:54 -0600 Subject: [PATCH 1/8] Fix film simulation links on photos --- src/photo/PhotoLarge.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/photo/PhotoLarge.tsx b/src/photo/PhotoLarge.tsx index 2ce202f1..a9cc1646 100644 --- a/src/photo/PhotoLarge.tsx +++ b/src/photo/PhotoLarge.tsx @@ -89,7 +89,7 @@ export default function PhotoLarge({ -
+
@@ -104,7 +104,7 @@ export default function PhotoLarge({ type="text-only" /> {showSimulation && photo.filmSimulation && -
+
From b5b2eb8f46409c2ba7794a8f8890f50a4b63e671 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Fri, 9 Feb 2024 20:38:31 -0600 Subject: [PATCH 2/8] =?UTF-8?q?Add=20shadow=20to=20=E2=80=A2=E2=80=A2?= =?UTF-8?q?=E2=80=A2=20menu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MoreMenu.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/MoreMenu.tsx b/src/components/MoreMenu.tsx index d553d059..d3d6aef4 100644 --- a/src/components/MoreMenu.tsx +++ b/src/components/MoreMenu.tsx @@ -34,6 +34,7 @@ export default function MoreMenu({ 'text-sm', 'p-1 rounded-md border', 'bg-content', + 'shadow-lg dark:shadow-xl', )}> {items.map(({ href, label }) => From 8151a4f1cd67f6b509ce6f4e27907c1df4540a29 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Fri, 9 Feb 2024 20:56:21 -0600 Subject: [PATCH 3/8] Simplify AdminPhotoMenu types --- src/admin/AdminPhotoMenu.tsx | 8 +++++--- src/admin/AdminPhotoMenuClient.tsx | 9 +++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/admin/AdminPhotoMenu.tsx b/src/admin/AdminPhotoMenu.tsx index c32c7c84..84f7259b 100644 --- a/src/admin/AdminPhotoMenu.tsx +++ b/src/admin/AdminPhotoMenu.tsx @@ -1,8 +1,10 @@ import { authCached } from '@/auth/cache'; -import AdminPhotoMenuClient, { AdminPhotoMenuClientProps } - from './AdminPhotoMenuClient'; +import AdminPhotoMenuClient from './AdminPhotoMenuClient'; +import { ComponentProps } from 'react'; -export default async function AdminPhotoMenu(props: AdminPhotoMenuClientProps) { +export default async function AdminPhotoMenu( + props: ComponentProps, +) { const session = await authCached(); return Boolean(session?.user?.email) ? diff --git a/src/admin/AdminPhotoMenuClient.tsx b/src/admin/AdminPhotoMenuClient.tsx index d861dd1f..e75de192 100644 --- a/src/admin/AdminPhotoMenuClient.tsx +++ b/src/admin/AdminPhotoMenuClient.tsx @@ -4,15 +4,12 @@ import { ComponentProps } from 'react'; import { pathForAdminPhotoEdit } from '@/site/paths'; import MoreMenu from '../components/MoreMenu'; -export interface AdminPhotoMenuClientProps - extends Omit, 'items'> { - photoId: string -} - export default function AdminPhotoMenuClient({ photoId, ...props -}: AdminPhotoMenuClientProps) { +}: Omit, 'items'> & { + photoId: string +}) { return ( Date: Sat, 10 Feb 2024 01:11:23 -0600 Subject: [PATCH 4/8] Add favorites to admin photo menu --- src/admin/AdminPhotoMenuClient.tsx | 28 ++++++++++-- src/components/MoreMenu.tsx | 73 +++++++++++++++++++++++------- src/photo/PhotoLarge.tsx | 2 +- src/photo/actions.ts | 10 +++- src/tag/index.ts | 11 ++++- 5 files changed, 100 insertions(+), 24 deletions(-) diff --git a/src/admin/AdminPhotoMenuClient.tsx b/src/admin/AdminPhotoMenuClient.tsx index e75de192..c90fddb0 100644 --- a/src/admin/AdminPhotoMenuClient.tsx +++ b/src/admin/AdminPhotoMenuClient.tsx @@ -3,16 +3,38 @@ import { ComponentProps } from 'react'; import { pathForAdminPhotoEdit } from '@/site/paths'; import MoreMenu from '../components/MoreMenu'; +import { toggleFavoritePhoto } from '@/photo/actions'; +import { FaRegEdit, FaStar } from 'react-icons/fa'; +import { Photo } from '@/photo'; +import { isPathFavs, isPhotoFav } from '@/tag'; +import clsx from 'clsx/lite'; +import { usePathname } from 'next/navigation'; export default function AdminPhotoMenuClient({ - photoId, + photo, ...props }: Omit, 'items'> & { - photoId: string + photo: Photo }) { + const isFav = isPhotoFav(photo); + const path = usePathname(); + const shouldRedirect = isPathFavs(path) && isFav; return ( , + href: pathForAdminPhotoEdit(photo.id), + }, { + label: isFav ? 'Unfavorite' : 'Favorite', + icon: , + action: () => toggleFavoritePhoto(photo.id, shouldRedirect), + }, + ], ...props, }}/> ); diff --git a/src/components/MoreMenu.tsx b/src/components/MoreMenu.tsx index d3d6aef4..8c41ab1a 100644 --- a/src/components/MoreMenu.tsx +++ b/src/components/MoreMenu.tsx @@ -2,17 +2,45 @@ import { clsx} from 'clsx/lite'; import Link from 'next/link'; import { Menu } from '@headlessui/react'; import { FiMoreHorizontal } from 'react-icons/fi'; -import { ReactNode } from 'react'; +import { Fragment, ReactNode, useState } from 'react'; export default function MoreMenu({ items, className, buttonClassName, }: { - items: { href: string, label: ReactNode }[] + items: { + label: ReactNode, + icon?: ReactNode, + href?: string, + action?: () => Promise, + }[] className?: string buttonClassName?: string }) { + const [isLoading, setIsLoading] = useState(false); + + const itemClass = clsx( + 'block w-full', + 'border-none min-h-0 bg-transparent', + 'text-left', + 'px-3 py-1.5 rounded-[3px]', + 'hover:text-main', + 'hover:bg-gray-50 active:bg-gray-100', + 'hover:dark:bg-gray-900/75 active:dark:bg-gray-900', + 'whitespace-nowrap', + isLoading && 'cursor-not-allowed opacity-50', + ); + + const renderItemContent = ( + label: ReactNode, + icon?: ReactNode, + ) => +
+ {icon} + {label} +
; + return (
- {items.map(({ href, label }) => - - - {label} - + {items.map(({ label, icon, href, action }) => + + <> + {href && + + {renderItemContent(label, icon)} + } + {action && + } + )} diff --git a/src/photo/PhotoLarge.tsx b/src/photo/PhotoLarge.tsx index a9cc1646..ecfe79ac 100644 --- a/src/photo/PhotoLarge.tsx +++ b/src/photo/PhotoLarge.tsx @@ -90,7 +90,7 @@ export default function PhotoLarge({
- +
diff --git a/src/photo/actions.ts b/src/photo/actions.ts index db8137ec..0f272b48 100644 --- a/src/photo/actions.ts +++ b/src/photo/actions.ts @@ -23,7 +23,7 @@ import { revalidateAllKeysAndPaths, revalidatePhotosKey, } from '@/photo/cache'; -import { PATH_ADMIN_PHOTOS, PATH_ADMIN_TAGS } from '@/site/paths'; +import { PATH_ADMIN_PHOTOS, PATH_ADMIN_TAGS, PATH_ROOT } from '@/site/paths'; import { extractExifDataFromBlobPath } from './server'; import { TAG_FAVS, isTagFavs } from '@/tag'; import { convertPhotoToPhotoDbInsert } from '.'; @@ -52,7 +52,10 @@ export async function updatePhotoAction(formData: FormData) { redirect(PATH_ADMIN_PHOTOS); } -export async function toggleFavoritePhoto(photoId: string) { +export async function toggleFavoritePhoto( + photoId: string, + shouldRedirect?: boolean, +) { const photo = await getPhoto(photoId); if (photo) { const { tags } = photo; @@ -61,6 +64,9 @@ export async function toggleFavoritePhoto(photoId: string) { : [...tags, TAG_FAVS]; await sqlUpdatePhoto(convertPhotoToPhotoDbInsert(photo)); revalidateAllKeysAndPaths(); + if (shouldRedirect) { + redirect(PATH_ROOT); + } } } diff --git a/src/tag/index.ts b/src/tag/index.ts index 58384d0a..60f9ed86 100644 --- a/src/tag/index.ts +++ b/src/tag/index.ts @@ -4,7 +4,11 @@ import { descriptionForPhotoSet, photoQuantityText, } from '@/photo'; -import { absolutePathForTag, absolutePathForTagImage } from '@/site/paths'; +import { + absolutePathForTag, + absolutePathForTagImage, + getPathComponents, +} from '@/site/paths'; import { capitalizeWords, convertStringToArray } from '@/utility/string'; export const TAG_FAVS = 'favs'; @@ -77,3 +81,8 @@ export const generateMetaForTag = ( }); export const isTagFavs = (tag: string) => tag.toLowerCase() === TAG_FAVS; + +export const isPhotoFav = ({ tags }: Photo) => tags.some(isTagFavs); + +export const isPathFavs = (pathname?: string) => + getPathComponents(pathname).tag === TAG_FAVS; From 9aaed392dcb1e5201397d6bece1a606937b71a9d Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sat, 10 Feb 2024 16:25:22 -0600 Subject: [PATCH 5/8] Refine admin more menu --- src/admin/AdminPhotoMenuClient.tsx | 16 ++++++++++------ src/components/MoreMenu.tsx | 6 +++--- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/admin/AdminPhotoMenuClient.tsx b/src/admin/AdminPhotoMenuClient.tsx index c90fddb0..6f72e2b1 100644 --- a/src/admin/AdminPhotoMenuClient.tsx +++ b/src/admin/AdminPhotoMenuClient.tsx @@ -4,10 +4,9 @@ import { ComponentProps } from 'react'; import { pathForAdminPhotoEdit } from '@/site/paths'; import MoreMenu from '../components/MoreMenu'; import { toggleFavoritePhoto } from '@/photo/actions'; -import { FaRegEdit, FaStar } from 'react-icons/fa'; +import { FaRegEdit, FaRegStar, FaStar } from 'react-icons/fa'; import { Photo } from '@/photo'; import { isPathFavs, isPhotoFav } from '@/tag'; -import clsx from 'clsx/lite'; import { usePathname } from 'next/navigation'; export default function AdminPhotoMenuClient({ @@ -28,10 +27,15 @@ export default function AdminPhotoMenuClient({ href: pathForAdminPhotoEdit(photo.id), }, { label: isFav ? 'Unfavorite' : 'Favorite', - icon: , + icon: isFav + ? + : , action: () => toggleFavoritePhoto(photo.id, shouldRedirect), }, ], diff --git a/src/components/MoreMenu.tsx b/src/components/MoreMenu.tsx index 8c41ab1a..1a5a7480 100644 --- a/src/components/MoreMenu.tsx +++ b/src/components/MoreMenu.tsx @@ -29,6 +29,7 @@ export default function MoreMenu({ 'hover:bg-gray-50 active:bg-gray-100', 'hover:dark:bg-gray-900/75 active:dark:bg-gray-900', 'whitespace-nowrap', + 'shadow-none', isLoading && 'cursor-not-allowed opacity-50', ); @@ -56,11 +57,10 @@ export default function MoreMenu({ Date: Sat, 10 Feb 2024 16:36:36 -0600 Subject: [PATCH 6/8] Simplify admin checklist --- src/components/Checklist.tsx | 10 ++++++--- src/components/ChecklistRow.tsx | 1 - src/site/SiteChecklistClient.tsx | 37 +++++++++++++++++--------------- src/site/config.ts | 4 ++-- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/components/Checklist.tsx b/src/components/Checklist.tsx index 811e9b46..cb80dded 100644 --- a/src/components/Checklist.tsx +++ b/src/components/Checklist.tsx @@ -4,10 +4,12 @@ import { clsx } from 'clsx/lite'; export default function Checklist({ title, icon, + optional, children, }: { title: string icon?: ReactNode + optional?: boolean children: ReactNode }) { return ( @@ -15,11 +17,13 @@ export default function Checklist({
{icon} -
- {title} +
+
{title}
+ {optional && +
(Optional)
}
{title} - {optional && ' (optional)'}
{children} diff --git a/src/site/SiteChecklistClient.tsx b/src/site/SiteChecklistClient.tsx index e69b363d..7b08db87 100644 --- a/src/site/SiteChecklistClient.tsx +++ b/src/site/SiteChecklistClient.tsx @@ -29,7 +29,7 @@ export default function SiteChecklistClient({ hasAwsS3Storage, hasMultipleStorageProviders, currentStorage, - hasAuth, + hasAuthSecret, hasAdminUser, hasTitle, hasDomain, @@ -198,26 +198,27 @@ export default function SiteChecklistClient({ > Store auth secret in environment variable: -
- -
- {secret} -
- {renderCopyButton('Secret', secret)} - } - onClick={refreshSecret} - isLoading={isPendingSecret} - spinnerColor="text" - /> + {!hasAuthSecret && +
+ +
+ {secret} +
+ {renderCopyButton('Secret', secret)} + } + onClick={refreshSecret} + isLoading={isPendingSecret} + spinnerColor="text" + /> +
-
- -
+ +
} {renderEnvVars(['AUTH_SECRET'])} } + optional > } + optional > 0, + hasAuthSecret: (process.env.AUTH_SECRET ?? '').length > 0, hasAdminUser: ( (process.env.ADMIN_EMAIL ?? '').length > 0 && (process.env.ADMIN_PASSWORD ?? '').length > 0 @@ -134,5 +134,5 @@ export type ConfigChecklistStatus = typeof CONFIG_CHECKLIST_STATUS; export const IS_SITE_READY = CONFIG_CHECKLIST_STATUS.hasPostgres && CONFIG_CHECKLIST_STATUS.hasStorage && - CONFIG_CHECKLIST_STATUS.hasAuth && + CONFIG_CHECKLIST_STATUS.hasAuthSecret && CONFIG_CHECKLIST_STATUS.hasAdminUser; From c07b1c1700ef01dd4cb4436c5e87d3c74dd86b71 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sat, 10 Feb 2024 17:40:15 -0600 Subject: [PATCH 7/8] Remove menu outline in safari --- src/components/MoreMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MoreMenu.tsx b/src/components/MoreMenu.tsx index 1a5a7480..be03e36b 100644 --- a/src/components/MoreMenu.tsx +++ b/src/components/MoreMenu.tsx @@ -62,7 +62,7 @@ export default function MoreMenu({ 'text-sm text-left', 'md:right-1', 'p-1 rounded-md border', - 'bg-content', + 'bg-content outline-none', 'shadow-lg dark:shadow-xl', )}> {items.map(({ label, icon, href, action }) => From 81ba7228b5ed691bbfd0a001fc4c7758561c1cf7 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sat, 10 Feb 2024 23:50:03 -0600 Subject: [PATCH 8/8] Make admin menu text consistent --- src/components/MoreMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MoreMenu.tsx b/src/components/MoreMenu.tsx index be03e36b..8de42a45 100644 --- a/src/components/MoreMenu.tsx +++ b/src/components/MoreMenu.tsx @@ -23,7 +23,7 @@ export default function MoreMenu({ const itemClass = clsx( 'block w-full', 'border-none min-h-0 bg-transparent', - 'text-left', + 'text-left text-main', 'px-3 py-1.5 rounded-[3px]', 'hover:text-main', 'hover:bg-gray-50 active:bg-gray-100', @@ -59,7 +59,7 @@ export default function MoreMenu({