177 lines
5.9 KiB
TypeScript
177 lines
5.9 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from 'react';
|
|
import { User, Mail, Phone, Building, MapPin, Edit2, Save, X } from 'lucide-react';
|
|
|
|
interface Contact {
|
|
id: string;
|
|
fullName?: string;
|
|
email?: string;
|
|
phone?: string;
|
|
organization?: string;
|
|
address?: string;
|
|
notes?: string;
|
|
group?: string;
|
|
}
|
|
|
|
interface ContactDetailsProps {
|
|
contact: Contact | null;
|
|
onSave?: (contact: Contact) => void;
|
|
onDelete?: (contact: Contact) => void;
|
|
}
|
|
|
|
export const ContactDetails: React.FC<ContactDetailsProps> = ({ contact, onSave, onDelete }) => {
|
|
const [isEditing, setIsEditing] = useState(false);
|
|
const [editedContact, setEditedContact] = useState<Contact | null>(null);
|
|
|
|
// Initialize edited contact when a contact is selected
|
|
React.useEffect(() => {
|
|
setEditedContact(contact);
|
|
setIsEditing(false);
|
|
}, [contact]);
|
|
|
|
if (!contact) {
|
|
return (
|
|
<div className="flex flex-col h-full bg-carnet-bg items-center justify-center text-carnet-text-muted">
|
|
<User className="h-16 w-16 mb-4 opacity-20" />
|
|
<p>Sélectionnez un contact pour voir les détails</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const handleSave = () => {
|
|
if (editedContact && onSave) {
|
|
onSave(editedContact);
|
|
setIsEditing(false);
|
|
}
|
|
};
|
|
|
|
const handleCancel = () => {
|
|
setEditedContact(contact);
|
|
setIsEditing(false);
|
|
};
|
|
|
|
const renderField = (label: string, value: string | undefined, field: keyof Contact, icon: React.ReactNode) => {
|
|
const bgColor = {
|
|
email: 'bg-blue-50',
|
|
phone: 'bg-green-50',
|
|
organization: 'bg-purple-50',
|
|
address: 'bg-orange-50'
|
|
}[field] || 'bg-gray-50';
|
|
|
|
const textColor = {
|
|
email: 'text-blue-500',
|
|
phone: 'text-green-500',
|
|
organization: 'text-purple-500',
|
|
address: 'text-orange-500'
|
|
}[field] || 'text-gray-500';
|
|
|
|
return (
|
|
<div className="flex items-center space-x-3">
|
|
<div className={`h-8 w-8 rounded-full ${bgColor} flex items-center justify-center`}>
|
|
<div className={textColor}>{icon}</div>
|
|
</div>
|
|
<div className="flex-1">
|
|
<p className="text-xs text-carnet-text-muted">{label}</p>
|
|
{isEditing ? (
|
|
<input
|
|
type="text"
|
|
value={editedContact?.[field] || ''}
|
|
onChange={(e) => setEditedContact(prev => prev ? {...prev, [field]: e.target.value} : null)}
|
|
className="w-full text-sm text-carnet-text-primary bg-transparent border-b border-primary focus:outline-none"
|
|
/>
|
|
) : (
|
|
<p className="text-sm text-carnet-text-primary">{value}</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="flex flex-col h-full bg-carnet-bg p-6">
|
|
<div className="flex justify-between items-start mb-6">
|
|
<div className="flex items-center space-x-4">
|
|
<div className="h-16 w-16 rounded-full bg-primary/10 flex items-center justify-center">
|
|
<User className="h-8 w-8 text-primary" />
|
|
</div>
|
|
<div>
|
|
{isEditing ? (
|
|
<input
|
|
type="text"
|
|
value={editedContact?.fullName || ''}
|
|
onChange={(e) => setEditedContact(prev => prev ? {...prev, fullName: e.target.value} : null)}
|
|
className="text-xl font-semibold text-carnet-text-primary bg-transparent border-b border-primary focus:outline-none"
|
|
placeholder="Nom complet"
|
|
/>
|
|
) : (
|
|
<h2 className="text-xl font-semibold text-carnet-text-primary">
|
|
{contact.fullName || contact.email || 'Sans nom'}
|
|
</h2>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="flex space-x-2">
|
|
{isEditing ? (
|
|
<>
|
|
<button
|
|
onClick={handleSave}
|
|
className="p-2 rounded-full hover:bg-primary/10 text-primary"
|
|
title="Enregistrer"
|
|
>
|
|
<Save className="h-5 w-5" />
|
|
</button>
|
|
<button
|
|
onClick={handleCancel}
|
|
className="p-2 rounded-full hover:bg-red-100 text-red-500"
|
|
title="Annuler"
|
|
>
|
|
<X className="h-5 w-5" />
|
|
</button>
|
|
</>
|
|
) : (
|
|
<>
|
|
<button
|
|
onClick={() => setIsEditing(true)}
|
|
className="p-2 rounded-full hover:bg-primary/10 text-primary"
|
|
title="Modifier"
|
|
>
|
|
<Edit2 className="h-5 w-5" />
|
|
</button>
|
|
{onDelete && (
|
|
<button
|
|
onClick={() => onDelete(contact)}
|
|
className="p-2 rounded-full hover:bg-red-100 text-red-500"
|
|
title="Supprimer"
|
|
>
|
|
<X className="h-5 w-5" />
|
|
</button>
|
|
)}
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
{renderField('Email', contact.email, 'email', <Mail className="h-4 w-4" />)}
|
|
{renderField('Téléphone', contact.phone, 'phone', <Phone className="h-4 w-4" />)}
|
|
{renderField('Organisation', contact.organization, 'organization', <Building className="h-4 w-4" />)}
|
|
{renderField('Adresse', contact.address, 'address', <MapPin className="h-4 w-4" />)}
|
|
</div>
|
|
|
|
<div className="mt-6">
|
|
<h3 className="text-sm font-medium text-carnet-text-primary mb-2">Notes</h3>
|
|
{isEditing ? (
|
|
<textarea
|
|
value={editedContact?.notes || ''}
|
|
onChange={(e) => setEditedContact(prev => prev ? {...prev, notes: e.target.value} : null)}
|
|
className="w-full h-32 text-sm text-carnet-text-muted bg-transparent border rounded-md p-2 focus:outline-none focus:border-primary"
|
|
placeholder="Ajouter des notes..."
|
|
/>
|
|
) : (
|
|
<p className="text-sm text-carnet-text-muted whitespace-pre-wrap">{contact.notes}</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|