Host tournaments as unranked Closes #1681

This commit is contained in:
Kalle
2024-03-04 21:36:00 +02:00
parent abd7ac6243
commit 0a82554530
6 changed files with 46 additions and 3 deletions

View File

@@ -386,6 +386,7 @@ export interface TournamentSettings {
bracketProgression: TournamentBracketProgression;
teamsPerGroup?: number;
thirdPlaceMatch?: boolean;
isRanked?: boolean;
}
export interface CastedMatchesInfo {

View File

@@ -386,6 +386,7 @@ type CreateArgs = Pick<
bracketProgression: TournamentSettings["bracketProgression"] | null;
teamsPerGroup?: number;
thirdPlaceMatch?: boolean;
isRanked?: boolean;
};
export async function create(args: CreateArgs) {
return db.transaction().execute(async (trx) => {
@@ -396,6 +397,7 @@ export async function create(args: CreateArgs) {
bracketProgression: args.bracketProgression,
teamsPerGroup: args.teamsPerGroup,
thirdPlaceMatch: args.thirdPlaceMatch,
isRanked: args.isRanked,
};
tournamentId = (
@@ -465,6 +467,7 @@ export async function update(args: UpdateArgs) {
bracketProgression: args.bracketProgression,
teamsPerGroup: args.teamsPerGroup,
thirdPlaceMatch: args.thirdPlaceMatch,
isRanked: args.isRanked,
};
await trx

View File

@@ -70,6 +70,7 @@ export const newCalendarEventActionSchema = z
pool: z.string().optional(),
toToolsEnabled: z.preprocess(checkboxValueToBoolean, z.boolean()),
toToolsMode: z.enum(["ALL", "SZ", "TC", "RM", "CB"]).optional(),
isRanked: z.preprocess(checkboxValueToBoolean, z.boolean().nullish()),
//
// tournament format related fields
//

View File

@@ -117,6 +117,7 @@ export const action: ActionFunction = async ({ request }) => {
bracketProgression: formValuesToBracketProgression(data),
teamsPerGroup: data.teamsPerGroup ?? undefined,
thirdPlaceMatch: data.thirdPlaceMatch ?? undefined,
isRanked: data.isRanked ?? undefined,
};
validate(
!commonArgs.toToolsEnabled || commonArgs.bracketProgression,
@@ -253,6 +254,12 @@ export default function CalendarNewEventPage() {
<DiscordLinkInput />
<TagsAdder />
<BadgesAdder />
{isTournament ? (
<>
<Divider>Tournament settings</Divider>
<RankedToggle />
</>
) : null}
{/* can't edit as participants might have chosen maps and changing this might cause impossible states */}
{isTournament && !eventToEdit ? (
<TournamentMapPickingStyleSelect />
@@ -607,6 +614,33 @@ function BadgesAdder() {
);
}
function RankedToggle() {
const data = useLoaderData<typeof loader>();
const [isRanked, setIsRanked] = React.useState(
data.tournamentCtx?.settings.isRanked ?? true,
);
const id = React.useId();
return (
<div>
<label htmlFor={id}>Ranked</label>
<Toggle
name="isRanked"
id={id}
tiny
checked={isRanked}
setChecked={setIsRanked}
/>
<FormMessage type="info">
Ranked tournaments affect SP. Tournaments that don&apos;t have open
registration (skill capped) or &quot;gimmick tournaments&quot; must
always be hosted as unranked. Any tournament hosted during off-season is
always unranked no matter what is chosen here.
</FormMessage>
</div>
);
}
const mapPickingStyleToShort: Record<
Tables["Tournament"]["mapPickingStyle"],
"ALL" | RankedModeShort
@@ -822,7 +856,7 @@ function TournamentFormatSelector() {
);
return (
<div className="stack md">
<div className="stack md w-full">
<Divider>Tournament format</Divider>
<div>
<Label htmlFor="format">Format</Label>
@@ -866,6 +900,7 @@ function TournamentFormatSelector() {
setChecked={setThirdPlaceMatch}
name="thirdPlaceMatch"
id="thirdPlaceMatch"
tiny
/>
</div>
) : null}

View File

@@ -266,7 +266,10 @@ export class Tournament {
}
get ranked() {
return Boolean(currentSeason(this.ctx.startTime));
const seasonIsActive = Boolean(currentSeason(this.ctx.startTime));
if (!seasonIsActive) return false;
return this.ctx.settings.isRanked ?? true;
}
get logoSrc() {

View File

@@ -140,7 +140,7 @@ export const action: ActionFunction = async ({ params, request }) => {
teams: tournament.ctx.teams,
finalStandings: _finalStandings,
results,
calculateSeasonalStats: typeof season === "number",
calculateSeasonalStats: tournament.ranked,
queryCurrentTeamRating: (identifier) =>
queryCurrentTeamRating({ identifier, season: season! }).rating,
queryCurrentUserRating: (userId) =>