Add recipe query param, sync menu item
This commit is contained in:
parent
1b92b42b78
commit
4ff7473a00
@ -2,7 +2,11 @@
|
||||
|
||||
import { ComponentProps, useMemo } from 'react';
|
||||
import { pathForAdminPhotoEdit, pathForPhoto } from '@/app/paths';
|
||||
import { deletePhotoAction, toggleFavoritePhotoAction } from '@/photo/actions';
|
||||
import {
|
||||
deletePhotoAction,
|
||||
syncPhotoAction,
|
||||
toggleFavoritePhotoAction,
|
||||
} from '@/photo/actions';
|
||||
import { FaRegEdit, FaRegStar, FaStar } from 'react-icons/fa';
|
||||
import {
|
||||
Photo,
|
||||
@ -17,6 +21,7 @@ import { useAppState } from '@/state/AppState';
|
||||
import { RevalidatePhoto } from '@/photo/InfinitePhotoScroll';
|
||||
import { MdOutlineFileDownload } from 'react-icons/md';
|
||||
import MoreMenuItem from '@/components/more/MoreMenuItem';
|
||||
import IconGrSync from '@/app/IconGrSync';
|
||||
|
||||
export default function AdminPhotoMenuClient({
|
||||
photo,
|
||||
@ -65,17 +70,24 @@ export default function AdminPhotoMenuClient({
|
||||
label: 'Download',
|
||||
icon: <MdOutlineFileDownload
|
||||
size={17}
|
||||
className="translate-x-[-1.5px] translate-y-[-0.5px]"
|
||||
className="translate-x-[-1px] translate-y-[-0.5px]"
|
||||
/>,
|
||||
href: photo.url,
|
||||
hrefDownloadName: downloadFileNameForPhoto(photo),
|
||||
});
|
||||
items.push({
|
||||
label: 'Sync',
|
||||
icon: <IconGrSync className="translate-x-[-1px]" />,
|
||||
action: () => syncPhotoAction(photo.id)
|
||||
.then(() => revalidatePhoto?.(photo.id)),
|
||||
});
|
||||
items.push({
|
||||
label: 'Delete',
|
||||
icon: <BiTrash
|
||||
size={15}
|
||||
className="translate-x-[-1.5px]"
|
||||
className="translate-x-[-1px]"
|
||||
/>,
|
||||
className: 'text-error',
|
||||
action: () => {
|
||||
if (confirm(deleteConfirmationTextForPhoto(photo))) {
|
||||
return deletePhotoAction(
|
||||
|
||||
@ -33,6 +33,10 @@ const PATH_CAMERA_DYNAMIC = `${PREFIX_CAMERA}/[make]/[model]`;
|
||||
const PATH_FILM_SIMULATION_DYNAMIC = `${PREFIX_FILM_SIMULATION}/[simulation]`;
|
||||
const PATH_FOCAL_LENGTH_DYNAMIC = `${PREFIX_FOCAL_LENGTH}/[focal]`;
|
||||
|
||||
// Search params
|
||||
export const SEARCH_PARAM_SHOW = 'show';
|
||||
export const SEARCH_PARAM_SHOW_RECIPE = 'recipe';
|
||||
|
||||
// Admin paths
|
||||
export const PATH_ADMIN_PHOTOS = `${PATH_ADMIN}/photos`;
|
||||
export const PATH_ADMIN_OUTDATED = `${PATH_ADMIN}/outdated`;
|
||||
@ -78,7 +82,9 @@ export const PATHS_TO_CACHE = [
|
||||
...PATHS_ADMIN,
|
||||
];
|
||||
|
||||
type PhotoPathParams = { photo: PhotoOrPhotoId } & PhotoSetCategory;
|
||||
type PhotoPathParams = { photo: PhotoOrPhotoId } & PhotoSetCategory & {
|
||||
showRecipe?: boolean
|
||||
};
|
||||
|
||||
// Absolute paths
|
||||
export const ABSOLUTE_PATH_FOR_HOME_IMAGE = `${BASE_URL}/home-image`;
|
||||
@ -103,6 +109,7 @@ export const pathForPhoto = ({
|
||||
camera,
|
||||
simulation,
|
||||
focal,
|
||||
showRecipe,
|
||||
}: PhotoPathParams) =>
|
||||
typeof photo !== 'string' && photo.hidden
|
||||
? `${pathForTag(TAG_HIDDEN)}/${getPhotoId(photo)}`
|
||||
@ -114,7 +121,9 @@ export const pathForPhoto = ({
|
||||
? `${pathForFilmSimulation(simulation)}/${getPhotoId(photo)}`
|
||||
: focal
|
||||
? `${pathForFocalLength(focal)}/${getPhotoId(photo)}`
|
||||
: `${PREFIX_PHOTO}/${getPhotoId(photo)}`;
|
||||
: `${PREFIX_PHOTO}/${getPhotoId(photo)}` + (showRecipe
|
||||
? `?${SEARCH_PARAM_SHOW}=${SEARCH_PARAM_SHOW_RECIPE}`
|
||||
: '');
|
||||
|
||||
export const pathForTag = (tag: string) =>
|
||||
`${PREFIX_TAG}/${tag}`;
|
||||
|
||||
@ -12,6 +12,7 @@ export default function MoreMenuItem({
|
||||
icon,
|
||||
href,
|
||||
hrefDownloadName,
|
||||
className,
|
||||
action,
|
||||
shouldPreventDefault = true,
|
||||
}: {
|
||||
@ -19,6 +20,7 @@ export default function MoreMenuItem({
|
||||
icon?: ReactNode
|
||||
href?: string
|
||||
hrefDownloadName?: string
|
||||
className?: string
|
||||
action?: () => Promise<void> | void
|
||||
shouldPreventDefault?: boolean
|
||||
}) {
|
||||
@ -43,6 +45,7 @@ export default function MoreMenuItem({
|
||||
isLoading
|
||||
? 'cursor-not-allowed opacity-50'
|
||||
: 'cursor-pointer',
|
||||
className,
|
||||
)}
|
||||
onClick={async e => {
|
||||
if (shouldPreventDefault) { e.preventDefault(); }
|
||||
|
||||
@ -15,6 +15,8 @@ import Link from 'next/link';
|
||||
import {
|
||||
pathForFocalLength,
|
||||
pathForPhoto,
|
||||
SEARCH_PARAM_SHOW,
|
||||
SEARCH_PARAM_SHOW_RECIPE,
|
||||
} from '@/app/paths';
|
||||
import PhotoTags from '@/tag/PhotoTags';
|
||||
import ShareButton from '@/share/ShareButton';
|
||||
@ -43,6 +45,7 @@ import ZoomControls, { ZoomControlsRef } from '@/components/image/ZoomControls';
|
||||
import PhotoRecipe from './PhotoRecipe';
|
||||
import { TbChecklist } from 'react-icons/tb';
|
||||
import { IoCloseSharp } from 'react-icons/io5';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
|
||||
export default function PhotoLarge({
|
||||
photo,
|
||||
@ -91,7 +94,10 @@ export default function PhotoLarge({
|
||||
|
||||
const zoomControlsRef = useRef<ZoomControlsRef>(null);
|
||||
|
||||
const [shouldShowRecipe, setShouldShowRecipe] = useState(false);
|
||||
const params = useSearchParams();
|
||||
const showRecipeInitially =
|
||||
params.get(SEARCH_PARAM_SHOW) === SEARCH_PARAM_SHOW_RECIPE;
|
||||
const [shouldShowRecipe, setShouldShowRecipe] = useState(showRecipeInitially);
|
||||
const recipeButtonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const {
|
||||
@ -333,9 +339,8 @@ export default function PhotoLarge({
|
||||
// Prevent collision with admin button
|
||||
!hasNonDateContent && isUserSignedIn && 'md:pr-7',
|
||||
)}
|
||||
// 'createdAt' is a naive datetime which
|
||||
// does not require a timezone and will not
|
||||
// cause server/client time mismatches
|
||||
// 'createdAt' is a naive datetime which does not require
|
||||
// a timezone and will not cause server/client mismatch
|
||||
timezone={null}
|
||||
hideTime={!SHOW_TAKEN_AT_TIME}
|
||||
/>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user