Files
mkd/components/objects/DistrictStaffModal.tsx

118 lines
7.1 KiB
TypeScript
Raw Normal View History

2026-02-04 00:17:04 +05:00
import React from 'react';
import { Employee, District } from '../../types';
import { X, User, Phone, MessageCircle, MapPin } from 'lucide-react';
interface Props {
district: District;
employees: Employee[];
onClose: () => void;
}
export const DistrictStaffModal: React.FC<Props> = ({ district, employees, onClose }) => {
const districtEmployees = employees.filter(emp => {
const ids = emp.assignedDistrictIds?.length ? emp.assignedDistrictIds : (emp.assignedDistrictId ? [emp.assignedDistrictId] : []);
return ids.includes(district.id);
});
return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4" onClick={onClose}>
<div
className="bg-white rounded-2xl shadow-xl max-w-2xl w-full max-h-[90vh] overflow-hidden flex flex-col"
onClick={(e) => e.stopPropagation()}
>
{/* Header */}
<div className="flex items-center justify-between p-6 border-b border-slate-200">
<div>
<h2 className="text-xl font-bold text-slate-800">Персонал участка</h2>
<p className="text-sm text-slate-500 mt-1">{district.name}</p>
</div>
<button
onClick={onClose}
className="p-2 hover:bg-slate-100 rounded-lg transition-colors"
>
<X className="w-5 h-5 text-slate-500" />
</button>
</div>
{/* Content */}
<div className="flex-1 overflow-y-auto p-6">
{districtEmployees.length === 0 ? (
<div className="text-center py-12 text-slate-400">
<User className="w-12 h-12 mx-auto mb-4 opacity-20" />
<p className="font-bold">На этом участке нет закрепленных сотрудников</p>
</div>
) : (
<div className="space-y-3">
{districtEmployees.map(emp => (
<div
key={emp.id}
className="flex items-center justify-between p-4 bg-slate-50 rounded-xl border border-slate-100 hover:bg-slate-100 transition-colors"
>
<div className="flex items-center gap-3 flex-1">
<div className="w-12 h-12 rounded-full bg-white flex items-center justify-center text-primary-600 font-black border border-slate-200 shrink-0">
{emp.photoUrl ? (
<img
src={emp.photoUrl.startsWith('http')
? emp.photoUrl
: `${import.meta.env.VITE_API_BASE_URL?.replace('/api', '') || 'http://localhost:4000'}${emp.photoUrl}`}
alt={emp.name}
className="w-full h-full rounded-full object-cover"
onError={(e) => {
const target = e.target as HTMLImageElement;
target.style.display = 'none';
const parent = target.parentElement;
if (parent) {
const fallback = document.createElement('div');
fallback.className = 'w-12 h-12 rounded-full bg-white flex items-center justify-center text-primary-600 font-black border border-slate-200';
fallback.textContent = emp.name.split(' ').map(n => n[0]).join('');
parent.appendChild(fallback);
}
}}
/>
) : (
emp.name.split(' ').map(n => n[0]).join('')
)}
</div>
<div className="flex-1 min-w-0">
<p className="font-bold text-slate-800 text-sm">{emp.name}</p>
<p className="text-xs text-slate-500 flex items-center gap-1 mt-1">
<MapPin className="w-3 h-3"/> {emp.position}
</p>
{emp.phone && (
<p className="text-xs text-slate-400 mt-1">{emp.phone}</p>
)}
</div>
</div>
<div className="flex gap-1 shrink-0">
{emp.phone && (
<a
href={`tel:${emp.phone}`}
className="p-2 text-emerald-600 hover:bg-emerald-50 rounded-lg transition-colors"
onClick={(e) => e.stopPropagation()}
>
<Phone className="w-4 h-4"/>
</a>
)}
{emp.messengerLogins && emp.messengerLogins.length > 0 && (
<button
className="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
onClick={(e) => {
e.stopPropagation();
// Здесь можно добавить логику открытия мессенджера
}}
>
<MessageCircle className="w-4 h-4"/>
</button>
)}
</div>
</div>
))}
</div>
)}
</div>
</div>
</div>
);
};