139 lines
5.3 KiB
TypeScript
139 lines
5.3 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from 'react';
|
|
import { Search, User, Mail, Phone, Building, MapPin, ChevronRight } from 'lucide-react';
|
|
|
|
interface Contact {
|
|
id: string;
|
|
fullName: string;
|
|
email: string;
|
|
phone?: string;
|
|
organization?: string;
|
|
address?: string;
|
|
notes?: string;
|
|
group?: string;
|
|
}
|
|
|
|
interface ContactsViewProps {
|
|
contacts: Contact[];
|
|
onContactSelect: (contact: Contact) => void;
|
|
selectedContact: Contact | null;
|
|
loading?: boolean;
|
|
}
|
|
|
|
export const ContactsView: React.FC<ContactsViewProps> = ({
|
|
contacts,
|
|
onContactSelect,
|
|
selectedContact,
|
|
loading = false
|
|
}) => {
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
|
|
const filteredContacts = contacts.filter(contact =>
|
|
contact.fullName.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
contact.email.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
contact.organization?.toLowerCase().includes(searchQuery.toLowerCase())
|
|
);
|
|
|
|
return (
|
|
<div className="flex flex-col h-full bg-carnet-bg border-r border-carnet-border">
|
|
{/* Search Bar */}
|
|
<div className="p-4 border-b border-carnet-border">
|
|
<div className="relative">
|
|
<input
|
|
type="text"
|
|
value={searchQuery}
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
placeholder="Rechercher un contact..."
|
|
className="w-full pl-9 pr-4 py-2 bg-white border border-carnet-border rounded-md text-sm text-carnet-text-primary placeholder-carnet-text-muted focus:outline-none focus:ring-1 focus:ring-primary"
|
|
/>
|
|
<Search className="absolute left-3 top-2.5 h-4 w-4 text-carnet-text-muted" />
|
|
</div>
|
|
</div>
|
|
|
|
{/* Contacts List */}
|
|
<div className="flex-1 overflow-y-auto">
|
|
{loading ? (
|
|
<div className="p-4 text-center text-carnet-text-muted">Chargement...</div>
|
|
) : filteredContacts.length === 0 ? (
|
|
<div className="p-4 text-center text-carnet-text-muted">Aucun contact trouvé</div>
|
|
) : (
|
|
<ul className="divide-y divide-carnet-border">
|
|
{filteredContacts.map((contact) => (
|
|
<li
|
|
key={contact.id}
|
|
onClick={() => onContactSelect(contact)}
|
|
className={`p-4 cursor-pointer hover:bg-carnet-hover ${
|
|
selectedContact?.id === contact.id ? 'bg-carnet-hover' : ''
|
|
}`}
|
|
>
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center space-x-3">
|
|
<div className="h-10 w-10 rounded-full bg-primary/10 flex items-center justify-center">
|
|
<User className="h-5 w-5 text-primary" />
|
|
</div>
|
|
<div>
|
|
<div className="font-medium text-carnet-text-primary">{contact.fullName}</div>
|
|
<div className="text-sm text-carnet-text-muted">{contact.email}</div>
|
|
</div>
|
|
</div>
|
|
<ChevronRight className="h-4 w-4 text-carnet-text-muted" />
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
|
|
{/* Contact Details */}
|
|
{selectedContact && (
|
|
<div className="p-4 border-t border-carnet-border">
|
|
<div className="space-y-4">
|
|
<div className="flex items-center space-x-3">
|
|
<div className="h-12 w-12 rounded-full bg-primary/10 flex items-center justify-center">
|
|
<User className="h-6 w-6 text-primary" />
|
|
</div>
|
|
<div>
|
|
<h3 className="text-lg font-semibold text-carnet-text-primary">
|
|
{selectedContact.fullName}
|
|
</h3>
|
|
{selectedContact.organization && (
|
|
<p className="text-sm text-carnet-text-muted">
|
|
{selectedContact.organization}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-3">
|
|
{selectedContact.email && (
|
|
<div className="flex items-center space-x-2">
|
|
<Mail className="h-4 w-4 text-carnet-text-muted" />
|
|
<span className="text-sm text-carnet-text-primary">{selectedContact.email}</span>
|
|
</div>
|
|
)}
|
|
{selectedContact.phone && (
|
|
<div className="flex items-center space-x-2">
|
|
<Phone className="h-4 w-4 text-carnet-text-muted" />
|
|
<span className="text-sm text-carnet-text-primary">{selectedContact.phone}</span>
|
|
</div>
|
|
)}
|
|
{selectedContact.address && (
|
|
<div className="flex items-center space-x-2">
|
|
<MapPin className="h-4 w-4 text-carnet-text-muted" />
|
|
<span className="text-sm text-carnet-text-primary">{selectedContact.address}</span>
|
|
</div>
|
|
)}
|
|
{selectedContact.notes && (
|
|
<div className="mt-4">
|
|
<h4 className="text-sm font-medium text-carnet-text-primary mb-2">Notes</h4>
|
|
<p className="text-sm text-carnet-text-muted">{selectedContact.notes}</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|