157 lines
4.7 KiB
TypeScript
157 lines
4.7 KiB
TypeScript
"use server"
|
|
|
|
import { revalidatePath } from "next/cache"
|
|
import { redirect } from "next/navigation"
|
|
|
|
import { auth } from "@/auth"
|
|
import { isAdminEmail } from "@/lib/admin-auth"
|
|
import { deleteInvitationGroup } from "@/lib/db/queries/invitations"
|
|
import {
|
|
deleteInvitationMember,
|
|
updateInvitationMemberName,
|
|
} from "@/lib/db/queries/members"
|
|
import { deleteUploadObject } from "@/lib/storage/uploads"
|
|
import { deleteInvitationSchema } from "@/lib/validation/invitation"
|
|
import {
|
|
deleteInvitationMemberSchema,
|
|
updateInvitationMemberSchema,
|
|
} from "@/lib/validation/member"
|
|
|
|
export interface DeleteInvitationActionState {
|
|
error: string | null
|
|
}
|
|
|
|
export interface MemberActionState {
|
|
error: string | null
|
|
success: boolean
|
|
}
|
|
|
|
export async function deleteInvitationAction(
|
|
_previousState: DeleteInvitationActionState,
|
|
formData: FormData,
|
|
): Promise<DeleteInvitationActionState> {
|
|
const session = await auth()
|
|
const adminEmail = session?.user?.email
|
|
|
|
if (!isAdminEmail(adminEmail)) {
|
|
return { error: "You are not allowed to delete invitations." }
|
|
}
|
|
|
|
const authorizedAdminEmail = adminEmail ?? ""
|
|
|
|
const parsed = deleteInvitationSchema.safeParse({
|
|
invitationId: formData.get("invitationId"),
|
|
})
|
|
|
|
if (!parsed.success) {
|
|
return { error: "Could not delete this guest group." }
|
|
}
|
|
|
|
let deleted: Awaited<ReturnType<typeof deleteInvitationGroup>>
|
|
|
|
try {
|
|
deleted = await deleteInvitationGroup(parsed.data.invitationId, authorizedAdminEmail)
|
|
} catch (error) {
|
|
console.error("Failed to delete invitation group", error)
|
|
return { error: "Could not delete this guest group. Please try again." }
|
|
}
|
|
|
|
if (!deleted) {
|
|
return { error: "This guest group was already removed." }
|
|
}
|
|
|
|
if (deleted.photoObjectKey) {
|
|
try {
|
|
await deleteUploadObject(deleted.photoObjectKey)
|
|
} catch (error) {
|
|
console.error("Failed to delete uploaded photo object", {
|
|
invitationId: deleted.id,
|
|
objectKey: deleted.photoObjectKey,
|
|
error,
|
|
})
|
|
}
|
|
}
|
|
|
|
revalidatePath("/admin/guests")
|
|
redirect("/admin/guests?deleted=1")
|
|
}
|
|
|
|
export async function updateInvitationMemberAction(
|
|
_previousState: MemberActionState,
|
|
formData: FormData,
|
|
): Promise<MemberActionState> {
|
|
const session = await auth()
|
|
const adminEmail = session?.user?.email
|
|
|
|
if (!isAdminEmail(adminEmail)) {
|
|
return { error: "You are not allowed to edit guest members.", success: false }
|
|
}
|
|
const authorizedAdminEmail = adminEmail ?? ""
|
|
|
|
const parsed = updateInvitationMemberSchema.safeParse({
|
|
invitationId: formData.get("invitationId")?.toString(),
|
|
memberId: formData.get("memberId")?.toString(),
|
|
name: formData.get("name")?.toString(),
|
|
})
|
|
|
|
if (!parsed.success) return { error: "Enter a valid member name.", success: false }
|
|
|
|
try {
|
|
const result = await updateInvitationMemberName({
|
|
...parsed.data,
|
|
adminEmail: authorizedAdminEmail,
|
|
})
|
|
|
|
if (result.status === "not_found") {
|
|
return { error: "This guest member was not found.", success: false }
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to update invitation member", error)
|
|
return { error: "Could not update this guest member. Please try again.", success: false }
|
|
}
|
|
|
|
revalidatePath(`/admin/guests/${parsed.data.invitationId}`)
|
|
revalidatePath("/admin/guests")
|
|
revalidatePath("/admin")
|
|
return { error: null, success: true }
|
|
}
|
|
|
|
export async function deleteInvitationMemberAction(
|
|
_previousState: MemberActionState,
|
|
formData: FormData,
|
|
): Promise<MemberActionState> {
|
|
const session = await auth()
|
|
const adminEmail = session?.user?.email
|
|
|
|
if (!isAdminEmail(adminEmail)) {
|
|
return { error: "You are not allowed to delete guest members.", success: false }
|
|
}
|
|
const authorizedAdminEmail = adminEmail ?? ""
|
|
|
|
const parsed = deleteInvitationMemberSchema.safeParse({
|
|
invitationId: formData.get("invitationId")?.toString(),
|
|
memberId: formData.get("memberId")?.toString(),
|
|
})
|
|
|
|
if (!parsed.success) return { error: "Could not delete this guest member.", success: false }
|
|
|
|
try {
|
|
const result = await deleteInvitationMember({ ...parsed.data, adminEmail: authorizedAdminEmail })
|
|
|
|
if (result.status === "not_found") {
|
|
return { error: "This guest member was already removed.", success: false }
|
|
}
|
|
if (result.status === "last_member") {
|
|
return { error: "A guest group must have at least one member.", success: false }
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to delete invitation member", error)
|
|
return { error: "Could not delete this guest member. Please try again.", success: false }
|
|
}
|
|
|
|
revalidatePath(`/admin/guests/${parsed.data.invitationId}`)
|
|
revalidatePath("/admin/guests")
|
|
revalidatePath("/admin")
|
|
return { error: null, success: true }
|
|
}
|