Animate query menu, add favs to chooser

This commit is contained in:
Sam Becker 2026-03-01 13:50:01 -06:00
parent bd2dd6a030
commit 017869fda9
5 changed files with 48 additions and 29 deletions

View File

@ -7,6 +7,7 @@ import {
getPhotosMetaCached, getPhotosMetaCached,
} from '@/photo/cache'; } from '@/photo/cache';
import { getPhoto } from '@/photo/query'; import { getPhoto } from '@/photo/query';
import { TAG_FAVS } from '@/tag';
const PHOTO_CHOOSER_QUERY_OPTIONS = feedQueryOptions({ const PHOTO_CHOOSER_QUERY_OPTIONS = feedQueryOptions({
isGrid: true, isGrid: true,
@ -22,7 +23,7 @@ export default async function AboutEditPage() {
}, },
photos, photos,
photosCount, photosCount,
photosHidden, photosFavs,
] = await Promise.all([ ] = await Promise.all([
getAbout() getAbout()
.then(async about => { .then(async about => {
@ -52,7 +53,7 @@ export default async function AboutEditPage() {
getPhotosMetaCached(PHOTO_CHOOSER_QUERY_OPTIONS) getPhotosMetaCached(PHOTO_CHOOSER_QUERY_OPTIONS)
.then(({ count }) => count) .then(({ count }) => count)
.catch(() => 0), .catch(() => 0),
getPhotosCached({ hidden: 'only', limit: 1000 }) getPhotosCached({ tag: TAG_FAVS })
.catch(() => []), .catch(() => []),
]); ]);
@ -63,7 +64,7 @@ export default async function AboutEditPage() {
photoHero, photoHero,
photos, photos,
photosCount, photosCount,
photosHidden, photosFavs,
shouldResizeImages: !PRESERVE_ORIGINAL_UPLOADS, shouldResizeImages: !PRESERVE_ORIGINAL_UPLOADS,
}} /> }} />
); );

View File

@ -1,17 +1,20 @@
import AdminComponentPageClient from '@/admin/AdminComponentPageClient'; import AdminComponentPageClient from '@/admin/AdminComponentPageClient';
import { INFINITE_SCROLL_GRID_INITIAL } from '@/photo'; import { INFINITE_SCROLL_GRID_INITIAL } from '@/photo';
import { getPhotosCached, getPhotosMetaCached } from '@/photo/cache'; import { getPhotosCached, getPhotosMetaCached } from '@/photo/cache';
import { TAG_FAVS } from '@/tag';
export default async function ComponentsPage() { export default async function ComponentsPage() {
const photos = await getPhotosCached({ limit: INFINITE_SCROLL_GRID_INITIAL }); const photos = await getPhotosCached({ limit: INFINITE_SCROLL_GRID_INITIAL });
const photosCount = await getPhotosMetaCached() const photosCount = await getPhotosMetaCached()
.then(({ count }) => count); .then(({ count }) => count);
const photosFavs = await getPhotosCached({ tag: TAG_FAVS });
return ( return (
<AdminComponentPageClient <AdminComponentPageClient
photo={photos[0]} photo={photos[0]}
photos={photos} photos={photos}
photosCount={photosCount} photosCount={photosCount}
photosFavs={photosFavs}
/> />
); );
} }

View File

@ -22,12 +22,14 @@ export default function AdminAboutEditPage({
photoHero: _photoHero, photoHero: _photoHero,
photos, photos,
photosCount, photosCount,
photosFavs,
}: { }: {
about?: About about?: About
photoAvatar?: Photo photoAvatar?: Photo
photoHero?: Photo photoHero?: Photo
photos: Photo[] photos: Photo[]
photosCount: number photosCount: number
photosFavs: Photo[]
shouldResizeImages?: boolean shouldResizeImages?: boolean
}) { }) {
const appText = useAppText(); const appText = useAppText();
@ -71,6 +73,7 @@ export default function AdminAboutEditPage({
photo={photoAvatar} photo={photoAvatar}
photos={photos} photos={photos}
photosCount={photosCount} photosCount={photosCount}
photosFavs={photosFavs}
/> />
<PhotoAvatar photo={photoAvatar} /> <PhotoAvatar photo={photoAvatar} />
<FieldsetWithStatus <FieldsetWithStatus

View File

@ -16,10 +16,12 @@ export default function AdminComponentPageClient({
photo, photo,
photos, photos,
photosCount, photosCount,
photosFavs,
}: { }: {
photo: Photo photo: Photo
photos: Photo[] photos: Photo[]
photosCount: number photosCount: number
photosFavs: Photo[]
}) { }) {
const [valuePhoto, setValuePhoto] = useState(photo?.id ?? ''); const [valuePhoto, setValuePhoto] = useState(photo?.id ?? '');
@ -43,6 +45,7 @@ export default function AdminComponentPageClient({
photo={photo} photo={photo}
photos={photos} photos={photos}
photosCount={photosCount} photosCount={photosCount}
photosFavs={photosFavs}
value={valuePhoto} value={valuePhoto}
onChange={setValuePhoto} onChange={setValuePhoto}
/> />

View File

@ -38,6 +38,7 @@ export default function FieldsetPhotoChooser({
photo: _photo, photo: _photo,
photos = [], photos = [],
photosCount, photosCount,
photosFavs,
}: { }: {
label: string label: string
value: string value: string
@ -45,6 +46,7 @@ export default function FieldsetPhotoChooser({
photo?: Photo photo?: Photo
photos: Photo[] photos: Photo[]
photosCount: number photosCount: number
photosFavs: Photo[]
}) { }) {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
@ -154,10 +156,10 @@ export default function FieldsetPhotoChooser({
}} }}
/> />
<div className={clsx( <div className={clsx(
'border-t border-medium', 'flex items-center transition-all overflow-hidden',
'p-1', showQuery ? 'h-12 opacity-100' : 'h-0 opacity-0',
!showQuery && 'hidden',
)}> )}>
<div className="p-1 border-t border-medium w-full">
<input <input
id="query" id="query"
ref={inputRef} ref={inputRef}
@ -168,15 +170,22 @@ export default function FieldsetPhotoChooser({
onChange={e => setQuery(e.target.value)} onChange={e => setQuery(e.target.value)}
/> />
</div> </div>
</div>
<div className={clsx( <div className={clsx(
'w-[18rem] max-h-[20rem] overflow-y-auto', 'w-[18rem] max-h-[20rem] overflow-y-auto',
'space-y-0.5', 'space-y-0.5',
)}> )}>
<div className={CLASSNAME_GRID}> <div className={CLASSNAME_GRID}>
{(showQuery && query ? photosQuery : photos) {(showQuery && query
? photosQuery
: mode === 'favs'
? photosFavs : photos)
.map(photo => renderPhotoButton(photo))} .map(photo => renderPhotoButton(photo))}
</div> </div>
{!(showQuery && query) && photosCount > photos.length && {
!(showQuery && query) &&
photosCount > photos.length &&
mode !== 'favs' &&
<InfinitePhotoScroll <InfinitePhotoScroll
cacheKey="photo-chooser" cacheKey="photo-chooser"
initialOffset={photos.length} initialOffset={photos.length}