diff --git a/backend/app/crud.py b/backend/app/crud.py index 3866ac4..647229d 100644 --- a/backend/app/crud.py +++ b/backend/app/crud.py @@ -2,7 +2,7 @@ from uuid import uuid4 from sqlalchemy.orm import Session, joinedload -from fastapi import HTTPException # <--- Add this at the top with your imports +from fastapi import HTTPException from . import logic, models, schemas @@ -28,7 +28,12 @@ def create_tournament(db: Session, data: schemas.TournamentCreate): duration=data.duration, type=data.type, ) - new_t.teams = [models.Team(name=n) for n in data.teams] + + new_t.teams = [ + models.Team(name=nt.name, dropped_out=nt.dropped_out) + for nt in data.teams + ] + new_t.courts = db.query(models.Court).filter(models.Court.id.in_(data.courts)).all() db.add(new_t) @@ -160,9 +165,15 @@ def update_tournament_teams(db: Session, tournament_id: str, new_teams: list[sch db.delete(team) db.flush() - t.teams = [models.Team(name=nt.name, tournament_id=t.id) for nt in new_teams] + t.teams = [ + models.Team(name=nt.name, tournament_id=t.id, dropped_out=nt.dropped_out) + for nt in new_teams + ] db.flush() _rebuild_structure(db, t) + for m in t.matches: + logic.check_and_apply_walkover(db, m) + db.commit() db.refresh(t) return t diff --git a/backend/app/logic.py b/backend/app/logic.py index fab8708..24003f0 100644 --- a/backend/app/logic.py +++ b/backend/app/logic.py @@ -148,14 +148,34 @@ def update_schedule_times(db: Session, t: models.Tournament): court_timers = {c.id: start_of_day for c in all_courts} planned_finish_times = {} unscheduled: list[models.Match] = [] + tournament_has_started = { + t_item.id: any(m.status == MatchStatus.FINISHED for m in t_item.matches) + for t_item in tournaments + } for m in all_matches: + is_locked = False + t_started = tournament_has_started[m.tournament_id] + if m.status == MatchStatus.FINISHED and m.start_time and m.court_id: + is_locked = True + + elif m.status == MatchStatus.PENDING and m.start_time and m.court_id: + if t_started: + is_locked = True + + elif m.tournament_id != t.id and m.start_time and m.court_id: + if t_started: + is_locked = True + + if is_locked and m.start_time and m.court_id: fin = m.start_time + timedelta(minutes=m.tournament.duration) planned_finish_times[m.id] = fin if court_timers.get(m.court_id, start_of_day) < fin: court_timers[m.court_id] = fin else: + m.start_time = None + m.court_id = None unscheduled.append(m) tournament_match_counts = {t_item.id: 0 for t_item in tournaments} diff --git a/backend/app/schemas.py b/backend/app/schemas.py index a3bfad0..9194086 100644 --- a/backend/app/schemas.py +++ b/backend/app/schemas.py @@ -13,7 +13,7 @@ class TeamSchema(BaseModel): model_config = ConfigDict(from_attributes=True) class TeamUpdate(BaseModel): - id: int + id: int | str name: str dropped_out: bool = False @@ -76,7 +76,7 @@ class TournamentCreate(BaseModel): type: TournamentTypes timestamp: datetime duration: int - teams: list[str] + teams: list[TeamUpdate] courts: list[int] diff --git a/frontend/src/components/Forms/TournamentForm.tsx b/frontend/src/components/Forms/TournamentForm.tsx index 205703f..aaa33a8 100644 --- a/frontend/src/components/Forms/TournamentForm.tsx +++ b/frontend/src/components/Forms/TournamentForm.tsx @@ -169,7 +169,20 @@ export default function TournamentForm({ tournamentId, onSuccess, onDelete }: To onSuccess(); } catch (err: any) { console.error("Save error:", err); - const msg = err?.response?.data?.detail || err?.detail || err?.message || "An error occurred while saving."; + let msg = "An error occurred while saving."; + if (err?.response?.data?.detail) { + const detail = err.response.data.detail; + if (Array.isArray(detail)) { + msg = detail.map((d: any) => `${d.loc[d.loc.length - 1]}: ${d.msg}`).join(' | '); + } else if (typeof detail === 'string') { + msg = detail; + } else { + msg = JSON.stringify(detail); + } + } else if (err?.message) { + msg = err.message; + } + setError(msg); } finally { setIsSubmitting(false); @@ -292,26 +305,43 @@ export default function TournamentForm({ tournamentId, onSuccess, onDelete }: To }`} /> - {hasStarted ? ( - - ) : ( - - )} +