'use client' import { useState, useEffect } from 'react' import { toast } from 'react-hot-toast' import { Plus, Edit, Trash2, Search, X, Calendar, User, Building2, Loader2, ExternalLink } from 'lucide-react' import { contactsAPI } from '@/lib/api/contacts' import { format } from 'date-fns' import Link from 'next/link' interface Relationship { id: string fromContactId: string toContactId: string type: string startDate: string endDate?: string notes?: string isActive: boolean fromContact: { id: string uniqueContactId: string type: string name: string email?: string phone?: string status: string } toContact: { id: string uniqueContactId: string type: string name: string email?: string phone?: string status: string } } interface RelationshipManagerProps { contactId: string } const RELATIONSHIP_TYPES = [ { value: 'REPRESENTATIVE', label: 'Representative - ممثل' }, { value: 'PARTNER', label: 'Partner - شريك' }, { value: 'SUPPLIER', label: 'Supplier - مورد' }, { value: 'EMPLOYEE', label: 'Employee - موظف' }, { value: 'SUBSIDIARY', label: 'Subsidiary - فرع' }, { value: 'BRANCH', label: 'Branch - فرع' }, { value: 'PARENT_COMPANY', label: 'Parent Company - شركة أم' }, { value: 'CUSTOMER', label: 'Customer - عميل' }, { value: 'VENDOR', label: 'Vendor - بائع' }, { value: 'OTHER', label: 'Other - أخرى' }, ] export default function RelationshipManager({ contactId }: RelationshipManagerProps) { const [relationships, setRelationships] = useState([]) const [loading, setLoading] = useState(true) const [showAddModal, setShowAddModal] = useState(false) const [showEditModal, setShowEditModal] = useState(false) const [selectedRelationship, setSelectedRelationship] = useState(null) const [submitting, setSubmitting] = useState(false) // Form state const [searchTerm, setSearchTerm] = useState('') const [searchResults, setSearchResults] = useState([]) const [searching, setSearching] = useState(false) const [formData, setFormData] = useState({ toContactId: '', type: 'REPRESENTATIVE', startDate: new Date().toISOString().split('T')[0], endDate: '', notes: '' }) useEffect(() => { fetchRelationships() }, [contactId]) const fetchRelationships = async () => { setLoading(true) try { const data = await contactsAPI.getRelationships(contactId) setRelationships(data) } catch (error: any) { toast.error('Failed to load relationships') } finally { setLoading(false) } } // Search contacts with debouncing useEffect(() => { if (!searchTerm || searchTerm.length < 2) { setSearchResults([]) return } const debounce = setTimeout(async () => { setSearching(true) try { const data = await contactsAPI.getAll({ search: searchTerm, pageSize: 10 }) setSearchResults(data.contacts.filter(c => c.id !== contactId)) } catch (error) { console.error('Search error:', error) } finally { setSearching(false) } }, 500) return () => clearTimeout(debounce) }, [searchTerm, contactId]) const resetForm = () => { setFormData({ toContactId: '', type: 'REPRESENTATIVE', startDate: new Date().toISOString().split('T')[0], endDate: '', notes: '' }) setSearchTerm('') setSearchResults([]) setSelectedRelationship(null) } const handleAdd = async () => { if (!formData.toContactId) { toast.error('Please select a contact') return } setSubmitting(true) try { await contactsAPI.addRelationship(contactId, { toContactId: formData.toContactId, type: formData.type, startDate: formData.startDate, endDate: formData.endDate || undefined, notes: formData.notes || undefined }) toast.success('Relationship added successfully') setShowAddModal(false) resetForm() fetchRelationships() } catch (error: any) { toast.error(error.response?.data?.message || 'Failed to add relationship') } finally { setSubmitting(false) } } const handleEdit = async () => { if (!selectedRelationship) return setSubmitting(true) try { await contactsAPI.updateRelationship( contactId, selectedRelationship.id, { type: formData.type, startDate: formData.startDate, endDate: formData.endDate || undefined, notes: formData.notes || undefined } ) toast.success('Relationship updated successfully') setShowEditModal(false) resetForm() fetchRelationships() } catch (error: any) { toast.error(error.response?.data?.message || 'Failed to update relationship') } finally { setSubmitting(false) } } const handleDelete = async (relationship: Relationship) => { if (!confirm('Are you sure you want to delete this relationship?')) return try { await contactsAPI.deleteRelationship(contactId, relationship.id) toast.success('Relationship deleted successfully') fetchRelationships() } catch (error: any) { toast.error('Failed to delete relationship') } } const openEditModal = (relationship: Relationship) => { setSelectedRelationship(relationship) setFormData({ toContactId: relationship.toContactId, type: relationship.type, startDate: relationship.startDate.split('T')[0], endDate: relationship.endDate ? relationship.endDate.split('T')[0] : '', notes: relationship.notes || '' }) setShowEditModal(true) } const getRelatedContact = (relationship: Relationship) => { return relationship.fromContactId === contactId ? relationship.toContact : relationship.fromContact } const getRelationshipDirection = (relationship: Relationship) => { return relationship.fromContactId === contactId ? '→' : '←' } if (loading) { return (
) } return (
{/* Header */}

العلاقات - Relationships ({relationships.length})

{/* Relationships List */} {relationships.length === 0 ? (

No relationships found

) : (
{relationships.map(relationship => { const relatedContact = getRelatedContact(relationship) return ( ) })}
Contact Type Start Date End Date Status Actions
{getRelationshipDirection(relationship)} {relatedContact.type === 'INDIVIDUAL' ? ( ) : ( )}
{relatedContact.name}

{relatedContact.email || relatedContact.phone}

{relationship.type.replace(/_/g, ' ')} {format(new Date(relationship.startDate), 'MMM d, yyyy')} {relationship.endDate ? format(new Date(relationship.endDate), 'MMM d, yyyy') : '-'} {relationship.isActive ? 'Active' : 'Inactive'}
)} {/* Add Modal */} {showAddModal && (

إضافة علاقة - Add Relationship

{/* Contact Search */}
setSearchTerm(e.target.value)} placeholder="Search contacts..." className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-gray-900" />
{searching && (

Searching...

)} {searchResults.length > 0 && (
{searchResults.map(contact => ( ))}
)}
{/* Relationship Type */}
{/* Start Date */}
setFormData({ ...formData, startDate: e.target.value })} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-gray-900" />
{/* End Date */}
setFormData({ ...formData, endDate: e.target.value })} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-gray-900" />
{/* Notes */}