All files / src/components/profile/whatsapp-recipients EditRecipientDialog.tsx

100% Statements 24/24
92.85% Branches 13/14
100% Functions 3/3
100% Lines 22/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                            20x 20x 20x 20x   20x   19x 5x 5x 5x 5x 1x 1x   4x 1x 1x   3x 3x 1x   2x 1x       19x                                                       5x                            
import { type FormEvent, useId, useState } from "react";
import { useUpdateWhatsAppRecipient } from "../../../hooks/queries/useWhatsAppRecipientQueries";
import { ApiError, type WhatsAppRecipient } from "../../../lib/api";
import { Button } from "../../ui/button";
import { DrawerDialog } from "../../ui/drawer-dialog";
import { Input } from "../../ui/input";
 
interface Props {
	proId: string;
	recipient?: WhatsAppRecipient;
	onClose: () => void;
}
 
export function EditRecipientDialog({ proId, recipient, onClose }: Props) {
	const [label, setLabel] = useState(recipient?.label ?? "");
	const [error, setError] = useState<string | null>(null);
	const labelId = useId();
	const updateMut = useUpdateWhatsAppRecipient(proId);
 
	if (!recipient) return null;
 
	const handleSubmit = async (e: FormEvent) => {
		e.preventDefault();
		setError(null);
		const trimmed = label.trim();
		if (!trimmed) {
			setError("Label cannot be empty.");
			return;
		}
		if (trimmed.length > 32) {
			setError("Label must be 32 characters or fewer.");
			return;
		}
		try {
			await updateMut.mutateAsync({ id: recipient.id, patch: { label: trimmed } });
			onClose();
		} catch (err) {
			if (err instanceof ApiError) setError(err.message);
			else setError("Could not save changes.");
		}
	};
 
	return (
		<DrawerDialog
			open
			onClose={onClose}
			title="Edit recipient"
			footer={
				<div className="flex justify-end gap-2">
					<Button variant="outline" onClick={onClose}>
						Cancel
					</Button>
					<Button
						type="submit"
						form="edit-recipient-form"
						disabled={updateMut.isPending}
					>
						{updateMut.isPending ? "Saving…" : "Save"}
					</Button>
				</div>
			}
		>
			<form id="edit-recipient-form" onSubmit={handleSubmit} className="flex flex-col gap-4">
				<div className="flex flex-col gap-1 text-sm">
					<label htmlFor={labelId} className="font-medium text-foreground-default">
						Label
					</label>
					<Input
						id={labelId}
						value={label}
						onChange={(e) => setLabel(e.target.value)}
						maxLength={32}
						autoFocus
					/>
				</div>
				<p className="text-xs text-foreground-muted">
					Number is fixed once verified. To change it, remove this row and add
					a new one.
				</p>
				{error && <p className="text-sm text-error" role="alert">{error}</p>}
			</form>
		</DrawerDialog>
	);
}