Files
Volleyball/frontend/src/pages/Teams.tsx
2025-11-28 14:31:12 +01:00

235 lines
7.6 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { getUserFromToken } from '../components/utils/jwt';
import { fetchTeams } from './api';
interface Team {
UUID: string;
Name: string;
Players: string[];
OwnerUUID: string;
Description: string
}
const TeamManagement: React.FC = () => {
const [teams, setTeams] = useState<Team[]>([]);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [error, setError] = useState('');
const [editingTeam, setEditingTeam] = useState<Team | null>(null);
const [selectedTeam, setSelectedTeam] = useState<Team | null>(null);
const token = localStorage.getItem('token');
const user = token ? getUserFromToken(token) : null;
const isAdmin = user?.role?.includes('admin');
const API_URL = 'http://localhost:8080/api';
useEffect(() => {
load();
}, [token]); // Add token as dependency
async function load() {
if (!token) return;
try {
const data = await fetchTeams(token);
// console.log("Geladene Teams:", data);
if (data) {
setTeams(data);
}
} catch (error) {
// console.error("Fehler beim Laden der Teams:", error);
setError('Fehler beim Laden der Teams');
}
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!user?.email) {
setError('User email not found. Please log in again.');
return;
}
const body = {
name,
description: description,
owneruuid: user.userId,
};
const method = editingTeam ? 'PUT' : 'POST';
const url = editingTeam ? `/teams/${editingTeam.UUID}` : '/teams';
try {
const res = await fetch(API_URL+url, {
method,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(body),
});
const data = await res.json();
console.log("Response data:", data);
if (res.ok) {
handleCreateNewClick(); // Reset form state
load(); // Reload teams
} else {
setError(data.error || 'Fehler beim Speichern');
}
} catch (err) {
setError('Ein Netzwerkfehler ist aufgetreten.');
}
};
const handleDelete = async (id: string) => {
if (!window.confirm("Are you sure you want to delete this team?")) return;
try {
const res = await fetch(`/api/teams/${id}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${token}` },
});
if (res.ok) {
handleCreateNewClick(); // Reset form
load(); // Refresh list
} else {
const data = await res.json();
setError(data.error || 'Löschen fehlgeschlagen');
}
} catch (err) {
setError('Ein Netzwerkfehler ist aufgetreten.');
}
};
const canDelete = (team: Team) => isAdmin || team.OwnerUUID === user?.userId;
const canCreate = () => isAdmin || true;
const handleSelectTeam = (team: Team) => {
setSelectedTeam(team);
setEditingTeam(team);
setName(team.Name);
setDescription(team.Description);
const currentUserEmail = user?.email;
// description(otherPlayer || '');
};
const handleCreateNewClick = () => {
setSelectedTeam(null);
setEditingTeam(null);
setName('');
setDescription('');
setError('');
};
// const myTeams = teams;
const myTeams = teams.filter(team =>
team.OwnerUUID === user?.userId || (user?.email && team.Players.includes(user.email))
);
// console.log("meine teams ", myTeams);
return (
<div className="max-w-4xl mx-auto p-6 bg-white rounded-xl shadow-md mt-6">
<h2 className="text-2xl font-bold mb-4">Team Management</h2>
{error && <p className="text-red-500 bg-red-100 p-3 rounded mb-4">{error}</p>}
<div className="mb-6">
<h3 className="text-xl font-semibold mb-2">Meine Teams</h3>
<div className="flex flex-wrap gap-2">
{myTeams.map((team) => (
<button
key={team.UUID}
onClick={() => handleSelectTeam(team)}
className={`px-4 py-2 rounded-lg text-sm font-medium
${selectedTeam?.UUID === team.UUID
? 'bg-blue-600 text-white shadow-lg'
: 'bg-gray-200 text-gray-800 hover:bg-gray-300'
}`}
>
{team.Name}
</button>
))}
</div>
</div>
<div className="mb-6">
{canCreate() && (
<button
onClick={handleCreateNewClick}
className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600"
>
Neues Team erstellen
</button>
)}
</div>
<hr className="my-6"/>
<div>
{!editingTeam && !selectedTeam && (
<h3 className="text-xl font-semibold mb-4">Neues Team erstellen</h3>
)}
{editingTeam && (
<h3 className="text-xl font-semibold mb-4">Team ansehen/bearbeiten: {editingTeam.Name}</h3>
)}
{/* Form for creating or editing a team */}
{(!selectedTeam && canCreate()) || editingTeam ? (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="teamname" className="block text-sm font-medium text-gray-700">Teamname</label>
<input
id="teamname"
className="mt-1 block w-full border p-2 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
type="text"
placeholder="Teamname"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<div>
<label htmlFor="description" className="block text-sm font-medium text-gray-700">Beschreibung</label>
<input
id="description"
className="mt-1 block w-full border p-2 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
type="text"
placeholder="Beschreibung"
value={description}
onChange={(e) => setDescription(e.target.value)}
// required={!isAdmin} // Admin can create single-player teams maybe?
/>
</div>
<div className="flex items-center gap-4">
<button type="submit"
className="bg-blue-600 text-white px-6 py-2 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
>
{editingTeam ? 'Aktualisieren' : 'Erstellen'}
</button>
{editingTeam && canDelete(editingTeam) && (
<button
type="button"
onClick={() => handleDelete(editingTeam.UUID)}
className="bg-red-600 text-white px-6 py-2 rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
>
Löschen
</button>
)}
</div>
</form>
) : (
<p className="text-gray-500">Wähle ein Team aus der Liste oben aus, um es zu bearbeiten, oder erstelle ein neues Team.</p>
)}
</div>
</div>
);
};
export default TeamManagement;