This commit is contained in:
Lars Behrends
2025-12-28 17:21:30 +01:00
parent 5d44abbedc
commit 2481187fe7
10 changed files with 1240 additions and 226 deletions

View File

@@ -1,4 +1,5 @@
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';
@@ -11,19 +12,11 @@ import BannerManagementModal from '../components/BannerManagementModal';
import GalleryManagementModal from '../components/GalleryManagementModal';
import DeleteProjectModal from '../components/DeleteProjectModal';
interface ProjectProfileProps {
project: Project;
onBack: () => void;
onSelectPlayer: (id: string) => void;
onSelectOrg: (id: string) => void;
}
const ProjectProfile: React.FC<ProjectProfileProps> = ({
project,
onBack,
onSelectPlayer,
onSelectOrg
}) => {
const ProjectProfile: React.FC = () => {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const [project, setProject] = useState<Project | null>(null);
const [loading, setLoading] = useState(true);
const [activeTab, setActiveTab] = useState<'overview' | 'shop' | 'manage'>('overview');
const [user, setUser] = useState<DiscordUser | null>(null);
const [org, setOrg] = useState<any>(null);
@@ -43,6 +36,26 @@ const ProjectProfile: React.FC<ProjectProfileProps> = ({
}, []);
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);
@@ -55,16 +68,37 @@ const ProjectProfile: React.FC<ProjectProfileProps> = ({
setOwnerPlayer(owner);
}, [project]);
const hasShop = project.shopCatalog && project.shopCatalog.length > 0;
const isOwner = user?.linkedPlayerUuid && ownerPlayer && dbService.getPlayer(user.linkedPlayerUuid)?.username === project.owner;
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') || [];
const services = project?.shopCatalog?.filter(i => i.type === 'service') || [];
const products = project?.shopCatalog?.filter(i => i.type !== 'service') || [];
if (loading || !project) {
return (
<div className="max-w-4xl mx-auto animate-in slide-in-from-right-4 duration-300">
<div className="flex justify-center py-20">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-accentInfo"></div>
</div>
</div>
);
}
return (
<div className="animate-in slide-in-from-right-4 duration-300">
<button onClick={onBack} className="flex items-center gap-2 text-sm text-textMuted hover:text-textMain mb-6 transition-colors group">
<button onClick={() => navigate('/projects')} className="flex items-center gap-2 text-sm text-textMuted hover:text-textMain mb-6 transition-colors group">
<span className="group-hover:-translate-x-1 transition-transform"></span> Zurück zum Verzeichnis
</button>