Add recipes to core admin surfaces
This commit is contained in:
parent
de5f49261b
commit
3d57de3997
48
app/admin/recipes/[recipe]/edit/page.tsx
Normal file
48
app/admin/recipes/[recipe]/edit/page.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
import AdminChildPage from '@/components/AdminChildPage';
|
||||
import { redirect } from 'next/navigation';
|
||||
import { getPhotosCached } from '@/photo/cache';
|
||||
import TagForm from '@/tag/TagForm';
|
||||
import { PATH_ADMIN, PATH_ADMIN_TAGS, pathForTag } from '@/app/paths';
|
||||
import PhotoLightbox from '@/photo/PhotoLightbox';
|
||||
import { getPhotosMeta } from '@/photo/db/query';
|
||||
import AdminTagBadge from '@/admin/AdminTagBadge';
|
||||
|
||||
const MAX_PHOTO_TO_SHOW = 6;
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ tag: string }>
|
||||
}
|
||||
|
||||
export default async function PhotoPageEdit({
|
||||
params,
|
||||
}: Props) {
|
||||
const { tag: tagFromParams } = await params;
|
||||
|
||||
const tag = decodeURIComponent(tagFromParams);
|
||||
|
||||
const [
|
||||
{ count },
|
||||
photos,
|
||||
] = await Promise.all([
|
||||
getPhotosMeta({ tag }),
|
||||
getPhotosCached({ tag, limit: MAX_PHOTO_TO_SHOW }),
|
||||
]);
|
||||
|
||||
if (count === 0) { redirect(PATH_ADMIN); }
|
||||
|
||||
return (
|
||||
<AdminChildPage
|
||||
backPath={PATH_ADMIN_TAGS}
|
||||
backLabel="Tags"
|
||||
breadcrumb={<AdminTagBadge {...{ tag, count, hideBadge: true }} />}
|
||||
>
|
||||
<TagForm {...{ tag, photos }}>
|
||||
<PhotoLightbox
|
||||
{...{ count, photos, tag }}
|
||||
maxPhotosToShow={MAX_PHOTO_TO_SHOW}
|
||||
moreLink={pathForTag(tag)}
|
||||
/>
|
||||
</TagForm>
|
||||
</AdminChildPage>
|
||||
);
|
||||
};
|
||||
18
app/admin/recipes/page.tsx
Normal file
18
app/admin/recipes/page.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import AdminTagTable from '@/admin/AdminTagTable';
|
||||
import SiteGrid from '@/components/SiteGrid';
|
||||
import { getUniqueTagsHiddenCached } from '@/photo/cache';
|
||||
|
||||
export default async function AdminTagsPage() {
|
||||
const tags = await getUniqueTagsHiddenCached().catch(() => []);
|
||||
|
||||
return (
|
||||
<SiteGrid
|
||||
contentMain={
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-4">
|
||||
<AdminTagTable {...{ tags }} />
|
||||
</div>
|
||||
</div>}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -5,6 +5,7 @@ import {
|
||||
PATH_ADMIN_CONFIGURATION,
|
||||
PATH_ADMIN_INSIGHTS,
|
||||
PATH_ADMIN_PHOTOS,
|
||||
PATH_ADMIN_RECIPES,
|
||||
PATH_ADMIN_TAGS,
|
||||
PATH_ADMIN_UPLOADS,
|
||||
PATH_GRID_INFERRED,
|
||||
@ -13,7 +14,7 @@ import { useAppState } from '@/state/AppState';
|
||||
import { ImCheckboxUnchecked } from 'react-icons/im';
|
||||
import { IoArrowDown, IoArrowUp, IoCloseSharp } from 'react-icons/io5';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import { TbPhoto } from 'react-icons/tb';
|
||||
import { TbChecklist, TbPhoto } from 'react-icons/tb';
|
||||
import { FiTag } from 'react-icons/fi';
|
||||
import { BiLockAlt } from 'react-icons/bi';
|
||||
import AdminAppInfoIcon from './AdminAppInfoIcon';
|
||||
@ -37,6 +38,7 @@ export default function AdminAppMenu({
|
||||
photosCountTotal = 0,
|
||||
uploadsCount = 0,
|
||||
tagsCount = 0,
|
||||
recipesCount = 0,
|
||||
selectedPhotoIds,
|
||||
startUpload,
|
||||
setSelectedPhotoIds,
|
||||
@ -103,6 +105,18 @@ export default function AdminAppMenu({
|
||||
});
|
||||
}
|
||||
|
||||
if (recipesCount) {
|
||||
items.push({
|
||||
label: 'Manage Recipes',
|
||||
annotation: `${recipesCount}`,
|
||||
icon: <TbChecklist
|
||||
size={17}
|
||||
className="translate-x-[-0.5px] translate-y-[0.5px]"
|
||||
/>,
|
||||
href: PATH_ADMIN_RECIPES,
|
||||
});
|
||||
}
|
||||
|
||||
if (photosCountTotal) {
|
||||
items.push({
|
||||
label: isSelecting
|
||||
|
||||
@ -2,10 +2,12 @@ import { getStorageUploadUrlsNoStore } from '@/platforms/storage/cache';
|
||||
import {
|
||||
getPhotosMetaCached,
|
||||
getPhotosMostRecentUpdateCached,
|
||||
getUniqueRecipesCached,
|
||||
getUniqueTagsCached,
|
||||
} from '@/photo/cache';
|
||||
import {
|
||||
PATH_ADMIN_PHOTOS,
|
||||
PATH_ADMIN_RECIPES,
|
||||
PATH_ADMIN_TAGS,
|
||||
PATH_ADMIN_UPLOADS,
|
||||
} from '@/app/paths';
|
||||
@ -14,21 +16,24 @@ import AdminNavClient from './AdminNavClient';
|
||||
export default async function AdminNav() {
|
||||
const [
|
||||
countPhotos,
|
||||
countTags,
|
||||
countUploads,
|
||||
countTags,
|
||||
countRecipes,
|
||||
mostRecentPhotoUpdateTime,
|
||||
] = await Promise.all([
|
||||
getPhotosMetaCached({ hidden: 'include' })
|
||||
.then(({ count }) => count)
|
||||
.catch(() => 0),
|
||||
getUniqueTagsCached().then(tags => tags.length)
|
||||
.catch(() => 0),
|
||||
getStorageUploadUrlsNoStore()
|
||||
.then(urls => urls.length)
|
||||
.catch(e => {
|
||||
console.error(`Error getting blob upload urls: ${e}`);
|
||||
return 0;
|
||||
}),
|
||||
getUniqueTagsCached().then(tags => tags.length)
|
||||
.catch(() => 0),
|
||||
getUniqueRecipesCached().then(recipes => recipes.length)
|
||||
.catch(() => 0),
|
||||
getPhotosMostRecentUpdateCached().catch(() => undefined),
|
||||
]);
|
||||
|
||||
@ -55,6 +60,13 @@ export default async function AdminNav() {
|
||||
count: countTags,
|
||||
}); }
|
||||
|
||||
// Recipes
|
||||
if (countRecipes > 0) { items.push({
|
||||
label: 'Recipes',
|
||||
href: PATH_ADMIN_RECIPES,
|
||||
count: countRecipes,
|
||||
}); }
|
||||
|
||||
return (
|
||||
<AdminNavClient {...{
|
||||
items,
|
||||
|
||||
@ -8,7 +8,11 @@ import { testStorageConnection } from '@/platforms/storage';
|
||||
import { APP_CONFIGURATION } from '@/app/config';
|
||||
import { getStorageUploadUrlsNoStore } from '@/platforms/storage/cache';
|
||||
import { getInsightsIndicatorStatus } from '@/admin/insights/server';
|
||||
import { getPhotosMeta, getUniqueTags } from '@/photo/db/query';
|
||||
import {
|
||||
getPhotosMeta,
|
||||
getUniqueTags,
|
||||
getUniqueRecipes,
|
||||
} from '@/photo/db/query';
|
||||
|
||||
export type AdminData = Awaited<ReturnType<typeof getAdminDataAction>>;
|
||||
|
||||
@ -17,8 +21,9 @@ export const getAdminDataAction = async () =>
|
||||
const [
|
||||
photosCount,
|
||||
photosCountHidden,
|
||||
tagsCount,
|
||||
uploadsCount,
|
||||
tagsCount,
|
||||
recipesCount,
|
||||
insightsIndicatorStatus,
|
||||
] = await Promise.all([
|
||||
getPhotosMeta()
|
||||
@ -27,15 +32,18 @@ export const getAdminDataAction = async () =>
|
||||
getPhotosMeta({ hidden: 'only' })
|
||||
.then(({ count }) => count)
|
||||
.catch(() => 0),
|
||||
getUniqueTags()
|
||||
.then(tags => tags.length)
|
||||
.catch(() => 0),
|
||||
getStorageUploadUrlsNoStore()
|
||||
.then(urls => urls.length)
|
||||
.catch(e => {
|
||||
console.error(`Error getting blob upload urls: ${e}`);
|
||||
return 0;
|
||||
}),
|
||||
getUniqueTags()
|
||||
.then(tags => tags.length)
|
||||
.catch(() => 0),
|
||||
getUniqueRecipes()
|
||||
.then(recipes => recipes.length)
|
||||
.catch(() => 0),
|
||||
getInsightsIndicatorStatus(),
|
||||
]);
|
||||
|
||||
@ -50,8 +58,9 @@ export const getAdminDataAction = async () =>
|
||||
photosCount,
|
||||
photosCountHidden,
|
||||
photosCountTotal,
|
||||
tagsCount,
|
||||
uploadsCount,
|
||||
tagsCount,
|
||||
recipesCount,
|
||||
insightsIndicatorStatus,
|
||||
};
|
||||
});
|
||||
|
||||
@ -41,6 +41,7 @@ export const PATH_ADMIN_PHOTOS = `${PATH_ADMIN}/photos`;
|
||||
export const PATH_ADMIN_OUTDATED = `${PATH_ADMIN}/outdated`;
|
||||
export const PATH_ADMIN_UPLOADS = `${PATH_ADMIN}/uploads`;
|
||||
export const PATH_ADMIN_TAGS = `${PATH_ADMIN}/tags`;
|
||||
export const PATH_ADMIN_RECIPES = `${PATH_ADMIN}/recipes`;
|
||||
export const PATH_ADMIN_CONFIGURATION = `${PATH_ADMIN}/configuration`;
|
||||
export const PATH_ADMIN_INSIGHTS = `${PATH_ADMIN}/insights`;
|
||||
export const PATH_ADMIN_BASELINE = `${PATH_ADMIN}/baseline`;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user