feat: edit guest from guest groups
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { useRouter } from "next/navigation"
|
||||
|
||||
import {
|
||||
deleteInvitationMemberAction,
|
||||
updateInvitationMemberAction,
|
||||
} from "@/app/admin/guests/[id]/actions"
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
|
||||
interface MemberManagementProps {
|
||||
invitationId: string
|
||||
memberId: string
|
||||
memberName: string
|
||||
canDelete: boolean
|
||||
}
|
||||
|
||||
function SubmitButton({ children, variant = "default", pending }: { children: React.ReactNode; variant?: "default" | "destructive"; pending: boolean }) {
|
||||
return (
|
||||
<Button type="submit" variant={variant} disabled={pending}>
|
||||
{pending ? "Saving..." : children}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
export function MemberManagement({
|
||||
invitationId,
|
||||
memberId,
|
||||
memberName,
|
||||
canDelete,
|
||||
}: MemberManagementProps) {
|
||||
const router = useRouter()
|
||||
const [editOpen, setEditOpen] = useState(false)
|
||||
const [deleteOpen, setDeleteOpen] = useState(false)
|
||||
const [name, setName] = useState(memberName)
|
||||
const [editError, setEditError] = useState<string | null>(null)
|
||||
const [deleteError, setDeleteError] = useState<string | null>(null)
|
||||
const [pendingAction, setPendingAction] = useState<"edit" | "delete" | null>(null)
|
||||
|
||||
async function submitEdit(event: React.FormEvent<HTMLFormElement>) {
|
||||
event.preventDefault()
|
||||
setPendingAction("edit")
|
||||
setEditError(null)
|
||||
const result = await updateInvitationMemberAction({ error: null, success: false }, new FormData(event.currentTarget))
|
||||
setPendingAction(null)
|
||||
if (result.error) {
|
||||
setEditError(result.error)
|
||||
return
|
||||
}
|
||||
setEditOpen(false)
|
||||
router.refresh()
|
||||
}
|
||||
|
||||
async function submitDelete(event: React.FormEvent<HTMLFormElement>) {
|
||||
event.preventDefault()
|
||||
setPendingAction("delete")
|
||||
setDeleteError(null)
|
||||
const result = await deleteInvitationMemberAction({ error: null, success: false }, new FormData(event.currentTarget))
|
||||
setPendingAction(null)
|
||||
if (result.error) {
|
||||
setDeleteError(result.error)
|
||||
return
|
||||
}
|
||||
setDeleteOpen(false)
|
||||
router.refresh()
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<AlertDialog open={editOpen} onOpenChange={setEditOpen}>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button type="button" size="sm" variant="outline">Edit</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<form onSubmit={submitEdit} className="space-y-4">
|
||||
<input type="hidden" name="invitationId" value={invitationId} />
|
||||
<input type="hidden" name="memberId" value={memberId} />
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Edit guest member</AlertDialogTitle>
|
||||
<AlertDialogDescription>Update the member's name.</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<Input
|
||||
name="name"
|
||||
value={name}
|
||||
onChange={(event) => setName(event.target.value)}
|
||||
aria-label="Member name"
|
||||
autoFocus
|
||||
maxLength={200}
|
||||
required
|
||||
/>
|
||||
{editError ? <p className="text-sm text-destructive">{editError}</p> : null}
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel type="button">Cancel</AlertDialogCancel>
|
||||
<SubmitButton pending={pendingAction === "edit"}>Save changes</SubmitButton>
|
||||
</AlertDialogFooter>
|
||||
</form>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
{canDelete ? (
|
||||
<AlertDialog open={deleteOpen} onOpenChange={setDeleteOpen}>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button type="button" size="sm" variant="destructive">Delete</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<form onSubmit={submitDelete} className="space-y-4">
|
||||
<input type="hidden" name="invitationId" value={invitationId} />
|
||||
<input type="hidden" name="memberId" value={memberId} />
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Delete {memberName}?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This removes the member from the invitation. If they are the primary contact,
|
||||
another member will become primary.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
{deleteError ? <p className="text-sm text-destructive">{deleteError}</p> : null}
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel type="button">Cancel</AlertDialogCancel>
|
||||
<SubmitButton variant="destructive" pending={pendingAction === "delete"}>Delete member</SubmitButton>
|
||||
</AlertDialogFooter>
|
||||
</form>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user