feat: quick contact dialog from registratura supports name OR company
- QuickContactDialog now has Company/Organization field - Either name or company is required (same logic as address book) - Auto-sets type to "institution" when only company is provided - Display name in registry form uses company as fallback Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,17 +13,24 @@ import {
|
||||
DialogFooter,
|
||||
} from "@/shared/components/ui/dialog";
|
||||
|
||||
export interface QuickContactData {
|
||||
name: string;
|
||||
company: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
interface QuickContactDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
/** Pre-filled name from the text the user typed */
|
||||
initialName: string;
|
||||
onConfirm: (data: { name: string; phone: string; email: string }) => void;
|
||||
onConfirm: (data: QuickContactData) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rapid popup for creating a new Address Book contact from Registratura.
|
||||
* Only requires Name; Phone and Email are optional.
|
||||
* Requires either Name or Company; Phone and Email are optional.
|
||||
*/
|
||||
export function QuickContactDialog({
|
||||
open,
|
||||
@@ -32,27 +39,34 @@ export function QuickContactDialog({
|
||||
onConfirm,
|
||||
}: QuickContactDialogProps) {
|
||||
const [name, setName] = useState(initialName);
|
||||
const [company, setCompany] = useState("");
|
||||
const [phone, setPhone] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
|
||||
// Sync name with initialName whenever the dialog opens
|
||||
// (useState(initialName) only works on first mount; controlled open
|
||||
// bypasses onOpenChange so we need useEffect)
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
setName(initialName);
|
||||
setCompany("");
|
||||
setPhone("");
|
||||
setEmail("");
|
||||
}
|
||||
}, [open, initialName]);
|
||||
|
||||
const hasIdentifier = name.trim() || company.trim();
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
// Stop propagation so the submit doesn't bubble through the React portal
|
||||
// to the outer registry-entry-form, which would close the whole form.
|
||||
e.stopPropagation();
|
||||
if (!name.trim()) return;
|
||||
onConfirm({ name: name.trim(), phone: phone.trim(), email: email.trim() });
|
||||
if (!hasIdentifier) return;
|
||||
onConfirm({
|
||||
name: name.trim(),
|
||||
company: company.trim(),
|
||||
phone: phone.trim(),
|
||||
email: email.trim(),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -65,16 +79,32 @@ export function QuickContactDialog({
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit} className="space-y-3">
|
||||
{!hasIdentifier && (
|
||||
<p className="text-xs text-destructive">
|
||||
Completează cel puțin Numele sau Compania/Organizația.
|
||||
</p>
|
||||
)}
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
<div>
|
||||
<Label>Nume *</Label>
|
||||
<Label>Nume {!company.trim() ? "*" : ""}</Label>
|
||||
<Input
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
className="mt-1"
|
||||
required
|
||||
required={!company.trim()}
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Companie/Organizație {!name.trim() ? "*" : ""}</Label>
|
||||
<Input
|
||||
value={company}
|
||||
onChange={(e) => setCompany(e.target.value)}
|
||||
className="mt-1"
|
||||
required={!name.trim()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
<div>
|
||||
<Label>Telefon</Label>
|
||||
@@ -104,7 +134,7 @@ export function QuickContactDialog({
|
||||
>
|
||||
Anulează
|
||||
</Button>
|
||||
<Button type="submit" disabled={!name.trim()}>
|
||||
<Button type="submit" disabled={!hasIdentifier}>
|
||||
Creează contact
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
@@ -93,6 +93,7 @@ export function RegistraturaModule() {
|
||||
const handleCreateContact = useCallback(
|
||||
async (data: {
|
||||
name: string;
|
||||
company: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
}): Promise<AddressContact | undefined> => {
|
||||
@@ -101,8 +102,8 @@ export function RegistraturaModule() {
|
||||
const contact: AddressContact = {
|
||||
id: uuid(),
|
||||
name: data.name,
|
||||
company: "",
|
||||
type: "collaborator",
|
||||
company: data.company,
|
||||
type: data.company && !data.name ? "institution" : "collaborator",
|
||||
email: data.email,
|
||||
email2: "",
|
||||
phone: data.phone,
|
||||
|
||||
@@ -100,6 +100,7 @@ interface RegistryEntryFormProps {
|
||||
/** Callback to create a new Address Book contact */
|
||||
onCreateContact?: (data: {
|
||||
name: string;
|
||||
company: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
}) => Promise<AddressContact | undefined>;
|
||||
@@ -513,15 +514,17 @@ export function RegistryEntryForm({
|
||||
|
||||
const handleQuickContactConfirm = async (data: {
|
||||
name: string;
|
||||
company: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
}) => {
|
||||
if (!onCreateContact) return;
|
||||
const contact = await onCreateContact(data);
|
||||
if (contact) {
|
||||
const displayName = contact.company
|
||||
const displayName =
|
||||
contact.name && contact.company
|
||||
? `${contact.name} (${contact.company})`
|
||||
: contact.name;
|
||||
: contact.name || contact.company;
|
||||
if (quickContactField === "sender") {
|
||||
setSender(displayName);
|
||||
setSenderContactId(contact.id);
|
||||
|
||||
Reference in New Issue
Block a user