package seasonsview import "git.haelnorr.com/h/oslstats/internal/db" import "git.haelnorr.com/h/oslstats/internal/permissions" import "git.haelnorr.com/h/oslstats/internal/contexts" import "git.haelnorr.com/h/oslstats/internal/view/baseview" import "fmt" import "time" func formatScheduleTime(t *time.Time) string { if t == nil { return "No time set" } return t.Format("Mon 2 Jan 2006 at 3:04 PM") } func formatHistoryTime(unix int64) string { return time.Unix(unix, 0).Format("2 Jan 2006 15:04") } templ FixtureDetailPage( fixture *db.Fixture, currentSchedule *db.FixtureSchedule, history []*db.FixtureSchedule, canSchedule bool, userTeamID int, ) { {{ permCache := contexts.Permissions(ctx) canManage := permCache.HasPermission(permissions.FixturesManage) backURL := fmt.Sprintf("/seasons/%s/leagues/%s/fixtures", fixture.Season.ShortName, fixture.League.ShortName) }} @baseview.Layout(fmt.Sprintf("%s vs %s", fixture.HomeTeam.Name, fixture.AwayTeam.Name)) {

{ fixture.HomeTeam.Name } vs { fixture.AwayTeam.Name }

Round { fmt.Sprint(fixture.Round) } if fixture.GameWeek != nil { Game Week { fmt.Sprint(*fixture.GameWeek) } } { fixture.Season.Name } β€” { fixture.League.Name }
Back to Fixtures
@fixtureScheduleStatus(fixture, currentSchedule, canSchedule, canManage, userTeamID) @fixtureScheduleActions(fixture, currentSchedule, canSchedule, canManage, userTeamID) @fixtureScheduleHistory(fixture, history)
} } templ fixtureScheduleStatus( fixture *db.Fixture, current *db.FixtureSchedule, canSchedule bool, canManage bool, userTeamID int, ) {

Schedule Status

if current == nil {
πŸ“…

No time scheduled

if canSchedule { Use the form to propose a time for this fixture. } else { A team manager needs to propose a time for this fixture. }

} else if current.Status == db.ScheduleStatusPending && current.ScheduledTime != nil {
⏳

Proposed: { formatScheduleTime(current.ScheduledTime) }

Proposed by { current.ProposedBy.Name } β€” awaiting response from the other team

if canSchedule && userTeamID != current.ProposedByTeamID {
} if canSchedule && userTeamID == current.ProposedByTeamID {
}
} else if current.Status == db.ScheduleStatusAccepted {
βœ…

Confirmed: { formatScheduleTime(current.ScheduledTime) }

Both teams have agreed on this time.

} else if current.Status == db.ScheduleStatusRejected {
❌

Proposal Rejected

The proposed time was rejected. A new time needs to be proposed.

} else if current.Status == db.ScheduleStatusCancelled {
🚫

Fixture Forfeited

if current.RescheduleReason != nil {

{ *current.RescheduleReason }

}
} else if current.Status == db.ScheduleStatusRescheduled {
πŸ”„

Rescheduled

if current.RescheduleReason != nil {

Reason: { *current.RescheduleReason }

}

A new time needs to be proposed.

} else if current.Status == db.ScheduleStatusPostponed {
⏸️

Postponed

if current.RescheduleReason != nil {

Reason: { *current.RescheduleReason }

}

A new time needs to be proposed.

} else if current.Status == db.ScheduleStatusWithdrawn {
↩️

Proposal Withdrawn

The proposed time was withdrawn. A new time needs to be proposed.

}
} templ fixtureScheduleActions( fixture *db.Fixture, current *db.FixtureSchedule, canSchedule bool, canManage bool, userTeamID int, ) { {{ // Determine what actions are available showPropose := false showReschedule := false showPostpone := false showCancel := false if canSchedule { if current == nil { showPropose = true } else if current.Status == db.ScheduleStatusRejected { showPropose = true } else if current.Status == db.ScheduleStatusRescheduled { showPropose = true } else if current.Status == db.ScheduleStatusPostponed { showPropose = true } else if current.Status == db.ScheduleStatusWithdrawn { showPropose = true } else if current.Status == db.ScheduleStatusAccepted { showReschedule = true showPostpone = true } } if canManage && current != nil && !current.Status.IsTerminal() { showCancel = true } }} if showPropose || showReschedule || showPostpone || showCancel {
if showPropose {

Propose Time

} if showReschedule {

Reschedule

@rescheduleReasonSelect(fixture)
} if showPostpone {

Postpone

@rescheduleReasonSelect(fixture)
} if showCancel {

Declare Forfeit

This action is irreversible. Declaring a forfeit will permanently cancel the fixture schedule.

@forfeitReasonSelect(fixture)
}
} else { if !canSchedule && !canManage {

Only team managers can manage fixture scheduling.

} } } templ forfeitReasonSelect(fixture *db.Fixture) { } templ rescheduleReasonSelect(fixture *db.Fixture) { } templ fixtureScheduleHistory(fixture *db.Fixture, history []*db.FixtureSchedule) {

Schedule History

if len(history) == 0 {

No scheduling activity yet.

} else {
for i := len(history) - 1; i >= 0; i-- { @scheduleHistoryItem(history[i], i == len(history)-1) }
}
} templ scheduleHistoryItem(schedule *db.FixtureSchedule, isCurrent bool) { {{ statusColor := "text-subtext0" statusBg := "bg-surface1" statusLabel := string(schedule.Status) switch schedule.Status { case db.ScheduleStatusPending: statusColor = "text-blue" statusBg = "bg-blue/20" statusLabel = "Pending" case db.ScheduleStatusAccepted: statusColor = "text-green" statusBg = "bg-green/20" statusLabel = "Accepted" case db.ScheduleStatusRejected: statusColor = "text-red" statusBg = "bg-red/20" statusLabel = "Rejected" case db.ScheduleStatusRescheduled: statusColor = "text-yellow" statusBg = "bg-yellow/20" statusLabel = "Rescheduled" case db.ScheduleStatusPostponed: statusColor = "text-peach" statusBg = "bg-peach/20" statusLabel = "Postponed" case db.ScheduleStatusCancelled: statusColor = "text-red" statusBg = "bg-red/20" statusLabel = "Cancelled" case db.ScheduleStatusWithdrawn: statusColor = "text-subtext0" statusBg = "bg-surface1" statusLabel = "Withdrawn" } }}
if isCurrent { CURRENT } { statusLabel }
{ formatHistoryTime(schedule.CreatedAt) }
Proposed by: { schedule.ProposedBy.Name }
if schedule.ScheduledTime != nil {
Time: { formatScheduleTime(schedule.ScheduledTime) }
} else {
Time: No time set
} if schedule.AcceptedBy != nil {
Accepted by: { schedule.AcceptedBy.Name }
} if schedule.RescheduleReason != nil {
Reason: { *schedule.RescheduleReason }
}
}