118 lines
4.2 KiB
TypeScript
118 lines
4.2 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from 'react';
|
|
import { Search, User, Mail, Phone, Building, MapPin, ChevronRight, Plus, Users } 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 => {
|
|
const searchLower = searchQuery.toLowerCase();
|
|
return (
|
|
(contact.fullName?.toLowerCase() || '').includes(searchLower) ||
|
|
(contact.email?.toLowerCase() || '').includes(searchLower) ||
|
|
(contact.organization?.toLowerCase() || '').includes(searchLower)
|
|
);
|
|
});
|
|
|
|
return (
|
|
<div className="flex flex-col h-full bg-carnet-bg border-r border-carnet-border">
|
|
{/* Header with Add Contact Button */}
|
|
<div className="p-4 border-b border-carnet-border">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<div className="flex items-center space-x-2">
|
|
<Users className="h-5 w-5 text-carnet-text-primary" />
|
|
<h2 className="text-lg font-semibold text-carnet-text-primary">Carnet d'adresses</h2>
|
|
</div>
|
|
<button
|
|
onClick={() => onContactSelect({
|
|
id: Math.random().toString(36).substr(2, 9),
|
|
fullName: '',
|
|
email: '',
|
|
phone: '',
|
|
organization: '',
|
|
address: '',
|
|
notes: '',
|
|
group: ''
|
|
})}
|
|
className="p-2 text-carnet-text-primary hover:bg-carnet-hover rounded-md"
|
|
>
|
|
<Plus className="h-5 w-5" />
|
|
</button>
|
|
</div>
|
|
{/* Search Bar */}
|
|
<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 || contact.email || 'Sans nom'}
|
|
</div>
|
|
{contact.email && (
|
|
<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>
|
|
</div>
|
|
);
|
|
};
|