1
Fork 0

Add modal

This commit is contained in:
Hadeed 2024-06-01 23:22:27 +04:00
parent 23880322c4
commit 0918fe65fa
5 changed files with 113 additions and 52 deletions

View file

@ -1,5 +1,6 @@
import MainMenu from "./mainMenu"; import MainMenu from "./mainMenu";
import Game from "./game"; import Game from "./game";
import Modal from "./modal";
export default () => { export default () => {
return ( return (

View file

@ -1,4 +1,5 @@
import { useImmer } from "use-immer"; import { useImmer } from "use-immer";
import { useState } from "react";
import Cross from "../assets/icon-x.svg?react"; import Cross from "../assets/icon-x.svg?react";
import CrossOutline from "../assets/icon-x-outline.svg?react"; import CrossOutline from "../assets/icon-x-outline.svg?react";
@ -7,10 +8,13 @@ import OvalOutline from "../assets/icon-o-outline.svg?react";
import logo from "../assets/logo.svg"; import logo from "../assets/logo.svg";
import restart from "../assets/icon-restart.svg"; import restart from "../assets/icon-restart.svg";
import Modal from "./modal";
export default () => { export default () => {
const [grid, updateGrid] = useImmer(Array(9).fill("")); const [grid, updateGrid] = useImmer(Array(9).fill(""));
const turn = grid.filter((s) => s == "").length % 2 != 0 ? "X" : "O"; const [modal, setModal] = useState(false);
const turn = grid.filter((s) => s == "").length % 2 != 0 ? "X" : "O";
const TurnOutline = turn == "X" ? CrossOutline : OvalOutline; const TurnOutline = turn == "X" ? CrossOutline : OvalOutline;
const TurnIndicator = turn == "X" ? Cross : Oval; const TurnIndicator = turn == "X" ? Cross : Oval;
@ -32,6 +36,7 @@ export default () => {
}; };
return ( return (
<>
<div className="flex flex-col space-y-4"> <div className="flex flex-col space-y-4">
<header className="flex items-center justify-between px-1"> <header className="flex items-center justify-between px-1">
<div className="flex-1"> <div className="flex-1">
@ -45,7 +50,7 @@ export default () => {
</div> </div>
<div className="flex-1"> <div className="flex-1">
<button <button
onClick={() => updateGrid(() => Array(9).fill(""))} onClick={() => setModal(true)}
className="ml-auto flex size-14 items-center justify-center rounded-xl bg-silver-700 inner-shadow-1-silver-900 hover:bg-silver-400" className="ml-auto flex size-14 items-center justify-center rounded-xl bg-silver-700 inner-shadow-1-silver-900 hover:bg-silver-400"
> >
<img src={restart} alt="restart" /> <img src={restart} alt="restart" />
@ -85,5 +90,31 @@ export default () => {
</div> </div>
</footer> </footer>
</div> </div>
<Modal
isOpen={modal}
className="space-y-8"
onClose={() => {
setModal(false);
}}
>
<h2 className="text-h-l uppercase text-silver-700">Restart game?</h2>
<form
className="flex items-center justify-around text-navy-700"
method="dialog"
>
<button className="rounded-xl bg-silver-700 px-5 py-4 inner-shadow-1-silver-900 hover:bg-silver-400">
<p className="text-h-xs uppercase">No, cancel</p>
</button>
<button
onClick={() => {
updateGrid(() => Array(9).fill(""));
}}
className="rounded-xl bg-yellow-700 px-5 py-4 inner-shadow-1-yellow-900 hover:bg-yellow-400"
>
<p className="text-h-xs uppercase">Yes, restart</p>
</button>
</form>
</Modal>
</>
); );
}; };

View file

@ -3,7 +3,7 @@ import * as RadioGroup from "@radix-ui/react-radio-group";
import logo from "../assets/logo.svg"; import logo from "../assets/logo.svg";
import Cross from "../assets/icon-x.svg?react"; import Cross from "../assets/icon-x.svg?react";
import Oval from "../assets/icon-o.svg?react"; import Oval from "../assets/icon-o.svg?react";
import { useStore, setPlayerOneSymbol } from "./store.jsx"; import { useStore, setPlayerOneSymbol } from "./store";
export default () => { export default () => {
const playerOneSymbol = useStore((state) => state.playerOneSymbol); const playerOneSymbol = useStore((state) => state.playerOneSymbol);
@ -11,7 +11,7 @@ export default () => {
return ( return (
<div className="m-6 flex w-full max-w-lg flex-col items-center space-y-10"> <div className="m-6 flex w-full max-w-lg flex-col items-center space-y-10">
<img src={logo} alt="logo" /> <img src={logo} alt="logo" />
<div className="inner-shadow-2-navy-900 flex w-full flex-col items-center justify-center rounded-2xl bg-navy-400 p-6"> <div className="flex w-full flex-col items-center justify-center rounded-2xl bg-navy-400 p-6 inner-shadow-2-navy-900">
<h2 className="mb-6 text-h-xs uppercase text-silver-700"> <h2 className="mb-6 text-h-xs uppercase text-silver-700">
Pick player 1's mark Pick player 1's mark
</h2> </h2>
@ -43,10 +43,10 @@ export default () => {
</p> </p>
</div> </div>
<div className="w-full space-y-5"> <div className="w-full space-y-5">
<button className="inner-shadow-2-yellow-900 flex w-full items-center justify-center rounded-2xl bg-yellow-700 p-4 hover:bg-yellow-400"> <button className="flex w-full items-center justify-center rounded-2xl bg-yellow-700 p-4 inner-shadow-2-yellow-900 hover:bg-yellow-400">
<p className="text-h-s uppercase text-navy-700">New game (vs cpu)</p> <p className="text-h-s uppercase text-navy-700">New game (vs cpu)</p>
</button> </button>
<button className="inner-shadow-2-blue-900 flex w-full items-center justify-center rounded-2xl bg-blue-700 p-4 hover:bg-blue-400"> <button className="flex w-full items-center justify-center rounded-2xl bg-blue-700 p-4 inner-shadow-2-blue-900 hover:bg-blue-400">
<p className="text-h-s uppercase text-navy-700"> <p className="text-h-s uppercase text-navy-700">
New game (vs player) New game (vs player)
</p> </p>

28
src/modal.jsx Normal file
View file

@ -0,0 +1,28 @@
import { useEffect, useRef } from "react";
export default ({ isOpen, children, className, onClose }) => {
const ref = useRef(null);
useEffect(() => {
if (isOpen) {
ref.current.showModal();
if (onClose) {
ref.current.addEventListener("close", onClose);
}
} else {
ref.current.close();
}
}, [isOpen]);
return (
<dialog
className="backdrop:bg-black/50 h-64 w-screen max-w-[100vw] bg-navy-700"
ref={ref}
>
<div className="flex h-full w-full items-center justify-center">
<div className={className}>{children}</div>
</div>
</dialog>
);
};

View file

@ -46,6 +46,7 @@ export default {
"yellow-900": "#CC8B13", "yellow-900": "#CC8B13",
"yellow-700": "#F2B137", "yellow-700": "#F2B137",
"yellow-400": "#FFC860", "yellow-400": "#FFC860",
black: "#000",
}, },
fontFamily: { fontFamily: {
sans: ["Outfit", "sans-serif"], sans: ["Outfit", "sans-serif"],
@ -80,7 +81,7 @@ export default {
}, },
], ],
"h-l": [ "h-l": [
"24px", "40px",
{ {
letterSpacing: "2.5px", letterSpacing: "2.5px",
fontWeight: "700", fontWeight: "700",