Files
mkd/components/objects/DistrictStaffModal.tsx
2026-02-04 00:17:04 +05:00

118 lines
7.1 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
};