diff --git a/apps/client/src/scenes/lobby/LobbyScene.tsx b/apps/client/src/scenes/lobby/LobbyScene.tsx index 1bdbb14..866d055 100644 --- a/apps/client/src/scenes/lobby/LobbyScene.tsx +++ b/apps/client/src/scenes/lobby/LobbyScene.tsx @@ -1,6 +1,7 @@ import { useEffect, useMemo, useState } from "react"; import { domain } from "@repo/shared"; import { OVERLAY_BUTTON_STYLE } from "@client/scenes/shared/styles/overlayStyles"; +import { LobbyRuleModal } from "./components/LobbyRuleModal"; type Props = { room: domain.room.Room | null; @@ -45,6 +46,7 @@ const [selectedStartPlayerCount, setSelectedStartPlayerCount] = useState( minimumStartPlayerCount, ); + const [isRuleModalOpen, setIsRuleModalOpen] = useState(false); useEffect(() => { setSelectedStartPlayerCount((prev) => { @@ -222,22 +224,54 @@ > ゲームスタート + + ) : (
- ホストの開始を待っています... +
+ ホストの開始を待っています... +
+ +
)} @@ -309,6 +343,14 @@ + + {isRuleModalOpen && ( + { + setIsRuleModalOpen(false); + }} + /> + )} ); }; diff --git a/apps/client/src/scenes/lobby/components/LobbyRuleModal.styles.ts b/apps/client/src/scenes/lobby/components/LobbyRuleModal.styles.ts new file mode 100644 index 0000000..b3992de --- /dev/null +++ b/apps/client/src/scenes/lobby/components/LobbyRuleModal.styles.ts @@ -0,0 +1,66 @@ +import type { CSSProperties } from "react"; + +export const LOBBY_RULE_MODAL_OVERLAY_STYLE: CSSProperties = { + position: "fixed", + inset: 0, + background: "rgba(0, 0, 0, 0.72)", + zIndex: 120, + display: "flex", + alignItems: "center", + justifyContent: "center", + padding: "16px", +}; + +export const LOBBY_RULE_MODAL_PANEL_STYLE: CSSProperties = { + width: "min(760px, 100%)", + maxHeight: "min(78dvh, 820px)", + borderRadius: "12px", + background: "rgba(20, 20, 20, 0.95)", + border: "1px solid rgba(255, 255, 255, 0.15)", + boxShadow: "0 12px 28px rgba(0, 0, 0, 0.45)", + color: "white", + display: "flex", + flexDirection: "column", +}; + +export const LOBBY_RULE_MODAL_HEADER_STYLE: CSSProperties = { + padding: "16px 18px", + borderBottom: "1px solid rgba(255, 255, 255, 0.16)", + fontSize: "1.1rem", + fontWeight: 800, +}; + +export const LOBBY_RULE_MODAL_BODY_STYLE: CSSProperties = { + padding: "14px 18px", + overflowY: "auto", + display: "flex", + flexDirection: "column", + gap: "16px", +}; + +export const LOBBY_RULE_MODAL_SECTION_STYLE: CSSProperties = { + display: "flex", + flexDirection: "column", + gap: "8px", +}; + +export const LOBBY_RULE_MODAL_SECTION_TITLE_STYLE: CSSProperties = { + margin: 0, + fontSize: "1rem", + fontWeight: 800, +}; + +export const LOBBY_RULE_MODAL_LIST_STYLE: CSSProperties = { + margin: 0, + paddingLeft: "20px", + display: "flex", + flexDirection: "column", + gap: "6px", +}; + +export const LOBBY_RULE_MODAL_FOOTER_STYLE: CSSProperties = { + padding: "14px 18px", + borderTop: "1px solid rgba(255, 255, 255, 0.16)", + display: "flex", + justifyContent: "flex-end", +}; diff --git a/apps/client/src/scenes/lobby/components/LobbyRuleModal.tsx b/apps/client/src/scenes/lobby/components/LobbyRuleModal.tsx new file mode 100644 index 0000000..8f41610 --- /dev/null +++ b/apps/client/src/scenes/lobby/components/LobbyRuleModal.tsx @@ -0,0 +1,47 @@ +import { OVERLAY_BUTTON_STYLE } from "@client/scenes/shared/styles/overlayStyles"; +import { + LOBBY_RULE_MODAL_BODY_STYLE, + LOBBY_RULE_MODAL_FOOTER_STYLE, + LOBBY_RULE_MODAL_HEADER_STYLE, + LOBBY_RULE_MODAL_LIST_STYLE, + LOBBY_RULE_MODAL_OVERLAY_STYLE, + LOBBY_RULE_MODAL_PANEL_STYLE, + LOBBY_RULE_MODAL_SECTION_STYLE, + LOBBY_RULE_MODAL_SECTION_TITLE_STYLE, +} from "./LobbyRuleModal.styles"; +import { LOBBY_RULE_SECTIONS } from "../presentation/lobbyRuleContent"; + +type LobbyRuleModalProps = { + onClose: () => void; +}; + +export const LobbyRuleModal = ({ onClose }: LobbyRuleModalProps) => { + return ( +
+
+
ルール
+ +
+ {LOBBY_RULE_SECTIONS.map((section) => ( +
+

+ {section.title} +

+
    + {section.lines.map((line) => ( +
  • {line}
  • + ))} +
+
+ ))} +
+ +
+ +
+
+
+ ); +}; diff --git a/apps/client/src/scenes/lobby/presentation/lobbyRuleContent.ts b/apps/client/src/scenes/lobby/presentation/lobbyRuleContent.ts new file mode 100644 index 0000000..5a0977c --- /dev/null +++ b/apps/client/src/scenes/lobby/presentation/lobbyRuleContent.ts @@ -0,0 +1,26 @@ +/** + * lobbyRuleContent + * ロビーのルール表示で使う短文テキストを定義する + */ + +/** ルール画面の短文セクション */ +export type LobbyRuleSection = { + title: string; + lines: string[]; +}; + +/** ロビーに表示するルール内容 */ +export const LOBBY_RULE_SECTIONS: LobbyRuleSection[] = [ + { + title: "操作", + lines: ["左で移動", "右下で爆弾設置"], + }, + { + title: "被弾", + lines: ["被弾でその場ステイ", "一定回数で初期位置へ戻る"], + }, + { + title: "勝利", + lines: ["制限時間終了時に塗り面積が最も高いチームが勝利"], + }, +];