diff --git a/backend/server.js b/backend/server.js index 56cf7b1..35d4d6c 100644 --- a/backend/server.js +++ b/backend/server.js @@ -18,6 +18,11 @@ const CALLBACK_URL = process.env.CALLBACK_URL || 'http://localhost:3000/auth/dis const FRONTEND_URL = process.env.FRONTEND_URL || 'http://localhost:8000'; const BACKEND_URL = process.env.BACKEND_URL || 'https://vollidioten.ceraticsoft.de'; +// CORS configuration - allow multiple origins for development +const corsOrigins = process.env.NODE_ENV === 'production' + ? [FRONTEND_URL] + : [FRONTEND_URL, 'http://localhost:3000', 'http://localhost:8000', 'http://127.0.0.1:3000']; + // File upload configuration const UPLOAD_DIR = path.join(__dirname, 'uploads'); if (!fs.existsSync(UPLOAD_DIR)) { @@ -55,7 +60,7 @@ init(); // Initialize DB // Middleware app.use(express.json()); -app.use(cors({ origin: FRONTEND_URL, credentials: true })); +app.use(cors({ origin: corsOrigins, credentials: true })); app.use(session({ secret: process.env.SESSION_SECRET || 'dev_secret', resave: false, diff --git a/components/Layout.tsx b/components/Layout.tsx index b70f18d..b25e7fe 100644 --- a/components/Layout.tsx +++ b/components/Layout.tsx @@ -72,21 +72,23 @@ const Layout: React.FC = ({ children, activeTab, onNavigate }) => {
- - - + + + )} {/* Mobile Menu Toggle */} -
)} - {activeTab === 'npcs' && ( -
- {/* NPC Citizens */} -
-

- - NPC-Bürger ({npcs.citizens.length}) -

- - {loading ? ( -
-
-
- ) : npcs.citizens.length === 0 ? ( -

Keine NPC-Bürger vorhanden.

- ) : ( -
- {npcs.citizens.map((citizen: any) => ( -
-
-
- NPC -
-
-

{citizen.username}

-

{citizen.stats.role}

-
-
-
- Level {citizen.stats.level} • {citizen.stats.playtimeHours}h Spielzeit -
-
- ))} -
- )} -
- - {/* NPC Companies */} -
-

- - NPC-Firmen ({npcs.companies.length}) -

- - {npcs.companies.length === 0 ? ( -

Keine NPC-Firmen vorhanden.

- ) : ( -
- {npcs.companies.map((company: any) => ( -
-
-

{company.title}

- - {company.category} - -
-

{company.description}

-
- Eigentümer: {company.owner} • Gegründet: {company.foundedDate} -
- {company.shopCatalog && company.shopCatalog.length > 0 && ( -
- Shop: {company.shopCatalog.length} Artikel -
- )} -
- ))} -
- )} -
-
- )} - {activeTab === 'edit-npcs' && (
{/* Edit NPC Citizens */} diff --git a/pages/PlayerProfile.tsx b/pages/PlayerProfile.tsx index 2b97a5b..c18e0a7 100644 --- a/pages/PlayerProfile.tsx +++ b/pages/PlayerProfile.tsx @@ -19,6 +19,7 @@ const PlayerProfile: React.FC = () => { const [isEditOrgOpen, setIsEditOrgOpen] = useState(false); const [ownedProjects, setOwnedProjects] = useState([]); const [loading, setLoading] = useState(true); + const [activeTab, setActiveTab] = useState<'story' | 'stats' | 'projects'>('story'); // Is this the logged-in user's profile? const isOwner = currentUser?.linkedPlayerUuid === player?.uuid; @@ -140,7 +141,7 @@ const PlayerProfile: React.FC = () => { console.log(player); return ( -
+
-
{player.stats?.role || 'Unbekannt'}
+
{player.minecraftStats?.role || 'Unbekannt'}
{playerOrg ? ( {playerOrg.name} @@ -275,72 +276,205 @@ const PlayerProfile: React.FC = () => {
- {/* Right Col: Story & Projects */} -
- {/* Story Section */} -
-
-

- Charakter-Journal -

-
- Markdown - {isOwner && ( - - )} -
+ {/* Right Col: Tabs */} +
+ {/* Tab Navigation */} +
+
+ + {player.minecraftStats && ( + + )} + {ownedProjects.length > 0 && ( + + )}
-
- {renderMarkdown(player.storyMarkdown || '')} -
-
- {/* Owned Projects Section */} - {ownedProjects.length > 0 && ( -
-

- - Unternehmen & Projekte ({ownedProjects.length}) -

-
- {ownedProjects.map((project) => ( -
-
-

{project.title}

- - {project.category} - -
-

{project.description}

-
- Gegründet: {project.foundedDate} -
- {project.shopCatalog && project.shopCatalog.length > 0 && ( - - - Shop ({project.shopCatalog.length}) - - )} - - - {project.employees.length + 1} - -
+ {/* Tab Content */} +
+ {activeTab === 'story' && ( +
+
+
+ Markdown + {isOwner && ( + + )}
- ))} -
+
+ {renderMarkdown(player.storyMarkdown || '')} +
+
+ )} + + {activeTab === 'stats' && player.minecraftStats && ( +
+ {/* Last Sync */} +
+
Letzte Synchronisation
+
+ {new Date(player.minecraftStats.lastSync).toLocaleString('de-DE', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + })} +
+
+ + {/* Statistics */} + {player.minecraftStats.statistics && ( +
+ {/* General Stats */} + {player.minecraftStats.statistics.general && Object.keys(player.minecraftStats.statistics.general).length > 0 && ( +
+

Allgemein

+
+ {Object.entries(player.minecraftStats.statistics.general) + .sort(([, a], [, b]) => (b as number) - (a as number)) + .map(([key, value]) => ( +
+ {key.replace('minecraft:', '')} + {value.toLocaleString()} +
+ ))} +
+
+ )} + + {/* Kills */} + {player.minecraftStats.statistics.kills && Object.keys(player.minecraftStats.statistics.kills).length > 0 && ( +
+

Kills

+
+ {Object.entries(player.minecraftStats.statistics.kills) + .sort(([, a], [, b]) => (b as number) - (a as number)) + .map(([key, value]) => ( +
+ {key.replace('minecraft:', '')} + {value} +
+ ))} +
+
+ )} + + {/* Killed By */} + {player.minecraftStats.statistics.killed_by && Object.keys(player.minecraftStats.statistics.killed_by).length > 0 && ( +
+

Gestorben durch

+
+ {Object.entries(player.minecraftStats.statistics.killed_by) + .sort(([, a], [, b]) => (b as number) - (a as number)) + .map(([key, value]) => ( +
+ {key.replace('minecraft:', '')} + {value} +
+ ))} +
+
+ )} +
+ )} + + {/* Advancements */} + {player.minecraftStats.advancements && player.minecraftStats.advancements.length > 0 && ( +
+

Erfolge ({player.minecraftStats.advancements.length})

+
+ {player.minecraftStats.advancements.map((advancement) => ( +
+
{advancement.title}
+
{advancement.id.replace('minecraft:', '')}
+
+ ))} +
+
+ )} +
+ )} + + {activeTab === 'projects' && ownedProjects.length > 0 && ( +
+
+ {ownedProjects.map((project) => ( +
+
+

{project.title}

+ + {project.category} + +
+

+ {project.description.split(' ').length > 50 + ? project.description.split(' ').slice(0, 50).join(' ') + '...' + : project.description} +

+
+ Gegründet: {project.foundedDate} +
+ {project.shopCatalog && project.shopCatalog.length > 0 && ( + + + Shop ({project.shopCatalog.length}) + + )} + + + {project.employees.length + 1} + +
+
+
+ ))} +
+
+ )}
- )} +
diff --git a/pages/Projects.tsx b/pages/Projects.tsx index a912269..1af265d 100644 --- a/pages/Projects.tsx +++ b/pages/Projects.tsx @@ -86,7 +86,9 @@ const VentureCard = ({ project, onClick }: { project: Project, onClick?: () => v

- {project.description} + {project.description.split(' ').length > 50 + ? project.description.split(' ').slice(0, 50).join(' ') + '...' + : project.description}