mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-07-16 08:27:05 -05:00
* Add DB tables
* Toggle TO Tools in new calendar event page
* TO tools page initial
* Add counter pick map pool UI
* Save tie breaker map pool
* Save team name
* Layout initial
* Load users own team
* Make team name input required
* Rename team
* Divide to sections
* Submit team map pool
* New style for counter pick map pool section expand
* Fix tiebreaker map pool not saved when new event made
* Split to many forms
* According for team name
* Small UI consistency tweaks
* Add explanation to tie breaker maps
* Remove redundant prop
* Fix new calendar event todos
* Use required hidden input component in new build page
* Fix to tools page showing even when toToolsEnabled = 0
* Delete team
* Map list generation tests initial
* Add tournament map list generation tests
* First version of map list generation
* Add seeded RNG
* Rearrange files
* Generation with strats initial
* Default map pool + allow one team not to have any maps
* Implement map generation via backtracking
* Make order of stages irrelevant
* Add one more TODO
* Seed
* Fixes
* Tournament map list generator initial
* More functional maplist
* Fix any
* Persist in search params initial
* Add date to calendar seed
* Revert "Persist in search params initial"
This reverts commit f01a9e6982.
* Allow admin to start tournament
* Rate maplist instead of optimal / suboptimal
* Add fallback if map list generation errors out
* Hide TO Tools if not admin
* Submit team roster and delete members
* Teams page
* Give roster s p a c e
* Clear user combobox on sent + layout tweaks
* Gracefully handle updating after tournament has started
* Add title
* Persist map list in search params
* Add i18n
151 lines
5.5 KiB
TypeScript
151 lines
5.5 KiB
TypeScript
import slugify from "slugify";
|
|
import type {
|
|
Badge,
|
|
CalendarEvent,
|
|
GearType,
|
|
MapPoolMap,
|
|
User,
|
|
} from "~/db/types";
|
|
import type { ModeShort, weaponCategories } from "~/modules/in-game-lists";
|
|
import type {
|
|
Ability,
|
|
AbilityWithUnknown,
|
|
MainWeaponId,
|
|
SpecialWeaponId,
|
|
StageId,
|
|
SubWeaponId,
|
|
} from "~/modules/in-game-lists/types";
|
|
import type navItems from "~/components/layout/nav-items.json";
|
|
import { type AuthErrorCode } from "~/modules/auth";
|
|
|
|
export const SPLATOON_2_SENDOU_IN_URL = "https://spl2.sendou.ink";
|
|
export const PLUS_SERVER_DISCORD_URL = "https://discord.gg/FW4dKrY";
|
|
export const SENDOU_INK_DISCORD_URL = "https://discord.gg/sendou";
|
|
export const SENDOU_TWITTER_URL = "https://twitter.com/sendouc";
|
|
export const SENDOU_INK_TWITTER_URL = "https://twitter.com/sendouink";
|
|
export const SENDOU_INK_PATREON_URL = "https://patreon.com/sendou";
|
|
export const SENDOU_INK_GITHUB_URL = "https://github.com/Sendouc/sendou.ink";
|
|
export const GITHUB_CONTRIBUTORS_URL =
|
|
"https://github.com/Sendouc/sendou.ink/graphs/contributors";
|
|
export const BORZOIC_TWITTER = "https://twitter.com/borzoic_";
|
|
export const LEAN_TWITTER = "https://twitter.com/LeanYoshi";
|
|
export const UBERU_TWITTER = "https://twitter.com/uberu5";
|
|
export const ipLabsMaps = (pool: string) =>
|
|
`https://maps.iplabs.ink/?3&pool=${pool}`;
|
|
|
|
export const LOG_IN_URL = "/auth";
|
|
export const LOG_OUT_URL = "/auth/logout";
|
|
export const ADMIN_PAGE = "/admin";
|
|
export const ARTICLES_MAIN_PAGE = "/a";
|
|
export const FAQ_PAGE = "/faq";
|
|
export const CONTRIBUTIONS_PAGE = "/contributions";
|
|
export const BADGES_PAGE = "/badges";
|
|
export const BUILDS_PAGE = "/builds";
|
|
export const CALENDAR_PAGE = "/calendar";
|
|
export const STOP_IMPERSONATING_URL = "/auth/impersonate/stop";
|
|
export const SEED_URL = "/seed";
|
|
|
|
export const COMMON_PREVIEW_IMAGE = "/img/layout/common-preview.png";
|
|
export const ERROR_GIRL_IMAGE_PATH = `/img/layout/error-girl`;
|
|
export const LOGO_PATH = `/img/layout/logo`;
|
|
|
|
export const GET_ALL_USERS_ROUTE = "/users";
|
|
export const GET_ALL_EVENTS_WITH_MAP_POOLS_ROUTE = "/calendar/map-pool-events";
|
|
|
|
interface UserLinkArgs {
|
|
discordId: User["discordId"];
|
|
customUrl?: User["customUrl"];
|
|
}
|
|
|
|
export const userPage = (user: UserLinkArgs) =>
|
|
`/u/${user.customUrl ?? user.discordId}`;
|
|
export const userEditProfilePage = (user: UserLinkArgs) =>
|
|
`${userPage(user)}/edit`;
|
|
export const userBuildsPage = (user: UserLinkArgs) =>
|
|
`${userPage(user)}/builds`;
|
|
export const userResultsPage = (user: UserLinkArgs) =>
|
|
`${userPage(user)}/results`;
|
|
export const userResultsEditHighlightsPage = (user: UserLinkArgs) =>
|
|
`${userResultsPage(user)}/highlights`;
|
|
export const userNewBuildPage = (user: UserLinkArgs) =>
|
|
`${userBuildsPage(user)}/new`;
|
|
|
|
export const authErrorUrl = (errorCode: AuthErrorCode) =>
|
|
`/?authError=${errorCode}`;
|
|
export const impersonateUrl = (idToLogInAs: number) =>
|
|
`/auth/impersonate?id=${idToLogInAs}`;
|
|
export const badgePage = (badgeId: number) => `${BADGES_PAGE}/${badgeId}`;
|
|
export const plusSuggestionPage = (tier?: string | number) =>
|
|
`/plus/suggestions${tier ? `?tier=${tier}` : ""}`;
|
|
|
|
export const calendarEventPage = (eventId: number) => `/calendar/${eventId}`;
|
|
export const calendarEditPage = (eventId?: number) =>
|
|
`/calendar/new${eventId ? `?eventId=${eventId}` : ""}`;
|
|
export const calendarReportWinnersPage = (eventId: number) =>
|
|
`/calendar/${eventId}/report-winners`;
|
|
export const toToolsPage = (eventId: number) => `/to/${eventId}`;
|
|
|
|
export const mapsPage = (eventId?: MapPoolMap["calendarEventId"]) =>
|
|
`/maps${eventId ? `?eventId=${eventId}` : ""}`;
|
|
export const readonlyMapsPage = (eventId: CalendarEvent["id"]) =>
|
|
`/maps?readonly&eventId=${eventId}`;
|
|
export const articlePage = (slug: string) => `${ARTICLES_MAIN_PAGE}/${slug}`;
|
|
export const analyzerPage = (args?: {
|
|
weaponId: MainWeaponId;
|
|
abilities: Ability[];
|
|
}) =>
|
|
`/analyzer${
|
|
args
|
|
? `?weapon=${args.weaponId}&build=${encodeURIComponent(
|
|
args.abilities.join(",")
|
|
)}`
|
|
: ""
|
|
}`;
|
|
export const objectDamageCalculatorPage = (weaponId?: MainWeaponId) =>
|
|
`/object-damage-calculator${
|
|
typeof weaponId === "number" ? `?weapon=${weaponId}` : ""
|
|
}`;
|
|
|
|
export const badgeUrl = ({
|
|
code,
|
|
extension,
|
|
}: {
|
|
code: Badge["code"];
|
|
extension?: "gif";
|
|
}) => `/badges/${code}${extension ? `.${extension}` : ""}`;
|
|
export const articlePreviewUrl = (slug: string) =>
|
|
`/img/article-previews/${slug}.png`;
|
|
|
|
export const navIconUrl = (navItem: typeof navItems[number]["name"]) =>
|
|
`/img/layout/${navItem}`;
|
|
export const gearImageUrl = (gearType: GearType, gearSplId: number) =>
|
|
`/img/gear/${gearType.toLowerCase()}/${gearSplId}`;
|
|
export const weaponCategoryUrl = (
|
|
category: typeof weaponCategories[number]["name"]
|
|
) => `/img/weapon-categories/${category}`;
|
|
export const mainWeaponImageUrl = (mainWeaponSplId: MainWeaponId) =>
|
|
`/img/main-weapons/${mainWeaponSplId}`;
|
|
export const subWeaponImageUrl = (subWeaponSplId: SubWeaponId) =>
|
|
`/img/sub-weapons/${subWeaponSplId}`;
|
|
export const specialWeaponImageUrl = (specialWeaponSplId: SpecialWeaponId) =>
|
|
`/img/special-weapons/${specialWeaponSplId}`;
|
|
export const abilityImageUrl = (ability: AbilityWithUnknown) =>
|
|
`/img/abilities/${ability}`;
|
|
export const modeImageUrl = (mode: ModeShort) => `/img/modes/${mode}`;
|
|
export const stageImageUrl = (stageId: StageId) => `/img/stages/${stageId}`;
|
|
|
|
export function resolveBaseUrl(url: string) {
|
|
return new URL(url).host;
|
|
}
|
|
|
|
export const mySlugify = (name: string) => {
|
|
return slugify(name, {
|
|
lower: true,
|
|
strict: true,
|
|
});
|
|
};
|
|
|
|
export const isCustomUrl = (value: string) => {
|
|
return Number.isNaN(Number(value));
|
|
};
|