import React, { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Project, ShopItem } from '../types'; import { Icons, ItemIcon } from '../components/IconSet'; import { dbService } from '../services/DatabaseService'; import { authService } from '../services/AuthService'; import { DiscordUser } from '../types'; import EditModal from '../components/EditModal'; import ShopManagementModal from '../components/ShopManagementModal'; import EmployeeManagementModal from '../components/EmployeeManagementModal'; import BannerManagementModal from '../components/BannerManagementModal'; import LogoManagementModal from '../components/LogoManagementModal'; import GalleryManagementModal from '../components/GalleryManagementModal'; import DeleteProjectModal from '../components/DeleteProjectModal'; const ProjectProfile: React.FC = () => { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const [project, setProject] = useState(null); const [loading, setLoading] = useState(true); const [activeTab, setActiveTab] = useState<'overview' | 'shop' | 'manage'>('overview'); const [user, setUser] = useState(null); const [org, setOrg] = useState(null); const [ownerPlayer, setOwnerPlayer] = useState(null); const [isEditDescriptionOpen, setIsEditDescriptionOpen] = useState(false); const [isEditHiringOpen, setIsEditHiringOpen] = useState(false); const [isShopModalOpen, setIsShopModalOpen] = useState(false); const [isEmployeeModalOpen, setIsEmployeeModalOpen] = useState(false); const [isBannerModalOpen, setIsBannerModalOpen] = useState(false); const [isLogoModalOpen, setIsLogoModalOpen] = useState(false); const [isGalleryModalOpen, setIsGalleryModalOpen] = useState(false); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); // Subscribe to auth and data updates useEffect(() => { const unsubAuth = authService.subscribe(setUser); return unsubAuth; }, []); useEffect(() => { if (!id) { navigate('/projects'); return; } // Load project data const projectData = dbService.getProject(id); if (projectData) { setProject(projectData); } else { navigate('/projects'); return; } setLoading(false); }, [id, navigate]); useEffect(() => { if (!project) return; // Load associated org and owner player if (project.associatedOrgId) { const foundOrg = dbService.getOrg(project.associatedOrgId); setOrg(foundOrg); } // Find owner player by username const players = dbService.getPlayers(); const owner = players.find(p => p.username === project.owner); setOwnerPlayer(owner); }, [project]); const onSelectPlayer = (playerId: string) => navigate(`/players/${playerId}`); const onSelectOrg = (orgId: string) => { const org = dbService.getOrgs().find(o => o.id === orgId); if (org?.type === 'City') { navigate(`/cities/${orgId}`); } else { navigate(`/organizations/${orgId}`); } }; const onBack = () => navigate('/projects'); const hasShop = project?.shopCatalog && project.shopCatalog.length > 0; const isOwner = user?.linkedPlayerUuid && ownerPlayer && dbService.getPlayer(user.linkedPlayerUuid)?.username === project?.owner; // Group shop items const services = project?.shopCatalog?.filter(i => i.type === 'service') || []; const products = project?.shopCatalog?.filter(i => i.type !== 'service') || []; if (loading || !project) { return (
); } return (
{/* Banner Header */}
{project.title} {/* Decorative elements for Black Market */} {project.category === 'Black Market' && (
)}
{project.category} {project.status === 'active' && ( AKTIV )} {project.hiring && ( STELLEN )}

{project.title}

ownerPlayer && onSelectPlayer(ownerPlayer.uuid)} > {project.logoUrl ? ( {`${project.title} ) : (
{project.owner.charAt(0)}
)} Inhaber: {project.owner}
{project.foundedDate && ( Gegr. {project.foundedDate} )}
{hasShop && ( )}
{/* Navigation */}
{hasShop && ( )} {isOwner && ( )}
{/* Content */}
{activeTab === 'overview' && (

Manifest

{project.description}

{/* Project Portfolio / Gallery */} {project.gallery && project.gallery.length > 0 && (

Portfolio

{project.gallery.map((image, idx) => (
{`Portfolio
))}
)}

Personal

{project.employees.map((emp, idx) => { const players = dbService.getPlayers(); const empPlayer = players.find(p => p.username === emp); return (
empPlayer && onSelectPlayer(empPlayer.uuid)} className={`flex items-center gap-3 bg-surface border border-border p-3 rounded-lg ${empPlayer ? 'cursor-pointer hover:border-accentInfo/50 hover:bg-surfaceHighlight/30 transition-all group' : ''}`} >
{emp.charAt(0)}
{emp}
); })} {project.employees.length === 0 && (
Kein weiteres Personal registriert.
)}
{/* Right Column: Statistics */}

Unternehmensdaten

