mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-26 13:22:50 -05:00
Tournament nav new style
This commit is contained in:
11
app/root.tsx
11
app/root.tsx
@@ -1,13 +1,5 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
Links,
|
||||
LiveReload,
|
||||
Meta,
|
||||
Outlet,
|
||||
Scripts,
|
||||
ScrollRestoration,
|
||||
useCatch,
|
||||
} from "remix";
|
||||
import { Links, LiveReload, Meta, Outlet, Scripts, useCatch } from "remix";
|
||||
import type { LinksFunction, LoaderFunction } from "remix";
|
||||
|
||||
import resetStyles from "~/styles/reset.css";
|
||||
@@ -61,7 +53,6 @@ function Document({
|
||||
</head>
|
||||
<body>
|
||||
{children}
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
{process.env.NODE_ENV === "development" && <LiveReload />}
|
||||
</body>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// TODO: 404 page that shows other tournaments by the organization
|
||||
|
||||
import classNames from "classnames";
|
||||
import {
|
||||
LinksFunction,
|
||||
LoaderFunction,
|
||||
@@ -8,7 +7,6 @@ import {
|
||||
NavLink,
|
||||
Outlet,
|
||||
useLoaderData,
|
||||
useLocation,
|
||||
} from "remix";
|
||||
import invariant from "tiny-invariant";
|
||||
import { ActionSection } from "~/components/tournament/ActionSection";
|
||||
@@ -53,15 +51,10 @@ export const meta: MetaFunction = (props) => {
|
||||
|
||||
export default function TournamentPage() {
|
||||
const data = useLoaderData<FindTournamentByNameForUrlI>();
|
||||
const location = useLocation();
|
||||
const user = useUser();
|
||||
|
||||
const displayNavLinks = ["register", "manage-roster", "join-team"].every(
|
||||
(urlPart) => !location.pathname.endsWith(urlPart)
|
||||
);
|
||||
|
||||
const navLinks = (() => {
|
||||
const result: { adminOnly?: boolean; code: string; text: string }[] = [
|
||||
const result: { code: string; text: string }[] = [
|
||||
{ code: "", text: "Overview" },
|
||||
{ code: "map-pool", text: "Map Pool" },
|
||||
{ code: "teams", text: `Teams (${data.teams.length})` },
|
||||
@@ -76,10 +69,11 @@ export default function TournamentPage() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: maybe some visual effect for admin only tabs?
|
||||
if (isTournamentAdmin({ userId: user?.id, organization: data.organizer })) {
|
||||
result.push({ code: "seeds", text: "Seeds", adminOnly: true });
|
||||
result.push({ code: "edit", text: "Edit", adminOnly: true });
|
||||
result.push({ code: "start", text: "Start", adminOnly: true });
|
||||
result.push({ code: "seeds", text: "Seeds" });
|
||||
result.push({ code: "edit", text: "Edit" });
|
||||
result.push({ code: "start", text: "Start" });
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -93,44 +87,37 @@ export default function TournamentPage() {
|
||||
"--tournaments-background": data.bannerBackground,
|
||||
"--tournaments-text": data.CSSProperties.text,
|
||||
"--tournaments-text-transparent": data.CSSProperties.textTransparent,
|
||||
// todo: could make a TS helper type for this that checks for leading --
|
||||
} as Record<string, string>
|
||||
}
|
||||
>
|
||||
<InfoBanner />
|
||||
<ActionSection />
|
||||
<div className="tournament__container__spacer" />
|
||||
{/* TODO: add scrolling icon */}
|
||||
<div className="tournament__links-overflower">
|
||||
<div
|
||||
style={{ "--tabs-count": navLinks.length } as any}
|
||||
className="tournament__links-container"
|
||||
>
|
||||
{navLinks.map(({ code, text, adminOnly }) => (
|
||||
<NavLink
|
||||
key={code}
|
||||
className="tournament__nav-link"
|
||||
to={code}
|
||||
data-cy={`${code}-nav-link`}
|
||||
prefetch="intent"
|
||||
end
|
||||
>
|
||||
{isTournamentAdmin({
|
||||
userId: user?.id,
|
||||
organization: data.organizer,
|
||||
}) && (
|
||||
<div
|
||||
className={classNames("tournament__nav-link__admin-text", {
|
||||
"visibility-hidden": !adminOnly,
|
||||
})}
|
||||
>
|
||||
ADMIN
|
||||
</div>
|
||||
)}
|
||||
<span>{text}</span>
|
||||
</NavLink>
|
||||
))}
|
||||
<div className="tournament__links-border">
|
||||
<div
|
||||
style={{ "--tabs-count": navLinks.length } as any}
|
||||
className="tournament__links-container"
|
||||
>
|
||||
{navLinks.map(({ code, text }) => (
|
||||
// TODO: on mobile keep the active link in center
|
||||
<NavLink
|
||||
key={code}
|
||||
className="tournament__nav-link"
|
||||
to={code}
|
||||
data-cy={`${code}-nav-link`}
|
||||
prefetch="intent"
|
||||
end
|
||||
>
|
||||
<span>{text}</span>
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tournament__container__spacer" />
|
||||
<ActionSection />
|
||||
<div className="tournament__outlet-container"></div>
|
||||
<Outlet />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -214,4 +214,5 @@ function CopyToClipboardButton({
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: handle 404 (logged in but not registered)
|
||||
export const CatchBoundary = Catcher;
|
||||
|
||||
@@ -118,7 +118,7 @@ export default function RegisterPage() {
|
||||
if (isAlreadyInTeam) return null;
|
||||
|
||||
return (
|
||||
<div className="tournament__register__container">
|
||||
<div>
|
||||
<h2 className="tournament__register__header">Register now</h2>
|
||||
<div className="tournament__register__content">
|
||||
<Form method="post">
|
||||
|
||||
@@ -59,6 +59,7 @@ export const loader: LoaderFunction = async ({ params }) => {
|
||||
return typedJson({ initialState, mapPool: tournament.mapPool });
|
||||
};
|
||||
|
||||
// TODO: component that shows a table of map, counts in the map pool, which rounds
|
||||
// TODO: handle warning if check-in has not concluded
|
||||
export default function StartBracketTab() {
|
||||
const args = useLoaderData<UseTournamentRoundsArgs>();
|
||||
@@ -268,6 +269,7 @@ function RoundsCollection({
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
// TODO: should be at the bottom always
|
||||
<Button
|
||||
variant="minimal"
|
||||
tiny
|
||||
|
||||
@@ -265,6 +265,7 @@ select::selection {
|
||||
}
|
||||
|
||||
.four-zero-one__status-header {
|
||||
/* TODO: css var */
|
||||
font-size: xx-large;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
.tournament__register__container {
|
||||
padding-block-start: var(--s-4);
|
||||
}
|
||||
|
||||
.tournament__register__header {
|
||||
margin-top: 0;
|
||||
font-size: var(--fonts-lg);
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
}
|
||||
|
||||
.tournament__container__spacer {
|
||||
margin-bottom: var(--s-6);
|
||||
margin-bottom: var(--s-3);
|
||||
}
|
||||
|
||||
.tournament__action-section {
|
||||
width: 100%;
|
||||
padding: var(--s-1-5);
|
||||
margin-top: var(--s-3);
|
||||
background: var(--tournaments-background);
|
||||
border-radius: var(--rounded);
|
||||
}
|
||||
@@ -44,51 +43,51 @@
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.tournament__links-border {
|
||||
display: inline-block;
|
||||
min-width: 100%;
|
||||
padding: var(--s-1-5);
|
||||
background: var(--tournaments-background);
|
||||
border-radius: var(--rounded);
|
||||
}
|
||||
|
||||
.tournament__links-container {
|
||||
display: grid;
|
||||
gap: var(--s-1);
|
||||
border-radius: var(--rounded);
|
||||
grid-template-columns: repeat(var(--tabs-count), minmax(100px, 1fr));
|
||||
padding-block-end: var(--s-8);
|
||||
padding-inline-end: var(--s-4);
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.tournament__nav-link {
|
||||
all: unset;
|
||||
border-radius: var(--rounded);
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
background-color: var(--bg-lighter);
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
font-size: var(--fonts-sm);
|
||||
padding-block: var(--s-1-5);
|
||||
}
|
||||
|
||||
.tournament__nav-link::after {
|
||||
display: block;
|
||||
width: 1.25rem;
|
||||
height: 3px;
|
||||
border-bottom: 3px solid transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.tournament__nav-link:hover::after {
|
||||
border-color: var(--theme-transparent);
|
||||
.tournament__nav-link:first-of-type {
|
||||
border-bottom-left-radius: var(--rounded);
|
||||
border-top-left-radius: var(--rounded);
|
||||
}
|
||||
|
||||
.tournament__nav-link:last-of-type {
|
||||
padding-inline-end: var(--s-6);
|
||||
border-bottom-right-radius: var(--rounded);
|
||||
border-top-right-radius: var(--rounded);
|
||||
}
|
||||
|
||||
.tournament__nav-link:hover {
|
||||
font-weight: var(--bold);
|
||||
}
|
||||
|
||||
.tournament__nav-link.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tournament__nav-link.active::after {
|
||||
width: 1.25rem;
|
||||
border-color: var(--theme);
|
||||
}
|
||||
|
||||
.tournament__nav-link__admin-text {
|
||||
color: var(--theme-secondary);
|
||||
font-size: var(--fonts-xxs);
|
||||
font-weight: var(--bold) !important;
|
||||
background-color: transparent;
|
||||
color: var(--tournaments-text);
|
||||
font-weight: var(--bold);
|
||||
}
|
||||
|
||||
.info-banner {
|
||||
@@ -205,6 +204,11 @@
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.tournament__outlet-container {
|
||||
padding-block-start: var(--s-8);
|
||||
}
|
||||
|
||||
/* separate .css file..? */
|
||||
.teams-tab {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user