diff --git a/index.html b/index.html index 56181c0..f35ab9d 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,7 @@ diff --git a/src/components/TitleLogo.tsx b/src/components/TitleLogo.tsx index 86b02de..f056c49 100644 --- a/src/components/TitleLogo.tsx +++ b/src/components/TitleLogo.tsx @@ -17,6 +17,10 @@ const TotalStatContainer = styled.div` align-items: flex-start; justify-content: flex-start; padding: 32px 0; + + @media screen and (max-width: 720px) { + padding: 16px 0; + } `; const TotalStatWrapper = styled.div` diff --git a/src/components/form/JyanshiSelect.tsx b/src/components/form/JyanshiSelect.tsx index 5ae30b0..7f82aa5 100644 --- a/src/components/form/JyanshiSelect.tsx +++ b/src/components/form/JyanshiSelect.tsx @@ -90,8 +90,6 @@ const JyanshiSelect = ({ } : undefined } - // autoSelect - autoComplete autoHighlight filterSelectedOptions /> diff --git a/src/components/form/gameRecord/GameChipInput.tsx b/src/components/form/gameRecord/GameChipInput.tsx new file mode 100644 index 0000000..0b81ff2 --- /dev/null +++ b/src/components/form/gameRecord/GameChipInput.tsx @@ -0,0 +1,115 @@ +import styled from "@emotion/styled"; +import { Input } from "@mui/base"; +import { useEffect, useState } from "react"; +import { color } from "../../../styles/colors"; +import { fontFamilies } from "../../../styles/fonts"; +import { IconPokerChip } from "@tabler/icons-react"; + +const ScoreBackground = styled.div` + position: relative; + ${fontFamilies.libreCaslon} + font-weight: 500; + background-color: #1a1a1b; + color: #b89554; + font-size: 1.6em; + border: 1px solid ${color.silkBlueLight}; + + &:hover { + border: 1px solid ${color.goldLight}; + } + + @media (max-width: 720px) { + font-size: 1.2em; + } +`; + +const InputRoot = styled.div` + flex: 1 0 0; + font-size: 1.2em; + min-width: 0; +`; + +const InputField = styled.input` + width: 100%; + background: none; + padding: 0; + border: none; + color: inherit; + padding: 8px 8px 8px 1.7ch; + text-align: center; +`; + +const InputAdornment = styled.span` + position: absolute; + user-select: none; + left: 8px; + bottom: 16%; +`; + +const strip = (value: string) => { + const replaced = value.replace(/[^0-9-]/g, ""); + if (!replaced.length) return ""; + if (/^0+$/.test(replaced)) return "0"; + return replaced.replace(/^0+/, "").replace(/^-0+/, "-"); +}; + +interface Props { + value: number; + onChange?: (value: number) => void; +} + +const GameChipInput = ({ value, onChange }: Props) => { + const [internalValue, setInternalValue] = useState(""); + + useEffect(() => { + if (!value) { + if (internalValue === "-") return; + } + if (value !== +internalValue) { + setInternalValue(Math.floor(value).toString()); + } + }, [internalValue, value]); + + const handleChange = (newValue: string) => { + const stripped = strip(newValue).slice(0, 5); + setInternalValue(stripped); + if (onChange) { + const int = +stripped; + if (isNaN(int)) { + onChange(0); + return; + } + onChange(int); + } + }; + + const handleFocus = () => { + if (internalValue === "0") { + setInternalValue(""); + } + }; + + const handleBlur = () => { + setInternalValue(Math.floor(value).toString()); + }; + + return ( + <> + + handleChange(e.target.value)} + onFocus={handleFocus} + onBlur={handleBlur} + /> + + + + + + ); +}; + +export default GameChipInput; diff --git a/src/components/form/gameRecord/GameRecordSingleUserInput.tsx b/src/components/form/gameRecord/GameRecordSingleUserInput.tsx index 3998631..494642c 100644 --- a/src/components/form/gameRecord/GameRecordSingleUserInput.tsx +++ b/src/components/form/gameRecord/GameRecordSingleUserInput.tsx @@ -9,6 +9,7 @@ import { fontFamilies } from "../../../styles/fonts"; import { Space } from "../../Space"; import { IconCheckbox, IconSquare } from "@tabler/icons-react"; import GameScoreInput from "./GameScoreInput"; +import GameChipInput from "./GameChipInput"; const InputCard = styled.div<{ oya: boolean }>` background-image: linear-gradient( @@ -119,6 +120,9 @@ const GameRecordSingleUserInput = ({ {scoreType === "score" && ( )} + {scoreType === "chips" && ( + + )} ); }; diff --git a/src/components/header/Header.tsx b/src/components/header/Header.tsx index dc7eab0..7c6eb83 100644 --- a/src/components/header/Header.tsx +++ b/src/components/header/Header.tsx @@ -28,6 +28,12 @@ const HeaderBackground = styled.div` display: flex; align-items: center; justify-content: flex-start; + + @media (max-width: 720px) { + min-height: 48px; + font-size: 1.5rem; + padding: 8px 120px 8px 16px; + } `; interface Props extends HTMLAttributes {} diff --git a/src/components/layouts/Container.tsx b/src/components/layouts/Container.tsx index b98fbed..38094bc 100644 --- a/src/components/layouts/Container.tsx +++ b/src/components/layouts/Container.tsx @@ -7,6 +7,6 @@ export const Container = styled.div` padding: 0 32px; @media screen and (max-width: 720px) { - padding: 0 16px; + padding: 0; } `; diff --git a/src/components/layouts/DefaultLayout.tsx b/src/components/layouts/DefaultLayout.tsx index 188f2d4..3438005 100644 --- a/src/components/layouts/DefaultLayout.tsx +++ b/src/components/layouts/DefaultLayout.tsx @@ -11,6 +11,10 @@ const FullScreenContainer = styled.div` height: calc(100vh - 72px); overflow: hidden; position: relative; + + @media screen and (max-width: 720px) { + height: calc(100vh - 48px); + } `; const BACKGROUND_IMAGES = { diff --git a/src/components/layouts/TopBarPadding.tsx b/src/components/layouts/TopBarPadding.tsx index d8ea071..d9e49bb 100644 --- a/src/components/layouts/TopBarPadding.tsx +++ b/src/components/layouts/TopBarPadding.tsx @@ -1,5 +1,8 @@ -import { Space } from "../Space"; +import styled from "@emotion/styled"; -export const TopBarPadding = () => { - return ; -}; +export const TopBarPadding = styled.div` + height: 96px; + @media screen and (max-width: 720px) { + height: 64px; + } +`; diff --git a/src/pages/create/CreateLoggedIn.tsx b/src/pages/create/CreateLoggedIn.tsx index 3238751..6ee2d04 100644 --- a/src/pages/create/CreateLoggedIn.tsx +++ b/src/pages/create/CreateLoggedIn.tsx @@ -1,49 +1,33 @@ import styled from "@emotion/styled"; import { useState } from "react"; import { Card } from "../../components/Card"; -import { Space } from "../../components/Space"; import GameTypeSelect from "../../components/form/GameTypeSelect"; import GameRecordInput from "../../components/form/gameRecord/GameRecordInput"; import { GameRecordInputValues } from "../../components/form/gameRecord/types"; import { GameTypeResponse } from "../../types/GameTypeResponse"; import { resolveWind } from "../../utils/wind"; -const InputRow = styled.div` - display: flex; - gap: 8px; - align-items: center; - justify-content: center; - - @media screen and (max-width: 720px) { - align-items: flex-start; - flex-direction: column; - } -`; - -const InputCaption = styled.div` - flex: 0 0 120px; - min-width: 0; - - @media screen and (max-width: 720px) { - flex: 0 0 auto; - } +const GameTypeInputContainer = styled.div` + width: 100%; + max-width: 540px; + margin: 0 auto; `; -const InputDetails = styled.div` - flex: 1; - min-width: 0; +const GameTypeSelectContainer = styled.div` + position: fixed; + z-index: 210; + left: 160px; + right: 0; + top: 46px; + color: white; @media screen and (max-width: 720px) { - flex: 0 0 auto; + left: unset; + top: 22px; + right: 0px; } `; -const GameTypeInputContainer = styled.div` - width: 100%; - max-width: 540px; - margin: 0 auto; -`; - const CreateLoggedIn = () => { const [selectedGameType, setSelectedGameType] = useState(null); @@ -85,22 +69,14 @@ const CreateLoggedIn = () => { return ( <> + + + - - 대국 유형 - - - - - - - 작사 - - {selectedGameType && ( (x === "sans-serif" ? x : `'${x}'`)) .join(", "); -const zenAntique = ["Zen Antique Soft", "sans-serif"]; +const zenAntique = ["Zen Antique Soft", "sans-serif"] + .map((x) => (x === "sans-serif" ? x : `'${x}'`)) + .join(", "); -const oxanium = ["Oxanium", "sans-serif"]; +const oxanium = ["Oxanium", "sans-serif"] + .map((x) => (x === "sans-serif" ? x : `'${x}'`)) + .join(", "); + +const libreCaslon = ["Libre Caslon Text", "sans-serif"] + .map((x) => (x === "sans-serif" ? x : `'${x}'`)) + .join(", "); export const fonts = { kimDaegon, milkyway, zenAntique, oxanium, + libreCaslon, }; export const fontFamilies = Object.fromEntries(