mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-14 23:26:15 -05:00
Add mobile friendliness
This commit is contained in:
50
frontend/components/common/Select.tsx
Normal file
50
frontend/components/common/Select.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { styled } from "stitches.config";
|
||||
|
||||
export function Select({
|
||||
values,
|
||||
onChange,
|
||||
selected,
|
||||
}: {
|
||||
values: { id: string; name: string }[];
|
||||
onChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||
selected: string;
|
||||
}) {
|
||||
return (
|
||||
<S_Select onChange={onChange}>
|
||||
{values.map((value) => {
|
||||
return (
|
||||
<option
|
||||
key={value.id}
|
||||
value={value.id}
|
||||
selected={value.id === selected}
|
||||
>
|
||||
{value.name}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</S_Select>
|
||||
);
|
||||
}
|
||||
|
||||
const S_Select = styled("select", {
|
||||
all: "unset",
|
||||
width: "100%",
|
||||
padding: "$2 $4",
|
||||
backgroundColor: "$bgLighter",
|
||||
backgroundImage: `url('data:image/svg+xml;utf8,<svg width="1rem" color="white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /></svg>')`,
|
||||
backgroundPositionX: "95%",
|
||||
backgroundPositionY: "50%",
|
||||
backgroundRepeat: "no-repeat",
|
||||
borderRadius: "$rounded",
|
||||
cursor: "pointer",
|
||||
fontWeight: "$body",
|
||||
fontSize: "$sm",
|
||||
|
||||
"&::selection": {
|
||||
fontWeight: "$bold",
|
||||
},
|
||||
|
||||
"&:focus": {
|
||||
outline: "2px solid $theme",
|
||||
},
|
||||
});
|
||||
@@ -18,10 +18,18 @@ export function MobileNav({ isExpanded }: { isExpanded: boolean }) {
|
||||
return (
|
||||
<Fragment key={navItem.title}>
|
||||
<S_GroupTitle>{navItem.title}</S_GroupTitle>
|
||||
{navItem.items.map((item) => {
|
||||
{navItem.items.map((item, i, arr) => {
|
||||
return (
|
||||
<NextLink key={item} href="/">
|
||||
<S_NavLink>
|
||||
<S_NavLink
|
||||
type={
|
||||
i === 0
|
||||
? "first"
|
||||
: i + 1 === arr.length
|
||||
? "last"
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<S_NavLinkImage
|
||||
src={`/img/nav-icons/${item.replace(" ", "")}.png`}
|
||||
/>
|
||||
@@ -50,6 +58,8 @@ const S_Container = styled("nav", {
|
||||
zIndex: 5,
|
||||
overflowY: "auto",
|
||||
paddingBottom: "$6",
|
||||
// TODO: same for Safari
|
||||
overscrollBehavior: "contain",
|
||||
|
||||
"@sm": {
|
||||
display: "none",
|
||||
@@ -78,7 +88,6 @@ const S_LinksContainer = styled("div", {
|
||||
justifyContent: "center",
|
||||
gridAutoColumns: "1fr",
|
||||
gridAutoRows: "4rem",
|
||||
paddingX: "$24",
|
||||
});
|
||||
|
||||
const S_NavLinkImage = styled("img", {
|
||||
@@ -95,6 +104,7 @@ const S_GroupTitle = styled("div", {
|
||||
marginBottom: "$1",
|
||||
backgroundColor: "$bg",
|
||||
fontWeight: "$bold",
|
||||
borderRadius: "$rounded",
|
||||
});
|
||||
|
||||
const S_NavLink = styled("div", {
|
||||
@@ -106,8 +116,20 @@ const S_NavLink = styled("div", {
|
||||
backgroundColor: "$bg",
|
||||
paddingX: "$2",
|
||||
fontSize: "$sm",
|
||||
marginX: "$12",
|
||||
|
||||
"&:last-child": {
|
||||
borderBottom: "3px solid $bgLighter",
|
||||
"@xs": {
|
||||
marginX: "$24",
|
||||
},
|
||||
|
||||
variants: {
|
||||
type: {
|
||||
first: {
|
||||
borderRadius: "$rounded $rounded 0 0",
|
||||
},
|
||||
last: {
|
||||
borderRadius: "0 0 $rounded $rounded",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -74,11 +74,15 @@ function dayNumber(date: string) {
|
||||
}
|
||||
|
||||
const S_Container = styled("div", {
|
||||
width: "min(48rem, 100%)",
|
||||
width: "100%",
|
||||
padding: "$6",
|
||||
background: "var(--background)",
|
||||
borderRadius: "$rounded",
|
||||
color: "var(--text)",
|
||||
|
||||
"@md": {
|
||||
borderRadius: "$rounded",
|
||||
width: "48rem",
|
||||
},
|
||||
});
|
||||
|
||||
const S_TopRow = styled("div", {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { styled } from "@stitches/react";
|
||||
import { styled } from "stitches.config";
|
||||
import { useTournamentData } from "hooks/data/useTournamentData";
|
||||
import { stages, modesShort } from "@sendou-ink/shared/constants";
|
||||
import type { Mode } from "@sendou-ink/api/common";
|
||||
@@ -64,13 +64,24 @@ const S_InfoSquare = styled("div", {
|
||||
fontSize: "$xl",
|
||||
backgroundImage: `url(/svg/background-pattern.svg)`,
|
||||
backgroundColor: "$bgLighter",
|
||||
borderRadius: "$rounded",
|
||||
|
||||
"@xs": {
|
||||
borderRadius: "$rounded",
|
||||
},
|
||||
});
|
||||
|
||||
const S_Container = styled("div", {
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(4, 1fr)",
|
||||
gridTemplateColumns: "1fr",
|
||||
gap: "1rem",
|
||||
|
||||
"@xs": {
|
||||
gridTemplateColumns: "repeat(2, 1fr)",
|
||||
},
|
||||
|
||||
"@sm": {
|
||||
gridTemplateColumns: "repeat(4, minmax(1px, 200px))",
|
||||
},
|
||||
});
|
||||
|
||||
const S_EmphasizedText = styled("span", {
|
||||
@@ -82,8 +93,11 @@ const S_StageImageContainer = styled("div", {
|
||||
});
|
||||
|
||||
const S_StageImage = styled("img", {
|
||||
width: "14rem",
|
||||
borderRadius: "$rounded",
|
||||
width: "100%",
|
||||
|
||||
"@xs": {
|
||||
borderRadius: "$rounded",
|
||||
},
|
||||
|
||||
variants: {
|
||||
filter: {
|
||||
|
||||
@@ -2,36 +2,46 @@ import { InfoBanner } from "components/tournament/InfoBanner";
|
||||
import { Tab } from "components/common/Tab";
|
||||
import { styled } from "stitches.config";
|
||||
import { MapPoolTab } from "components/tournament/MapPoolTab";
|
||||
import { Select } from "components/common/Select";
|
||||
import { useState } from "react";
|
||||
|
||||
const tabs = [
|
||||
{ name: "Overview", id: "info" },
|
||||
{ name: "Map Pool", id: "map-pool" },
|
||||
{ name: "Bracket", id: "bracket" },
|
||||
{ name: "Teams (23)", id: "teams" },
|
||||
{ name: "Streams (4)", id: "streams" },
|
||||
{ name: "Overview", id: "info", component: null },
|
||||
{ name: "Map Pool", id: "map-pool", component: <MapPoolTab /> },
|
||||
{ name: "Bracket", id: "bracket", component: null },
|
||||
{ name: "Teams (23)", id: "teams", component: null },
|
||||
{ name: "Streams (4)", id: "streams", component: null },
|
||||
];
|
||||
|
||||
export default function TournamentPage() {
|
||||
const [activeTab, setActiveTab] = useState(tabs[0].id);
|
||||
return (
|
||||
<S_Container>
|
||||
<InfoBanner />
|
||||
<Tab.Group>
|
||||
<Tab.List tabsCount={tabs.length}>
|
||||
{tabs.map((tab) => (
|
||||
<Tab key={tab.id}>{tab.name}</Tab>
|
||||
))}
|
||||
</Tab.List>
|
||||
<Tab.Panels>
|
||||
<Tab.Panel>Content 1</Tab.Panel>
|
||||
<Tab.Panel>
|
||||
<MapPoolTab />
|
||||
</Tab.Panel>
|
||||
<Tab.Panel>Content 3</Tab.Panel>
|
||||
<Tab.Panel>Content 4</Tab.Panel>
|
||||
<Tab.Panel>Content 5</Tab.Panel>
|
||||
<Tab.Panel>Content 6</Tab.Panel>
|
||||
</Tab.Panels>
|
||||
</Tab.Group>
|
||||
<S_TabsContainer>
|
||||
<Tab.Group>
|
||||
<Tab.List tabsCount={tabs.length}>
|
||||
{tabs.map((tab) => (
|
||||
<Tab key={tab.id}>{tab.name}</Tab>
|
||||
))}
|
||||
</Tab.List>
|
||||
<Tab.Panels>
|
||||
{tabs.map((tab) => (
|
||||
<Tab.Panel key={tab.id}>{tab.component}</Tab.Panel>
|
||||
))}
|
||||
</Tab.Panels>
|
||||
</Tab.Group>
|
||||
</S_TabsContainer>
|
||||
<S_MobileContent>
|
||||
<S_SelectContainer>
|
||||
<Select
|
||||
values={tabs}
|
||||
onChange={(e) => setActiveTab(e.target.value)}
|
||||
selected={activeTab}
|
||||
/>
|
||||
</S_SelectContainer>
|
||||
{tabs.find((tab) => tab.id === activeTab)!.component}
|
||||
</S_MobileContent>
|
||||
</S_Container>
|
||||
);
|
||||
}
|
||||
@@ -42,3 +52,26 @@ const S_Container = styled("div", {
|
||||
alignItems: "center",
|
||||
gap: "$8",
|
||||
});
|
||||
|
||||
const S_TabsContainer = styled("div", {
|
||||
display: "none",
|
||||
|
||||
"@sm": {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: "$8",
|
||||
},
|
||||
});
|
||||
|
||||
const S_SelectContainer = styled("div", {
|
||||
width: "12rem",
|
||||
margin: "0 auto",
|
||||
marginBottom: "$8",
|
||||
});
|
||||
|
||||
const S_MobileContent = styled("div", {
|
||||
"@sm": {
|
||||
display: "none",
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user