235 lines
7.6 KiB
TypeScript
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;
|