feat: implement project contacts fetching and display in ProjectViewPage
This commit is contained in:
@@ -30,6 +30,7 @@ export default function ProjectViewPage() {
|
||||
const [uploadedFiles, setUploadedFiles] = useState([]);
|
||||
const [editingNoteId, setEditingNoteId] = useState(null);
|
||||
const [editText, setEditText] = useState('');
|
||||
const [projectContacts, setProjectContacts] = useState([]);
|
||||
|
||||
// Helper function to parse note text with links
|
||||
const parseNoteText = (text) => {
|
||||
@@ -163,9 +164,14 @@ export default function ProjectViewPage() {
|
||||
const filesRes = await fetch(`/api/files?entityType=project&entityId=${params.id}`);
|
||||
const filesData = filesRes.ok ? await filesRes.json() : [];
|
||||
|
||||
// Fetch project contacts
|
||||
const contactsRes = await fetch(`/api/projects/${params.id}/contacts`);
|
||||
const contactsData = contactsRes.ok ? await contactsRes.json() : [];
|
||||
|
||||
setProject(projectData);
|
||||
setNotes(notesData);
|
||||
setUploadedFiles(filesData);
|
||||
setProjectContacts(contactsData);
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
setProject(null);
|
||||
@@ -221,6 +227,17 @@ export default function ProjectViewPage() {
|
||||
return "success";
|
||||
};
|
||||
|
||||
const getContactTypeBadge = (type) => {
|
||||
const types = {
|
||||
project: { label: "Projekt", variant: "primary" },
|
||||
contractor: { label: "Wykonawca", variant: "warning" },
|
||||
office: { label: "Urząd", variant: "info" },
|
||||
supplier: { label: "Dostawca", variant: "success" },
|
||||
other: { label: "Inny", variant: "secondary" },
|
||||
};
|
||||
return types[type] || types.other;
|
||||
};
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
{/* Mobile: Full-width title, Desktop: Standard PageHeader */}
|
||||
@@ -479,12 +496,53 @@ export default function ProjectViewPage() {
|
||||
{project.contact && (
|
||||
<div className="border-t pt-4">
|
||||
<span className="text-sm font-medium text-gray-500 block mb-1">
|
||||
Kontakt
|
||||
Kontakt (stary format)
|
||||
</span>
|
||||
<p className="text-gray-900 font-medium">{project.contact}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* New Contacts System */}
|
||||
{projectContacts.length > 0 && (
|
||||
<div className="border-t pt-4">
|
||||
<span className="text-sm font-medium text-gray-500 block mb-2">
|
||||
Kontakty
|
||||
</span>
|
||||
<div className="space-y-2">
|
||||
{projectContacts.map((contact) => {
|
||||
const typeBadge = getContactTypeBadge(contact.contact_type);
|
||||
return (
|
||||
<div
|
||||
key={contact.contact_id}
|
||||
className="p-3 bg-gray-50 rounded-md border border-gray-200"
|
||||
>
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<span className="font-medium text-gray-900">
|
||||
{contact.name}
|
||||
</span>
|
||||
{contact.is_primary === 1 && (
|
||||
<Badge variant="success" size="xs">
|
||||
Główny
|
||||
</Badge>
|
||||
)}
|
||||
<Badge variant={typeBadge.variant} size="xs">
|
||||
{typeBadge.label}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="text-sm text-gray-600 space-y-0.5">
|
||||
{contact.phone && <div>📞 {contact.phone}</div>}
|
||||
{contact.email && <div>📧 {contact.email}</div>}
|
||||
{contact.company && (
|
||||
<div className="text-xs text-gray-500">🏢 {contact.company}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{project.coordinates && (
|
||||
<div className="border-t pt-4">
|
||||
<span className="text-sm font-medium text-gray-500 block mb-1">
|
||||
|
||||
Reference in New Issue
Block a user