Skip to content

Commit

Permalink
UI in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
gwaarb committed Jul 10, 2023
1 parent 20c998b commit 5acba13
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 180 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="https://cdn-icons-png.flaticon.com/128/6062/6062646.png" />
<link rel="stylesheet" href="index.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DevDuel</title>
Expand Down
33 changes: 0 additions & 33 deletions src/components/buttons/SeeRulesButton.tsx

This file was deleted.

4 changes: 3 additions & 1 deletion src/components/cards/CardHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
const cardHeaderStyling = "card-header";

interface CardHeaderProps {
name: string;
}

function CardHeader({ name }: CardHeaderProps) {
return (
<div className="card-header">
<div className={cardHeaderStyling}>
<h2>{name}</h2>
</div>
);
Expand Down
8 changes: 6 additions & 2 deletions src/components/cards/CardStats.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { IStats } from "./cardTypes";

const cardStatsStyling = "card-stats";
const cardStatStyling = "p-2 h-10 hover:animate-pulse hover:bg-blue-600 hover:text-white hover:cursor-pointer";

interface CardStatsProps {
stats: IStats;
onStatSelect: (stat: string) => void;
Expand All @@ -14,14 +17,15 @@ function CardStats({
leadingPlayer,
}: CardStatsProps) {
return (
<div className="card-stats">
<div className={cardStatsStyling}>
{Object.entries(stats).map(([key, value], i) => (
<div
className={cardStatStyling}
key={i}
onClick={() => onStatSelect(key)}
style={{
backgroundColor:
leadingPlayer && key === pendingStat ? "yellow" : "white",
leadingPlayer && key === pendingStat ? "orange" : "",
}}
>
<strong>{key}:</strong> {value}
Expand Down
51 changes: 20 additions & 31 deletions src/components/forms/UsernameForm.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,36 @@
import { ChangeEvent, FormEvent } from "react";
import { motion } from "framer-motion";
import React, { ChangeEvent, FormEvent } from "react";
import { Link } from "react-router-dom";

interface UsernameFormProps {
isVisible: boolean;
username: string;
handleChange: (event: ChangeEvent<HTMLInputElement>) => void;
}

function UsernameForm({
isVisible,
const UsernameForm: React.FC<UsernameFormProps> = ({
username,
handleChange,
}: UsernameFormProps) {
handleChange
}) => {
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
};

return (
<motion.div
className="top-half flex flex-col items-center"
animate={!isVisible ? { y: 0 } : { y: -50 }}
transition={{ duration: 0.3 }}
>
<h1 className="mb-3">Dev Duel</h1>
<form className="w-full max-w-sm" onSubmit={handleSubmit}>
<div className="flex items-center border-b border-gray-900 py-2">
<input
className="appearance-none bg-transparent border-none w-full text-gray-700 mr-3 py-1 px-2 leading-tight focus:outline-none"
type="text"
value={username}
onChange={handleChange}
aria-label="username"
placeholder="Enter username"
/>
<button
className="flex-shrink-0 hover:bg-gray-900 border-none hover:text-white text-sm border-4 text-black py-1 px-2 rounded"
type="submit"
>
Create Game
</button>
</div>
<div className="p-9 flex-row justify-center font-mono border-t-8 border-2 border-red-500 w-full">
<h1 className="text-center">dev-duel.exe</h1>
<form className="pt-4 flex justify-around items-center" onSubmit={handleSubmit}>
<input
className="w-64 h-10 p-2 focus:outline-none"
type="text"
value={username}
onChange={handleChange}
aria-label="username"
placeholder="username"
/>
<Link to="/game" className="p-2 h-10 bg-red-500 text-white hover:animate-pulse hover:bg-blue-600 hover:text-white" type="submit">
Run Program
</Link>
</form>
</motion.div>
</div>
);
}

Expand Down
87 changes: 87 additions & 0 deletions src/components/menus/RulesMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useState } from "react";
import { motion } from "framer-motion";

const buttonStyling = "p-2 h-10 bg-red-500 text-white hover:animate-pulse hover:bg-blue-600 hover:text-white";
const itemStyling = "p-3 text-xs hover:animate-pulse hover:bg-blue-600 hover:text-white";

const itemVariants = {
open: {
opacity: 1,
y: 0,
transition: { type: "spring", stiffness: 300, damping: 24 }
},
closed: {
opacity: 0,
y: 20,
transition: { duration: 0.2 }
}
};

function Rules() {
const [isOpen, setIsOpen] = useState(false);

return (
<motion.nav
initial={false}
animate={isOpen ? "open" : "closed"}
className="menu"
>
<div className="flex justify-center">
<motion.button
className={buttonStyling}
whileTap={{ scale: 0.97 }}
onClick={() => setIsOpen(!isOpen)}
>
README.md
<motion.div
variants={{
open: { rotate: 180 },
closed: { rotate: 0 }
}}
transition={{ duration: 0.2 }}
style={{ originY: 0.55 }}
></motion.div>
</motion.button>
</div>
<motion.ul
className="text-center border-2 border-red-500"
variants={{
open: {
clipPath: "inset(0% 0% 0% 0%)",
transition: {
type: "spring",
bounce: 0,
duration: 0.7,
delayChildren: 0.3,
staggerChildren: 0.05
}
},
closed: {
clipPath: "inset(10% 50% 90% 50%)",
transition: {
type: "spring",
bounce: 0,
duration: 0.3
}
}
}}
style={{ pointerEvents: isOpen ? "auto" : "none" }}
>
<motion.li className={itemStyling} variants={itemVariants}>
Players take turns selecting card stats.
</motion.li>
<motion.li className={itemStyling} variants={itemVariants}>
The player with the highest value wins the round.
</motion.li>
<motion.li className={itemStyling} variants={itemVariants}>
The winner collects the opponent's card.
</motion.li>
<motion.li className={itemStyling} variants={itemVariants}>
The game continues until one player has all the cards.
</motion.li>
</motion.ul>
</motion.nav>
);
}

export default Rules;
59 changes: 22 additions & 37 deletions src/components/text/Rules.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,28 @@
import { motion } from "framer-motion";

interface RulesProps {
isVisible: boolean;
}

function Rules({ isVisible }: RulesProps) {
function Rules() {
return (
<motion.div
initial="hidden"
animate={isVisible ? "visible" : "hidden"}
variants={{
visible: { opacity: 1, y: 0 },
hidden: { opacity: 0, y: 20 },
}}
transition={{ duration: 0.3 }}
style={{ originX: 0 }}
>
<div className="bg-gray-100 rounded-lg p-6">
<h2 className="text-2xl font-bold mb-4">Game Rules</h2>
<ul className="list-disc list-inside space-y-2 text-lg">
<li>Two players will take turns to select a card stat.</li>
<li>
Those stats will be compared - the round winner will be the highest
of the two stats.
</li>
<li>The round winner will then pick the next stat.</li>
<li>Each player will have 10 cards, resulting in 10 rounds.</li>
<li>
If the stats are equal, both players lose the round and the
subsequent cards are sent into the black hole.
</li>
<li>
The game is over after 10 rounds (all cards have been played).
</li>
<li>
The overall winner is the player with the highest total round wins.
</li>
</ul>
</div>
<motion.div>
<h2 className="">Game Rules</h2>
<ul className="">
<li>Two players will take turns to select a card stat.</li>
<li>
Those stats will be compared - the round winner will be the highest
of the two stats.
</li>
<li>The round winner will then pick the next stat.</li>
<li>Each player will have 10 cards, resulting in 10 rounds.</li>
<li>
If the stats are equal, both players lose the round and the
subsequent cards are sent into the black hole.
</li>
<li>
The game is over after 10 rounds (all cards have been played).
</li>
<li>
The overall winner is the player with the highest total round wins.
</li>
</ul>
</motion.div>
);
}
Expand Down
16 changes: 15 additions & 1 deletion src/pages/About.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import { motion } from "framer-motion";

function About() {
return <h1>About Page</h1>;
return (
<motion.div
className="w-max mx-auto flex flex-col items-center"
initial={{ opacity: 0, y: -10 }}
animate={{
opacity: 1,
y: 0,
transition: { duration: 0.5, ease: "easeInOut" },
}}
>
<h1>About</h1>
</motion.div>
)
}

export default About;
Loading

0 comments on commit 5acba13

Please sign in to comment.