Tournament nav new style

This commit is contained in:
Kalle (Sendou)
2021-12-19 14:29:03 +02:00
parent 5648218943
commit 0877fe9264
8 changed files with 67 additions and 85 deletions

View File

@@ -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>

View File

@@ -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>
);

View File

@@ -214,4 +214,5 @@ function CopyToClipboardButton({
);
}
// TODO: handle 404 (logged in but not registered)
export const CatchBoundary = Catcher;

View File

@@ -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">

View File

@@ -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

View File

@@ -265,6 +265,7 @@ select::selection {
}
.four-zero-one__status-header {
/* TODO: css var */
font-size: xx-large;
}

View File

@@ -1,7 +1,3 @@
.tournament__register__container {
padding-block-start: var(--s-4);
}
.tournament__register__header {
margin-top: 0;
font-size: var(--fonts-lg);

View File

@@ -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;