mirror of
https://github.com/ceratic/project_vollidioten_website.git
synced 2026-05-14 00:16:47 +02:00
feat: Initialize project with Vite, React, and TypeScript
Sets up the foundational structure for the Obsidian | RP Plattform. This includes configuring Vite as the build tool, integrating React for the UI, and establishing TypeScript for type safety. Also includes initial styling and placeholder data to define the application's core interfaces.
This commit is contained in:
75
pages/Cities.tsx
Normal file
75
pages/Cities.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import React from 'react';
|
||||
import { MOCK_ORGS } from '../constants';
|
||||
import { Organization } from '../types';
|
||||
import { Icons } from '../components/IconSet';
|
||||
|
||||
interface CitiesProps {
|
||||
onSelectCity: (id: string) => void;
|
||||
}
|
||||
|
||||
const CityCard = ({ city, onClick }: { city: Organization; onClick: () => void }) => (
|
||||
<div
|
||||
onClick={onClick}
|
||||
className="group relative h-64 rounded-2xl overflow-hidden cursor-pointer border border-border hover:border-accentInfo/50 transition-all duration-300 shadow-card"
|
||||
>
|
||||
{/* Background Image */}
|
||||
<div className="absolute inset-0">
|
||||
<img
|
||||
src={city.bannerUrl || 'https://via.placeholder.com/800x400'}
|
||||
alt={city.name}
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-background via-background/60 to-transparent" />
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="absolute inset-0 p-6 flex flex-col justify-end">
|
||||
<div className="flex justify-between items-end">
|
||||
<div>
|
||||
<div className="text-xs font-bold text-accentInfo mb-1 uppercase tracking-widest">{city.establishedYear || 'Unbekannte Ära'}</div>
|
||||
<h2 className="text-3xl font-bold text-white mb-2 group-hover:translate-x-1 transition-transform">{city.name}</h2>
|
||||
<p className="text-sm text-gray-300 line-clamp-2 max-w-sm">
|
||||
{city.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-end gap-2">
|
||||
<div className="flex items-center gap-2 px-3 py-1 bg-black/40 backdrop-blur rounded-full border border-white/10">
|
||||
<Icons.Users className="w-4 h-4 text-textMuted" />
|
||||
<span className="text-sm font-medium text-white">{city.memberCount} Bürger</span>
|
||||
</div>
|
||||
<div className="px-3 py-1 bg-accentInfo/20 backdrop-blur rounded-full border border-accentInfo/30 text-xs font-bold text-accentInfo uppercase">
|
||||
{city.status}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const Cities: React.FC<CitiesProps> = ({ onSelectCity }) => {
|
||||
const cities = MOCK_ORGS.filter(org => org.type === 'City');
|
||||
|
||||
return (
|
||||
<div className="animate-in fade-in slide-in-from-bottom-2 space-y-8">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold mb-1">Große Siedlungen</h1>
|
||||
<p className="text-textMuted">Entdecke die blühenden Zentren der Zivilisation im Obsidian-Tal.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-6">
|
||||
{cities.map(city => (
|
||||
<CityCard key={city.id} city={city} onClick={() => onSelectCity(city.id)} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{cities.length === 0 && (
|
||||
<div className="text-center py-20 text-textMuted">
|
||||
<p>Noch keine Städte gegründet.</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Cities;
|
||||
Reference in New Issue
Block a user