diff --git a/client/src/common/components/FormInput/FormInput.jsx b/client/src/common/components/FormInput/FormInput.jsx
new file mode 100644
index 0000000..ca696f5
--- /dev/null
+++ b/client/src/common/components/FormInput/FormInput.jsx
@@ -0,0 +1,12 @@
+export const FormInput = ({
+ type = "text", placeholder, value, onChange,
+ error, maxLength, className = ""
+ }) => {
+ return (
+
+
ToneGuessr
Das Frequenzspiel für Marco :3
-
-
{}} />
- setCurrentState("Game")} />
+
+
+
+
+ {homeState === 'joining' && (
+
+ )}
+
+
+
+ {homeState === 'creating' && (
+
+ )}
+
);
diff --git a/client/src/pages/Home/components/CreateForm/CreateForm.jsx b/client/src/pages/Home/components/CreateForm/CreateForm.jsx
new file mode 100644
index 0000000..0b83446
--- /dev/null
+++ b/client/src/pages/Home/components/CreateForm/CreateForm.jsx
@@ -0,0 +1,42 @@
+import "@/common/styles/forms.sass";
+import {useState} from "react";
+import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
+import {faArrowLeft, faPlusSquare} from "@fortawesome/free-solid-svg-icons";
+import FormInput from "@/common/components/FormInput";
+
+export const CreateForm = ({onSubmit, onBack}) => {
+ const [name, setName] = useState("");
+ const [errors, setErrors] = useState({});
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+
+ if (!name.trim()) {
+ setErrors({name: "Gib einen Namen ein"});
+ return;
+ }
+
+ onSubmit(name);
+ };
+
+ return (
+
+
+
+
Raum erstellen
+
+
+
+ );
+};
diff --git a/client/src/pages/Home/components/CreateForm/index.js b/client/src/pages/Home/components/CreateForm/index.js
new file mode 100644
index 0000000..25690d0
--- /dev/null
+++ b/client/src/pages/Home/components/CreateForm/index.js
@@ -0,0 +1 @@
+export {CreateForm as default} from "./CreateForm.jsx";
\ No newline at end of file
diff --git a/client/src/pages/Home/components/JoinForm/JoinForm.jsx b/client/src/pages/Home/components/JoinForm/JoinForm.jsx
new file mode 100644
index 0000000..583d44b
--- /dev/null
+++ b/client/src/pages/Home/components/JoinForm/JoinForm.jsx
@@ -0,0 +1,51 @@
+import "@/common/styles/forms.sass";
+import {useState} from "react";
+import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
+import {faArrowLeft, faArrowRightToBracket} from "@fortawesome/free-solid-svg-icons";
+import FormInput from "@/common/components/FormInput";
+
+export const JoinForm = ({onSubmit, onBack}) => {
+ const [name, setName] = useState("");
+ const [roomCode, setRoomCode] = useState("");
+ const [errors, setErrors] = useState({});
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+
+ const newErrors = {};
+ if (!name.trim()) newErrors.name = "Gib einen Namen an";
+ if (!roomCode.trim()) newErrors.roomCode = "Gib einen Raum-Code an";
+
+ if (Object.keys(newErrors).length > 0) {
+ setErrors(newErrors);
+ return;
+ }
+
+ onSubmit(name, roomCode);
+ };
+
+ return (
+
+
+
+
Beitreten
+
+
+
+ );
+};
diff --git a/client/src/pages/Home/components/JoinForm/index.js b/client/src/pages/Home/components/JoinForm/index.js
new file mode 100644
index 0000000..9b28307
--- /dev/null
+++ b/client/src/pages/Home/components/JoinForm/index.js
@@ -0,0 +1,2 @@
+
+export {JoinForm as default} from "./JoinForm.jsx";
\ No newline at end of file
diff --git a/client/src/pages/Home/styles.sass b/client/src/pages/Home/styles.sass
index cbc97c4..480d113 100644
--- a/client/src/pages/Home/styles.sass
+++ b/client/src/pages/Home/styles.sass
@@ -8,62 +8,69 @@
height: 100vh
width: 100vw
position: relative
- z-index: 1
- animation: page-fade-in 1s ease-in-out
+ z-index: 10
-.logo-container
- text-align: center
- margin-bottom: 2rem
- animation: logo-entrance 1.2s cubic-bezier(0.175, 0.885, 0.32, 1.275)
- position: relative
-
- .logo
- font-size: 80pt
- line-height: 1.1
- margin: 0
- padding: 0 15px
- background: linear-gradient(135deg, $pink, $blue 45%, $mint-green 65%, $yellow 85%, $pink)
- background-size: 300% 100%
- animation: logo-shimmer 10s infinite alternate ease-in-out, logo-glow 5s infinite alternate ease-in-out
- -webkit-background-clip: text
- background-clip: text
- -webkit-text-fill-color: transparent
- filter: drop-shadow(0 0 12px rgba(255, 255, 255, 0.6))
- position: relative
- letter-spacing: 0.1em
- font-weight: bold
+ .logo-container
+ text-align: center
+ margin-bottom: 3rem
+ transform: translateY(0)
+ transition: transform 0.6s cubic-bezier(0.68, -0.55, 0.27, 1.55), margin-bottom 0.6s cubic-bezier(0.68, -0.55, 0.27, 1.55)
+ z-index: 5
- &:before
- content: "ToneGuessr"
- position: absolute
- z-index: -1
- left: 0
- top: 0
- background: none
- -webkit-text-fill-color: transparent
- filter: blur(15px) brightness(1.2)
- opacity: 0.7
- width: 100%
- height: 100%
- animation: text-pulse 5s infinite alternate ease-in-out
-
- .tagline
- font-size: 24pt
- margin: 5px 0 0 0
- color: rgba(255, 255, 255, 0.9)
- text-shadow: 0 0 15px rgba(255, 255, 255, 0.4)
- animation: tagline-fade 2s ease-in-out
- letter-spacing: 0.1em
+ &.shifted
+ transform: translateY(-25vh)
+ margin-bottom: 0
+
+ .logo
+ font-size: 6rem
+ margin: 0
+ color: $white
+ text-shadow: 0 0 20px rgba(255, 255, 255, 0.5)
+ letter-spacing: 0.5rem
+ animation: logo-glow 3s infinite alternate ease-in-out
+
+ .tagline
+ font-size: 1.5rem
+ margin-top: 0.5rem
+ opacity: 0.8
+ text-shadow: 0 0 10px rgba(255, 255, 255, 0.3)
+ font-weight: lighter
+ letter-spacing: 0.2rem
-.action-area
- margin-top: 2rem
- display: flex
- gap: 3rem
- flex-wrap: wrap
- justify-content: center
- position: relative
- z-index: 2
- animation: float-up 1.5s ease-out
+ .content-container
+ position: relative
+ width: 100%
+ display: flex
+ justify-content: center
+ align-items: center
+ transition: all 0.5s ease
+
+ .action-area
+ display: flex
+ gap: 3rem
+ opacity: 1
+ transform: scale(1) translateY(0)
+ transition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55)
+ z-index: 4
+
+ &.hidden
+ opacity: 0
+ transform: scale(0.8) translateY(30px)
+ pointer-events: none
+
+ .form-container
+ position: absolute
+ opacity: 0
+ transform: translateY(30px) scale(0.9)
+ transition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55)
+ pointer-events: none
+ width: 400px
+
+ &.active
+ opacity: 1
+ transform: translateY(0) scale(1)
+ pointer-events: all
+ z-index: 5
@keyframes logo-entrance
0%
@@ -75,11 +82,11 @@
@keyframes logo-glow
0%, 100%
- filter: drop-shadow(0 0 12px rgba(255, 255, 255, 0.6))
- transform: scale(1) rotate(-1deg)
+ text-shadow: 0 0 20px rgba(255, 255, 255, 0.5)
+ transform: scale(1)
50%
- filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.9)) drop-shadow(0 0 40px rgba(102, 204, 255, 0.5))
- transform: scale(1.05) rotate(1deg)
+ text-shadow: 0 0 30px rgba(255, 255, 255, 0.7), 0 0 50px rgba(255, 255, 255, 0.3)
+ transform: scale(1.02)
@keyframes tagline-fade
0%