diff --git a/src/admin/AdminCTA.tsx b/src/admin/AdminCTA.tsx
index 79a448f8..92fae7b4 100644
--- a/src/admin/AdminCTA.tsx
+++ b/src/admin/AdminCTA.tsx
@@ -4,15 +4,22 @@ import PhotoUpload from '@/photo/PhotoUpload';
import { PATH_ADMIN_PHOTOS } from '@/site/paths';
import { useAppState } from '@/state/AppState';
import Link from 'next/link';
+import { useState } from 'react';
import { FaArrowRight } from 'react-icons/fa';
export default function AdminCTA() {
const { isUserSignedIn } = useAppState();
+ const [isUploading, setIsUploading] = useState(false);
+
return (
{isUserSignedIn
- ?
+ ?
:
Promise
+ blobPhotoUrls: StorageListResponse
+ infiniteScrollInitial: number
+ infiniteScrollMultiple: number
+}) {
+ const [isUploading, setIsUploading] = useState(false);
+
+ return (
+
+
+
+ {photosCountOutdated > 0 &&
}
+ title={`${photosCountOutdated} Outdated Photos`}
+ className={clsx(
+ isUploading && 'hidden md:inline-flex',
+ )}
+ hideTextOnMobile={false}
+ >
+ {photosCountOutdated}
+ }
+
+ {!isUploading && blobPhotoUrls.length > 0 &&
+ }
+
+
+ {photosCount > photos.length &&
+
}
+
+ }
+ />
+ );
+}
diff --git a/src/admin/AdminPhotosTable.tsx b/src/admin/AdminPhotosTable.tsx
index 36a969a5..4f5228d5 100644
--- a/src/admin/AdminPhotosTable.tsx
+++ b/src/admin/AdminPhotosTable.tsx
@@ -25,11 +25,15 @@ export default function AdminPhotosTable({
onLastPhotoVisible,
revalidatePhoto,
hasAiTextGeneration,
+ canEdit = true,
+ canDelete = true,
}: {
photos: Photo[],
onLastPhotoVisible?: () => void
revalidatePhoto?: RevalidatePhoto
hasAiTextGeneration?: boolean
+ canEdit?: boolean
+ canDelete?: boolean
}) {
const { invalidateSwr } = useAppState();
@@ -82,7 +86,8 @@ export default function AdminPhotosTable({
'flex flex-nowrap',
'gap-2 sm:gap-3 items-center',
)}>
-
+ {canEdit &&
+ }
- revalidatePhoto?.(photo.id, true)}
- >
-
-
-
-
+ {canDelete &&
+ revalidatePhoto?.(photo.id, true)}
+ >
+
+
+
+ }
)}
diff --git a/src/admin/AdminPhotosTableInfinite.tsx b/src/admin/AdminPhotosTableInfinite.tsx
index 33b8b793..285d8091 100644
--- a/src/admin/AdminPhotosTableInfinite.tsx
+++ b/src/admin/AdminPhotosTableInfinite.tsx
@@ -3,16 +3,18 @@
import { PATH_ADMIN_PHOTOS } from '@/site/paths';
import InfinitePhotoScroll from '../photo/InfinitePhotoScroll';
import AdminPhotosTable from './AdminPhotosTable';
+import { ComponentProps } from 'react';
export default function AdminPhotosTableInfinite({
initialOffset,
itemsPerPage,
hasAiTextGeneration,
+ canEdit,
+ canDelete,
}: {
initialOffset: number
itemsPerPage: number
- hasAiTextGeneration?: boolean
-}) {
+} & Omit, 'photos'>) {
return (
}
);
diff --git a/src/app/admin/outdated/page.tsx b/src/app/admin/outdated/page.tsx
index 526dfbf1..32322067 100644
--- a/src/app/admin/outdated/page.tsx
+++ b/src/app/admin/outdated/page.tsx
@@ -54,6 +54,8 @@ export default async function AdminPhotosPage() {
diff --git a/src/app/admin/photos/page.tsx b/src/app/admin/photos/page.tsx
index b62a20f4..8f8d4279 100644
--- a/src/app/admin/photos/page.tsx
+++ b/src/app/admin/photos/page.tsx
@@ -1,19 +1,9 @@
-import PhotoUpload from '@/photo/PhotoUpload';
-import { clsx } from 'clsx/lite';
-import SiteGrid from '@/components/SiteGrid';
-import AdminUploadsTable from '@/admin/AdminUploadsTable';
-import { AI_TEXT_GENERATION_ENABLED, PRO_MODE_ENABLED } from '@/site/config';
import { getStoragePhotoUrlsNoStore } from '@/services/storage/cache';
import { getPhotos } from '@/photo/db/query';
-import { revalidatePath } from 'next/cache';
-import AdminPhotosTable from '@/admin/AdminPhotosTable';
-import AdminPhotosTableInfinite from
- '@/admin/AdminPhotosTableInfinite';
import { getPhotosMetaCached } from '@/photo/cache';
-import { IoInformationCircleOutline } from 'react-icons/io5';
-import PathLoaderButton from '@/components/primitives/PathLoaderButton';
-import { PATH_ADMIN_OUTDATED } from '@/site/paths';
import { OUTDATED_THRESHOLD } from '@/photo';
+import AdminPhotosClient from '@/admin/AdminPhotosClient';
+import { revalidatePath } from 'next/cache';
const DEBUG_PHOTO_BLOBS = false;
@@ -47,54 +37,18 @@ export default async function AdminPhotosPage() {
]);
return (
-
-
-
-
{
- 'use server';
- // Update upload count in admin nav
- revalidatePath('/admin', 'layout');
- }}
- />
-
- {photosCountOutdated > 0 &&
}
- title={`${photosCountOutdated} Outdated Photos`}
- hideTextOnMobile={false}
- >
- {photosCountOutdated}
- }
-
- {blobPhotoUrls.length > 0 &&
- }
-
-
- {photosCount > photos.length &&
-
}
-
- }
- />
+ {
+ 'use server';
+ // Update upload count in admin nav
+ revalidatePath('/admin', 'layout');
+ },
+ blobPhotoUrls,
+ infiniteScrollInitial: INFINITE_SCROLL_INITIAL_ADMIN_PHOTOS,
+ infiniteScrollMultiple: INFINITE_SCROLL_MULTIPLE_ADMIN_PHOTOS,
+ }} />
);
}
diff --git a/src/photo/PhotoUpload.tsx b/src/photo/PhotoUpload.tsx
index 62df397b..836d5d13 100644
--- a/src/photo/PhotoUpload.tsx
+++ b/src/photo/PhotoUpload.tsx
@@ -10,15 +10,18 @@ import { clsx } from 'clsx/lite';
export default function PhotoUpload({
shouldResize,
onLastUpload,
+ isUploading,
+ setIsUploading,
showUploadStatus,
debug,
}: {
shouldResize?: boolean
onLastUpload?: () => Promise
+ isUploading: boolean
+ setIsUploading: (isUploading: boolean) => void
showUploadStatus?: boolean
debug?: boolean
}) {
- const [isUploading, setIsUploading] = useState(false);
const [uploadError, setUploadError] = useState();
const [debugDownload, setDebugDownload] = useState<{
href: string