4.5 KiB
4.5 KiB
AI Coding Agent Instructions
Project Overview
Volleyball Team Manager - Eine moderne React-Webapp zur Verwaltung von Volleyball-Teams in zwei vordefinierten Gruppen (Bundesliga & Champions League). Fokus auf hohe Usability und User Experience mit responsivem Design, Animations und intuitiver Bedienung. Lokale Browser-Speicherung via localStorage, kein Backend nötig.
Architecture & Key Components
- Frontend (
src/): React 18 + Vite + Tailwind CSScomponents/: Modulare UI-Components (Header, GroupSection, TeamForm, TeamCard, Toast)hooks/useTeams.js: Custom Hook für localStorage-Management und Team-LogikApp.jsx: Main App mit State & Event-Handlingindex.css: Global Styles mit Tailwind Utilities
- Data Flow: User Input → React State (useTeams hook) → localStorage sync → Component Re-render
- Build: Vite für schnelle Entwicklung mit Hot Module Replacement
- Container: Docker Multi-stage Build (Node builder → nginx production)
Developer Workflows
Local Development
npm install
npm run dev
# http://localhost:5173 mit Hot Reload
Production Build
npm run build # Output: dist/
npm run preview # Test production build lokal
Docker (Production)
docker-compose up --build
# http://localhost:3000
Building Image
docker build -t team-manager .
# Multi-stage: Node build stage (install deps, build) → nginx serve stage
Project Conventions
Code Style
- React: Functional Components mit Hooks (useState, useEffect), keine Class Components
- JavaScript: Modern ES6+, keine async/await nötig (synchrone localStorage)
- CSS: Tailwind CSS Utility-First, keine custom CSS außer in
index.css@layer directives - Naming: camelCase für Functions/Variables, PascalCase für Components
File Organization
src/
├── components/ # Dumb/presentational components
├── hooks/ # Custom hooks (state logic)
├── App.jsx # Container component
├── main.jsx # Vite entry point
└── index.css # Global styles + Tailwind
Component Pattern
// src/components/MyComponent.jsx
export default function MyComponent({ prop1, onEvent }) {
const [state, setState] = useState()
return (
<div className="...">
{/* JSX */}
</div>
)
}
Data Pattern: useTeams Hook
// In any component
const { teams, addTeam, deleteTeam, resetAll } = useTeams()
// teams structure: { bundesliga: [{id, name, chant, createdAt}], championsleague: [...] }
// Alle Änderungen auto-persist zu localStorage
Tailwind + Custom Components
Häufige Klassen im @layer components in index.css:
.btn-primary,.btn-danger,.btn-sm.input-field.cardfür weiße Boxes mit Shadow
Integration Points
- Tailwind CSS: Konfiguriert in
tailwind.config.jsmit custom colors (primary #667eea, secondary #764ba2) - PostCSS: Auto-processing für Tailwind in
postcss.config.js - localStorage API:
useTeamshook handelt alle Read/Write (key: 'teamManagerData') - Vite: Schneller dev server + production build optimizer
- Docker: Node:20-alpine build + nginx:alpine serve (optimierte Layer)
Common Patterns
Team hinzufügen (Form → Hook)
- TeamForm mit Name/Chant-Inputs (mit Validation)
- onSubmit ruft
addTeam(group, name, chant)auf - Hook erstellt Team-Objekt (id=timestamp, createdAt)
- setState → localStorage.setItem('teamManagerData', JSON.stringify(newTeams))
- Component re-render mit aktualisierten teams
Error Handling & Validation
- Form-Validierung in TeamForm (nicht leer, max length)
- Error-Messages inline unter Inputs anzeigen
- Toast für Bestätigungen (success/error/info)
- Try-catch in useTeams.loadData() für corrupted localStorage
Toast Notifications
const [toast, setToast] = useState(null)
showToast('Message', 'success') // success|error|info
// Toast auto-dismissed nach 3s
Animations
Tailwind animate-* in tailwind.config.js definiert:
.animate-fade-in→ opacity transition.animate-slide-in/down/up→ transform transitions- Auf Components anwenden:
className="animate-fade-in"
When You're Stuck
- Check
src/hooks/useTeams.jsfür localStorage pattern - Check
src/components/für Best-Practice Component-Struktur (Props, Event Handlers) - Tailwind docs für Styling (keine custom CSS nötig!)
README.mdfür Commands & Architecture Übersicht- Browser DevTools → Application → localStorage um 'teamManagerData' zu inspizieren