Add server action to rename tag globally

This commit is contained in:
Sam Becker 2023-10-06 08:54:23 -05:00
parent bdad8507c5
commit d2d5a8875c
5 changed files with 31 additions and 6 deletions

View File

@ -6,6 +6,8 @@ import { Fragment } from 'react';
import DeleteButton from '@/admin/DeleteButton';
import { photoQuantityText } from '@/photo';
import { getUniqueTagsWithCountCached } from '@/cache';
import PhotoTag from '@/tag/PhotoTag';
import { formatTag } from '@/tag';
export const runtime = 'edge';
@ -21,9 +23,9 @@ export default async function AdminPhotosPage() {
{tags.map(({ tag, count }) =>
<Fragment key={tag}>
<div className="pr-2">
{tag}
<PhotoTag {...{ tag }} />
</div>
<div className="text-dim">
<div className="text-dim uppercase">
{photoQuantityText(count, false)}
</div>
<div />
@ -31,7 +33,7 @@ export default async function AdminPhotosPage() {
action={deletePhotoTagGloballyAction}
confirmText={
// eslint-disable-next-line max-len
`Are you sure you want to remove "${tag}?" from ${photoQuantityText(count, false).toLowerCase()}?`}
`Are you sure you want to remove "${formatTag(tag)}?" from ${photoQuantityText(count, false).toLowerCase()}?`}
>
<input type="hidden" name="tag" value={tag} />
<DeleteButton />

View File

@ -5,6 +5,7 @@ import {
sqlInsertPhoto,
sqlDeletePhotoTagGlobally,
sqlUpdatePhoto,
sqlRenamePhotoTagGlobally,
} from '@/services/postgres';
import { convertFormDataToPhoto } from './form';
import { redirect } from 'next/navigation';
@ -71,6 +72,17 @@ export async function deletePhotoTagGloballyAction(formData: FormData) {
revalidatePhotosKey();
}
export async function renamePhotoTagGloballyAction(formData: FormData) {
const tag = formData.get('tag') as string;
const newTag = formData.get('newTag') as string;
if (tag && newTag && tag !== newTag) {
await sqlRenamePhotoTagGlobally(tag, newTag);
revalidatePhotosKey();
}
}
export async function deleteBlobPhotoAction(formData: FormData) {
await deleteBlobPhoto(formData.get('url') as string);

View File

@ -135,7 +135,14 @@ export const sqlUpdatePhoto = (photo: PhotoDbInsert) =>
export const sqlDeletePhotoTagGlobally = (tag: string) =>
sql`
UPDATE photos
SET tags=array_remove(tags, ${tag})
SET tags=ARRAY_REMOVE(tags, ${tag})
WHERE ${tag}=ANY(tags)
`;
export const sqlRenamePhotoTagGlobally = (tag: string, newTag: string) =>
sql`
UPDATE photos
SET tags=ARRAY_REPLACE(tags, ${tag}, ${newTag})
WHERE ${tag}=ANY(tags)
`;

View File

@ -2,6 +2,7 @@ import Link from 'next/link';
import { pathForTag } from '@/site/paths';
import { FaTag } from 'react-icons/fa';
import { cc } from '@/utility/css';
import { formatTag } from '.';
export default function PhotoTag({
tag,
@ -27,7 +28,7 @@ export default function PhotoTag({
)}
/>}
<span className="uppercase">
{tag.replaceAll('-', ' ')}
{formatTag(tag)}
</span>
</Link>
);

View File

@ -7,12 +7,15 @@ import {
import { absolutePathForTag, absolutePathForTagImage } from '@/site/paths';
import { capitalizeWords } from '@/utility/string';
export const formatTag = (tag: string) =>
capitalizeWords(tag.replaceAll('-', ' '));
export const titleForTag = (
tag: string,
photos:Photo[],
explicitCount?: number,
) => [
capitalizeWords(tag.replaceAll('-', ' ')),
formatTag(tag),
photoQuantityText(explicitCount ?? photos.length),
].join(' ');