{/* Industry */}
Branche {project.category}
{/* Founded */}
Gegründet {project.foundedDate || 'N/A'}
{/* Reputation */}
Ruf {project.progress}/100
{/* Workforce */}
Belegschaft
{project.employees.length + 1}
{/* Headquarters Link */} {org && (
Hauptsitz
onSelectOrg(org.id)} className="flex items-center gap-3 bg-surfaceHighlight/50 p-2 rounded-lg border border-white/5 cursor-pointer hover:border-accentInfo/50 hover:bg-surfaceHighlight transition-all group" >
{org.name.charAt(0)}
{org.name}
)}
)} {activeTab === 'manage' && isOwner && (

Unternehmen verwalten

{/* Edit Description */}

Manifest bearbeiten

Ändern Sie die Beschreibung und das Leitbild Ihres Unternehmens.

{/* Toggle Hiring */}

Stellenanzeigen

Aktuell: {project.hiring ? 'Stellen sind ausgeschrieben' : 'Keine offenen Stellen'}

{/* Shop Management */}

Shop verwalten

Fügen Sie Produkte, Dienstleistungen und Preise hinzu.

{/* Employee Management */}

Mitarbeiter verwalten

Fügen Sie Mitarbeiter hinzu oder entfernen Sie sie.

{/* Banner Management */}

Banner ändern

Ändern Sie das Titelbild Ihres Unternehmens.

{/* Logo Management */}

Logo ändern

Setzen Sie ein Logo für Ihr Unternehmen.

{/* Gallery Management */}

Galerie verwalten

Fügen Sie Bilder zu Ihrem Portfolio hinzu.

{/* Danger Zone */}

Gefahrenzone

Unwiderrufliche Aktionen für dieses Unternehmen.

)} {activeTab === 'shop' && project.shopCatalog && (
{/* Services Section */} {services.length > 0 && (

Dienstleistungen & Verträge

Fachkräfte für Spezialaufträge anheuern.

{services.map(item => (

{item.name}

{item.price} {item.currency}

{item.description}

{item.materialsRequired && (
Materialanforderungen: {item.materialsRequired}
)}
))}
)} {/* Products Section */} {products.length > 0 && (

Produktkatalog

Items, Bücher und Baupläne zur sofortigen Abholung.

{products.map(item => (
{item.type === 'blueprint' ? : }
0 ? 'bg-green-500/10 text-green-400 border-green-500/20' : 'bg-red-500/10 text-red-400 border-red-500/20' }`}> {item.stock > 0 ? `${item.stock} auf Lager` : 'Ausverkauft'}

{item.name}

{item.description}

Preis {item.price} {item.currency}
))}
)}
)} {/* Edit Modals */} setIsEditDescriptionOpen(false)} onSave={async (newDescription) => { try { const response = await fetch(`https://vollidioten.ceraticsoft.de/api/projects/${project.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ description: newDescription }) }); if (response.ok) { // Update local data dbService.updateProject(project.id, { description: newDescription }); console.log('Description updated successfully'); } else { const errorData = await response.json(); alert(`Fehler beim Aktualisieren: ${errorData.error || 'Unbekannter Fehler'}`); } } catch (err) { console.error('Error updating description:', err); alert('Netzwerkfehler beim Aktualisieren der Beschreibung'); } }} /> setIsEditHiringOpen(false)} onSave={async (value) => { const newHiringStatus = !project.hiring; try { const response = await fetch(`https://vollidioten.ceraticsoft.de/api/projects/${project.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ hiring: newHiringStatus }) }); if (response.ok) { // Update local data dbService.updateProject(project.id, { hiring: newHiringStatus }); console.log('Hiring status updated successfully:', newHiringStatus); } else { const errorData = await response.json(); alert(`Fehler beim Aktualisieren: ${errorData.error || 'Unbekannter Fehler'}`); } } catch (err) { console.error('Error updating hiring status:', err); alert('Netzwerkfehler beim Aktualisieren der Stellenanzeigen'); } }} /> {/* Management Modals */} setIsShopModalOpen(false)} projectId={project.id} onUpdate={() => { // Refresh project data console.log('Shop updated, refreshing project data...'); // The dbService should automatically update via subscription }} /> setIsEmployeeModalOpen(false)} projectId={project.id} onUpdate={() => { // Refresh project data console.log('Employees updated, refreshing project data...'); }} /> setIsBannerModalOpen(false)} projectId={project.id} currentBannerUrl={project.bannerUrl || ''} onUpdate={() => { // Refresh project data console.log('Banner updated, refreshing project data...'); }} /> setIsLogoModalOpen(false)} projectId={project.id} currentLogoUrl={project.logoUrl || ''} onUpdate={() => { // Refresh project data console.log('Logo updated, refreshing project data...'); }} /> setIsGalleryModalOpen(false)} projectId={project.id} onUpdate={() => { // Refresh project data console.log('Gallery updated, refreshing project data...'); }} /> setIsDeleteModalOpen(false)} projectId={project.id} projectTitle={project.title} onDelete={async () => { try { const response = await fetch(`https://vollidioten.ceraticsoft.de/api/projects/${project.id}`, { method: 'DELETE', credentials: 'include' }); if (response.ok) { alert('Projekt erfolgreich gelöscht!'); onBack(); // Navigate back to projects list } else { alert('Fehler beim Löschen des Projekts'); } } catch (err) { console.error('Error deleting project:', err); alert('Netzwerkfehler beim Löschen'); } }} />
); }; export default ProjectProfile;