Wire up initial recipe paths

This commit is contained in:
Sam Becker 2025-03-02 23:42:41 -06:00
parent 2b93dd750f
commit 3b7ef6541a
5 changed files with 93 additions and 59 deletions

View File

@ -21,6 +21,8 @@ import {
safelyParseFormattedHtml, safelyParseFormattedHtml,
} from '@/utility/html'; } from '@/utility/html';
import { clsx } from 'clsx/lite'; import { clsx } from 'clsx/lite';
import { convertTagToRecipe, isTagRecipe } from '@/recipe';
import PhotoRecipe from '@/recipe/PhotoRecipe';
export default function PhotoGridSidebar({ export default function PhotoGridSidebar({
tags, tags,
@ -51,35 +53,47 @@ export default function PhotoGridSidebar({
className="text-icon translate-y-[1px]" className="text-icon translate-y-[1px]"
/>} />}
items={tagsIncludingHidden.map(({ tag, count }) => { items={tagsIncludingHidden.map(({ tag, count }) => {
switch (tag) { if (isTagRecipe(tag)) {
case TAG_FAVS: return <PhotoRecipe
return <FavsTag
key={TAG_FAVS}
countOnHover={count}
type="icon-last"
prefetch={false}
contrast="low"
badged
/>;
case TAG_HIDDEN:
return <HiddenTag
key={TAG_HIDDEN}
countOnHover={count}
type="icon-last"
prefetch={false}
contrast="low"
badged
/>;
default:
return <PhotoTag
key={tag} key={tag}
tag={tag} recipe={convertTagToRecipe(tag)}
type="text-only"
countOnHover={count} countOnHover={count}
type="icon-last"
prefetch={false} prefetch={false}
contrast="low" contrast="low"
badged badged
/>; />;
} else {
switch (tag) {
case TAG_FAVS:
return <FavsTag
key={TAG_FAVS}
countOnHover={count}
type="icon-last"
prefetch={false}
contrast="low"
badged
/>;
case TAG_HIDDEN:
return <HiddenTag
key={TAG_HIDDEN}
countOnHover={count}
type="icon-last"
prefetch={false}
contrast="low"
badged
/>;
default:
return <PhotoTag
key={tag}
tag={tag}
type="text-only"
countOnHover={count}
prefetch={false}
contrast="low"
badged
/>;
}
} }
})} })}
/> />

View File

@ -1,4 +1,4 @@
import { pathForTag } from '@/app/paths'; import { pathForRecipe } from '@/app/paths';
import EntityLink, { import EntityLink, {
EntityLinkExternalProps, EntityLinkExternalProps,
} from '@/components/primitives/EntityLink'; } from '@/components/primitives/EntityLink';
@ -25,8 +25,13 @@ export default function PhotoRecipe({
<EntityLink <EntityLink
title="Recipe" title="Recipe"
label={formatRecipe(recipe)} label={formatRecipe(recipe)}
href={pathForTag(recipe)} href={pathForRecipe(recipe)}
icon={<TbChecklist size={16} />} icon={<TbChecklist
size={16}
className={clsx(
badged && 'translate-x-[-1px] translate-y-[0.5px]',
)}
/>}
className={className} className={className}
type={type} type={type}
badged={badged} badged={badged}
@ -34,15 +39,17 @@ export default function PhotoRecipe({
prefetch={prefetch} prefetch={prefetch}
hoverEntity={countOnHover} hoverEntity={countOnHover}
/> />
<button {recipeOnClick &&
onClick={recipeOnClick} <button
className={clsx( onClick={recipeOnClick}
'px-1! py-0!', className={clsx(
'text-[11px] text-medium tracking-wider', 'self-start',
)} 'px-1 py-0.5 mt-[1px]',
> 'text-[10px] text-medium tracking-wider',
OPEN )}
</button> >
RECIPE
</button>}
</div> </div>
); );
} }

View File

@ -2,7 +2,7 @@
import Modal from '@/components/Modal'; import Modal from '@/components/Modal';
import { useAppState } from '@/state/AppState'; import { useAppState } from '@/state/AppState';
import PhotoRecipeOGTile from './PhotoRecipeOGTile'; import PhotoRecipeGrid from './PhotoRecipeGrid';
export default function ShareModals() { export default function ShareModals() {
const { const {
@ -15,7 +15,10 @@ export default function ShareModals() {
onClose={() => setRecipeModalProps?.(undefined)} onClose={() => setRecipeModalProps?.(undefined)}
container={false} container={false}
> >
<PhotoRecipeOGTile {...recipeModalProps}/> <PhotoRecipeGrid {...{
...recipeModalProps,
onClose: () => setRecipeModalProps?.(undefined),
}}/>
</Modal>; </Modal>;
} }
} }

View File

@ -1,13 +1,8 @@
import { absolutePathForRecipe, absolutePathForRecipeImage } from '@/app/paths'; import { absolutePathForRecipe, absolutePathForRecipeImage } from '@/app/paths';
import { Photo, photoQuantityText } from '@/photo'; import { descriptionForPhotoSet, Photo, photoQuantityText } from '@/photo';
import { PhotoDateRange } from '@/photo'; import { PhotoDateRange } from '@/photo';
import { import { Tags } from '../tag';
descriptionForTaggedPhotos, import { parameterize } from '@/utility/string';
isTagFavs,
isTagHidden,
Tags,
} from '../tag';
import { convertStringToArray, parameterize } from '@/utility/string';
import { capitalizeWords } from '@/utility/string'; import { capitalizeWords } from '@/utility/string';
import { FujifilmRecipe } from '@/platforms/fujifilm/recipe'; import { FujifilmRecipe } from '@/platforms/fujifilm/recipe';
import { FilmSimulation } from '@/simulation'; import { FilmSimulation } from '@/simulation';
@ -21,8 +16,11 @@ export interface RecipeProps {
exposure?: string exposure?: string
} }
export const isTagRecipe = (tag: string) =>
(new RegExp(`^${KEY_RECIPE}-?`).test(tag));
export const convertTagsToRecipes = (tags: Tags) => export const convertTagsToRecipes = (tags: Tags) =>
tags.filter(({ tag }) => tag.startsWith(KEY_RECIPE)) tags.filter(({ tag }) => isTagRecipe(tag))
.map(({ tag }) => convertTagToRecipe(tag)); .map(({ tag }) => convertTagToRecipe(tag));
export const convertRecipeToTag = (recipe: string) => export const convertRecipeToTag = (recipe: string) =>
@ -34,15 +32,6 @@ export const convertTagToRecipe = (tag: string) =>
export const formatRecipe = (recipe?: string) => export const formatRecipe = (recipe?: string) =>
capitalizeWords(recipe?.replaceAll('-', ' ')); capitalizeWords(recipe?.replaceAll('-', ' '));
export const getValidationMessageForTags = (tags?: string) => {
const reservedTags = (convertStringToArray(tags) ?? [])
.filter(tag => isTagFavs(tag) || isTagHidden(tag))
.map(tag => tag.toLocaleUpperCase());
return reservedTags.length
? `Reserved tags: ${reservedTags.join(', ').toLocaleLowerCase()}`
: undefined;
};
export const titleForRecipe = ( export const titleForRecipe = (
recipe: string, recipe: string,
photos:Photo[] = [], photos:Photo[] = [],
@ -52,6 +41,20 @@ export const titleForRecipe = (
photoQuantityText(explicitCount ?? photos.length), photoQuantityText(explicitCount ?? photos.length),
].join(' '); ].join(' ');
export const descriptionForRecipePhotos = (
photos: Photo[] = [],
dateBased?: boolean,
explicitCount?: number,
explicitDateRange?: PhotoDateRange,
) =>
descriptionForPhotoSet(
photos,
undefined,
dateBased,
explicitCount,
explicitDateRange,
);
export const generateMetaForRecipe = ( export const generateMetaForRecipe = (
recipe: string, recipe: string,
photos: Photo[], photos: Photo[],
@ -61,6 +64,6 @@ export const generateMetaForRecipe = (
url: absolutePathForRecipe(recipe), url: absolutePathForRecipe(recipe),
title: titleForRecipe(recipe, photos, explicitCount), title: titleForRecipe(recipe, photos, explicitCount),
description: description:
descriptionForTaggedPhotos(photos, true, explicitCount, explicitDateRange), descriptionForRecipePhotos(photos, true, explicitCount, explicitDateRange),
images: absolutePathForRecipeImage(recipe), images: absolutePathForRecipeImage(recipe),
}); });

View File

@ -3,6 +3,8 @@ import { isTagFavs } from '.';
import FavsTag from './FavsTag'; import FavsTag from './FavsTag';
import { EntityLinkExternalProps } from '@/components/primitives/EntityLink'; import { EntityLinkExternalProps } from '@/components/primitives/EntityLink';
import { Fragment } from 'react'; import { Fragment } from 'react';
import { convertTagToRecipe, isTagRecipe } from '@/recipe';
import PhotoRecipe from '@/recipe/PhotoRecipe';
export default function PhotoTags({ export default function PhotoTags({
tags, tags,
@ -15,9 +17,14 @@ export default function PhotoTags({
<div className="flex flex-col"> <div className="flex flex-col">
{tags.map(tag => {tags.map(tag =>
<Fragment key={tag}> <Fragment key={tag}>
{isTagFavs(tag) {isTagRecipe(tag)
? <FavsTag {...{ contrast, prefetch }} /> ? <PhotoRecipe {...{
: <PhotoTag {...{ tag, contrast, prefetch }} />} recipe: convertTagToRecipe(tag),
recipeOnClick: () => console.log('clicked'),
}} />
: isTagFavs(tag)
? <FavsTag {...{ contrast, prefetch }} />
: <PhotoTag {...{ tag, contrast, prefetch }} />}
</Fragment>)} </Fragment>)}
</div> </div>
); );