From 0465b51427c48ccfb148e8e3d211ea9d13ec33ff Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sat, 28 Feb 2026 14:16:14 -0600 Subject: [PATCH] Create custom photo chooser grid --- app/admin/components/page.tsx | 12 +++- src/admin/AdminComponentPageClient.tsx | 6 ++ src/photo/form/FieldsetPhotoChooser.tsx | 93 ++++++++++++++++++------- src/photo/useDynamicPhoto.ts | 2 +- 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/app/admin/components/page.tsx b/app/admin/components/page.tsx index 9869f3ff..90a17f40 100644 --- a/app/admin/components/page.tsx +++ b/app/admin/components/page.tsx @@ -1,10 +1,16 @@ import AdminComponentPageClient from '@/admin/AdminComponentPageClient'; -import { getPhotosCached } from '@/photo/cache'; +import { getPhotosCached, getPhotosMetaCached } from '@/photo/cache'; export default async function ComponentsPage() { - const photos = await getPhotosCached({ limit: 1}); + const photos = await getPhotosCached(); + const photosCount = await getPhotosMetaCached() + .then(({ count }) => count); return ( - + ); } diff --git a/src/admin/AdminComponentPageClient.tsx b/src/admin/AdminComponentPageClient.tsx index 5ddb6ca0..e70d4208 100644 --- a/src/admin/AdminComponentPageClient.tsx +++ b/src/admin/AdminComponentPageClient.tsx @@ -15,8 +15,12 @@ import FieldsetPhotoChooser from '@/photo/form/FieldsetPhotoChooser'; export default function ComponentsPageClient({ photo, + photos, + photosCount, }: { photo: Photo + photos: Photo[] + photosCount: number }) { const [valuePhoto, setValuePhoto] = useState(photo?.id ?? ''); const [valuePhotoChooser, setValuePhotoChooser] = useState(photo?.id ?? ''); @@ -39,6 +43,8 @@ export default function ComponentsPageClient({ diff --git a/src/photo/form/FieldsetPhotoChooser.tsx b/src/photo/form/FieldsetPhotoChooser.tsx index 46576f55..2f2cb2c5 100644 --- a/src/photo/form/FieldsetPhotoChooser.tsx +++ b/src/photo/form/FieldsetPhotoChooser.tsx @@ -3,10 +3,11 @@ import { altTextForPhoto, doesPhotoNeedBlurCompatibility, Photo } from '..'; import clsx from 'clsx/lite'; import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; import ImageMedium from '@/components/image/ImageMedium'; -import PhotoGridInfinite from '../PhotoGridInfinite'; import { menuSurfaceStyles } from '@/components/primitives/surface'; import { GRID_SPACE_CLASSNAME } from '@/components'; -import PhotoGrid from '../PhotoGrid'; +import useDynamicPhoto from '../useDynamicPhoto'; +import { IoSearch } from 'react-icons/io5'; +import { useState } from 'react'; export default function FieldsetPhotoChooser({ label, @@ -14,7 +15,6 @@ export default function FieldsetPhotoChooser({ onChange, photo, photos = [], - photosCount, }: { label: string value: string @@ -24,26 +24,37 @@ export default function FieldsetPhotoChooser({ photosCount?: number photosHidden?: Photo[] }) { + const [query, setQuery] = useState(''); + + const { + photo: photoAvatar, + isLoading: isLoadingPhotoAvatar, + } = useDynamicPhoto({ + initialPhoto: photo, + photoId: value, + }); + return ( <> @@ -55,16 +66,46 @@ export default function FieldsetPhotoChooser({ >
- {photos.length > 0 && - } - {(!photosCount || photosCount > photos.length) && - } +
+
+ Choose photo +
+ +
+ setQuery(e.target.value)} + /> +
+ {photos.map(photo => ( + + onChange(photo.id)} + /> + + ))} +
diff --git a/src/photo/useDynamicPhoto.ts b/src/photo/useDynamicPhoto.ts index ea4963ce..b3f36a8a 100644 --- a/src/photo/useDynamicPhoto.ts +++ b/src/photo/useDynamicPhoto.ts @@ -14,7 +14,7 @@ export default function useDynamicPhoto({ const [isLoading, setIsLoading] = useState(false); - const [photoIdDebounced] = useDebounce(photoId, 500); + const [photoIdDebounced] = useDebounce(photoId, 500, { leading: true }); useEffect(() => { if (photoIdDebounced) {