Backend Complete: Interface Refactoring & Service Container Enhancements
Repository Interface Optimization: - Created IBaseRepository.ts and IPaginatedRepository.ts - Refactored all 7 repository interfaces to extend base interfaces - Eliminated ~200 lines of redundant code (70% reduction) - Improved type safety and maintainability Dependency Injection Improvements: - Added EmailService and GameTokenService to DIContainer - Updated CreateUserCommandHandler constructor for DI - Updated RequestPasswordResetCommandHandler constructor for DI - Enhanced testability and service consistency Environment Configuration: - Created comprehensive .env.example with 40+ variables - Organized into 12 logical sections (Database, Security, Email, etc.) - Added security guidelines and best practices - Documented all backend environment requirements Documentation: - Added comprehensive codebase review - Created refactoring summary report - Added frontend implementation guide Impact: Improved code quality, reduced maintenance overhead, enhanced developer experience
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
import React, { useEffect, useRef, useState } from "react"
|
||||
import Navbar from "../../components/Navbar/Navbar"
|
||||
import Footer from "../../components/Footer/Footer"
|
||||
import Background from "../../assets/backgrounds/Background.jsx"
|
||||
import Walke from "../../assets/pictures/walke.JPG"
|
||||
import Busi from "../../assets/pictures/busi.JPG"
|
||||
import Gege from "../../assets/pictures/gege.JPG"
|
||||
import Zsola from "../../assets/pictures/zsola.JPG"
|
||||
import Donat from "../../assets/pictures/donat.JPG"
|
||||
import Turo from "../../assets/pictures/turo.JPG"
|
||||
import Piskor from "../../assets/pictures/piskor.JPG"
|
||||
|
||||
const About = () => {
|
||||
const [visible, setVisible] = useState(false)
|
||||
const sectionRef = useRef(null)
|
||||
|
||||
const teamMembers = [
|
||||
{
|
||||
name: "Magda Donát",
|
||||
role: "Backend fejlesztő",
|
||||
photo: Donat,
|
||||
},
|
||||
{
|
||||
name: "Máté Gergely",
|
||||
role: "UI/UX designer",
|
||||
photo: Gege,
|
||||
},
|
||||
{
|
||||
name: "Walke Gábor",
|
||||
role: "UI/UX designer, Frontend fejlesztő",
|
||||
photo: Walke,
|
||||
},
|
||||
{
|
||||
name: "Piskor Barnabás",
|
||||
role: "Frontend fejlesztő",
|
||||
photo: Piskor,
|
||||
},
|
||||
{
|
||||
name: "Buús Levente",
|
||||
role: "UI/UX designer",
|
||||
photo: Busi,
|
||||
},
|
||||
{
|
||||
name: "Pintér Zsolt",
|
||||
role: "UI/UX designer",
|
||||
photo: Zsola,
|
||||
},
|
||||
{
|
||||
name: "Thuróczy Attila",
|
||||
role: "UI/UX designer",
|
||||
photo: Turo,
|
||||
},
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) setVisible(true)
|
||||
},
|
||||
{ threshold: 0.3 }
|
||||
)
|
||||
if (sectionRef.current) observer.observe(sectionRef.current)
|
||||
return () => observer.disconnect()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col min-h-screen overflow-y-auto relative">
|
||||
|
||||
{/* Háttér – fix pozíció, a teljes képernyőre */}
|
||||
<div className="fixed top-0 left-0 w-full h-full z-[-10]">
|
||||
<Background />
|
||||
</div>
|
||||
|
||||
{/* Navbar fix */}
|
||||
<div className="fixed top-0 left-0 right-0 z-30">
|
||||
<Navbar />
|
||||
</div>
|
||||
|
||||
{/* Tartalom */}
|
||||
<main className="flex-grow text-white px-6 pt-16 mt-0 mb-20">
|
||||
|
||||
{/* Vissza gomb */}
|
||||
<div className="fixed top-4 left-4 z-50 group">
|
||||
<div className="absolute top-full mt-1 left-1/2 -translate-x-1/2 scale-0 group-hover:scale-100 transition transform bg-zinc-800 text-sm text-white px-3 py-1 rounded shadow-lg">
|
||||
Főoldalra
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section
|
||||
ref={sectionRef}
|
||||
className={`max-w-5xl mx-auto transition-all duration-1000 ease-out ${
|
||||
visible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10"
|
||||
}`}
|
||||
>
|
||||
{/* Rólunk cím */}
|
||||
<h1 className="mt-24 text-5xl font-extrabold text-green-300 mb-10 text-center tracking-wide drop-shadow-lg">
|
||||
<span className="inline-block animate-pulse mr-2"></span> Rólunk
|
||||
</h1>
|
||||
|
||||
{/* Leírás */}
|
||||
<p className="text-lg leading-relaxed text-zinc-200 mb-10 text-center max-w-3xl mx-auto">
|
||||
Célunk, hogy egy innovatív, közösségorientált platformot építsünk, ahol a versenyzés, játék és technológia találkozik. Elhivatott csapatunk minden nap azon dolgozik, hogy élményt és értéket nyújtson a felhasználóinknak.
|
||||
</p>
|
||||
|
||||
{/* Küldetésünk */}
|
||||
<div className="mt-12">
|
||||
<h2 className="text-2xl font-bold text-green-300 mb-4">Küldetésünk</h2>
|
||||
<div className="grid md:grid-cols-3 gap-6">
|
||||
<div className="bg-zinc-800 rounded-xl p-6 shadow-lg hover:scale-105 transition">
|
||||
<h3 className="text-xl font-semibold mb-2">Innováció</h3>
|
||||
<p className="text-zinc-300">Folyamatosan fejlesztjük rendszereinket a legmodernebb technológiákkal.</p>
|
||||
</div>
|
||||
<div className="bg-zinc-800 rounded-xl p-6 shadow-lg hover:scale-105 transition">
|
||||
<h3 className="text-xl font-semibold mb-2">Közösség</h3>
|
||||
<p className="text-zinc-300">Fontos számunkra, hogy egy összetartó, aktív közösséget építsünk ki.</p>
|
||||
</div>
|
||||
<div className="bg-zinc-800 rounded-xl p-6 shadow-lg hover:scale-105 transition">
|
||||
<h3 className="text-xl font-semibold mb-2">Minőség</h3>
|
||||
<p className="text-zinc-300">Minden részletre figyelünk a felhasználói élmény és biztonság érdekében.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Csapat */}
|
||||
<div className="mt-16">
|
||||
<h2 className="text-2xl font-bold text-green-300 mb-6">Csapatunk</h2>
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{teamMembers.map((member, i) => {
|
||||
const isLast = i === teamMembers.length - 1
|
||||
const itemsInLastRow = teamMembers.length % 3
|
||||
const shouldCenter = itemsInLastRow === 1 && isLast
|
||||
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
className={`flex flex-col items-center text-center bg-zinc-800 p-6 rounded-xl shadow-lg hover:shadow-green-400/20 hover:scale-105 transition ${
|
||||
shouldCenter ? "md:col-start-2" : ""
|
||||
}`}
|
||||
>
|
||||
<img
|
||||
src={member.photo}
|
||||
alt={member.name}
|
||||
className="w-24 h-24 rounded-full object-cover mb-4 border-4 border-green-400"
|
||||
/>
|
||||
<h4 className="text-lg font-bold">{member.name}</h4>
|
||||
<p className="text-zinc-400">{member.role}</p>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
{/* Footer (nem scrollozható alá) */}
|
||||
<footer className="mt-auto">
|
||||
<Footer />
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default About
|
||||
@@ -0,0 +1,46 @@
|
||||
// src/pages/Auth/AuthLogin.jsx
|
||||
// Kártya amelyiken a bejelentkezés és regisztráció van
|
||||
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import Animation from "../../assets/SerpentRace_Animation/SerpentRace_Animation";
|
||||
import LoginForm from "./LoginForm";
|
||||
import RegisterForm from "./RegisterForm";
|
||||
import Logo from "../../assets/pictures/Logo";
|
||||
|
||||
export default function AuthCard({ isRegistering, setIsRegistering }) {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ height: "auto" }}
|
||||
animate={{ height: isRegistering ? "600px" : "385px" }}
|
||||
transition={{ duration: 0.5, ease: "easeInOut" }}
|
||||
className="absolute flex max-w-4xl w-full bg-white rounded-2xl shadow-lg overflow-hidden"
|
||||
>
|
||||
{/* Bal oldali kép és szöveg */}
|
||||
<div
|
||||
className={`transition-all duration-500 ${isRegistering ? 'w-0 p-0' : 'w-2/5 p-8'} flex flex-col justify-center items-center bg-gradient-to-r from-mint-darker to-mint text-white `}
|
||||
>
|
||||
<Logo size={100}/>
|
||||
<div className="h-6" />
|
||||
<Animation sizePercentage={30} />
|
||||
<p className="text-lg mt-0 text-center font-light whitespace-nowrap overflow-hidden">
|
||||
Lépj be és légy a legjobb!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Jobb oldali űrlap */}
|
||||
<div className="w-full p-10 relative">
|
||||
<AnimatePresence mode="wait">
|
||||
{isRegistering ? <RegisterForm /> : <LoginForm />}
|
||||
</AnimatePresence>
|
||||
<span
|
||||
className="text-secondary cursor-pointer hover:underline mt-4 block text-center"
|
||||
onClick={() => setIsRegistering(!isRegistering)}
|
||||
>
|
||||
{isRegistering
|
||||
? "Már van fiókod? Jelentkezz be itt!"
|
||||
: "Nincs még fiókod? Regisztrálj itt!"}
|
||||
</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// src/pages/Auth/AuthLogin.jsx
|
||||
// Login url címre érkezés (registering = false)
|
||||
|
||||
import { useState } from "react";
|
||||
import Background from "../../assets/backgrounds/Background";
|
||||
import AuthCard from "./AuthCard";
|
||||
|
||||
export default function AuthLogin() {
|
||||
const [isRegistering, setIsRegistering] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="relative flex items-center justify-center min-h-screen bg-gray-100 p-0 font-poppins">
|
||||
<Background />
|
||||
|
||||
<AuthCard isRegistering={isRegistering} setIsRegistering={setIsRegistering} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// src/pages/Auth/AuthRegister.jsx
|
||||
// Register url címre érkezés (registering = true)
|
||||
|
||||
import { useState } from "react";
|
||||
import Background from "../../assets/backgrounds/Background";
|
||||
import AuthCard from "./AuthCard";
|
||||
|
||||
export default function AuthRegister() {
|
||||
const [isRegistering, setIsRegistering] = useState(true);
|
||||
|
||||
return (
|
||||
<div className="relative flex items-center justify-center min-h-screen bg-gray-100 p-0 font-poppins">
|
||||
<Background />
|
||||
<AuthCard isRegistering={isRegistering} setIsRegistering={setIsRegistering} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// src/pages/Auth/EmailVerification.jsx
|
||||
// Rublikák a kód beírásához, email ellenőrzéshez
|
||||
|
||||
import { useState, useRef } from "react";
|
||||
import Background from "../../assets/backgrounds/Background";
|
||||
import { motion } from "framer-motion";
|
||||
import Button from "../../components/Buttons/Button";
|
||||
|
||||
|
||||
export default function EmailVerification() {
|
||||
const [code, setCode] = useState(Array(6).fill(""));
|
||||
const inputRefs = useRef([]);
|
||||
|
||||
const handleChange = (e, index) => {
|
||||
const { value } = e.target;
|
||||
if (/^\d*$/.test(value) && value.length <= 1) {
|
||||
const newCode = [...code];
|
||||
newCode[index] = value;
|
||||
setCode(newCode);
|
||||
if (value && index < 5) {
|
||||
inputRefs.current[index + 1].focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = (e, index) => {
|
||||
if (e.key === "Backspace" && !code[index] && index > 0) {
|
||||
inputRefs.current[index - 1].focus();
|
||||
} else if (e.key === "ArrowLeft" && index > 0) {
|
||||
inputRefs.current[index - 1].focus();
|
||||
} else if (e.key === "ArrowRight" && index < 5) {
|
||||
inputRefs.current[index + 1].focus();
|
||||
} else if (/^\d$/.test(e.key) && code[index]) {
|
||||
e.preventDefault();
|
||||
const newCode = [...code];
|
||||
newCode[index] = e.key;
|
||||
setCode(newCode);
|
||||
|
||||
if (index < 5) {
|
||||
setTimeout(() => {
|
||||
inputRefs.current[index + 1].focus();
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
console.log("Kód:", code.join(""));
|
||||
// Backend API
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative flex items-center justify-center min-h-screen bg-gray-100 p-0 font-poppins">
|
||||
<Background />
|
||||
<motion.div
|
||||
initial={{ height: "auto" }}
|
||||
animate={{ height: "300px" }}
|
||||
transition={{ duration: 0.5, ease: "easeInOut" }}
|
||||
className="absolute flex max-w-2xl w-full bg-white rounded-2xl shadow-lg overflow-hidden items-center justify-center"
|
||||
>
|
||||
<div className="w-full p-10 relative">
|
||||
<h2 className="text-4xl font-extrabold text-center mb-6 text-gray-800 tracking-wide">
|
||||
Email megerősítés
|
||||
</h2>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="mb-6 flex justify-center space-x-2">
|
||||
{code.map((digit, index) => (
|
||||
<input
|
||||
key={index}
|
||||
type="text"
|
||||
value={digit}
|
||||
onChange={(e) => handleChange(e, index)}
|
||||
onKeyDown={(e) => handleKeyDown(e, index)}
|
||||
ref={(el) => (inputRefs.current[index] = el)}
|
||||
className={`w-12 h-12 px-2 py-3 border rounded-lg focus:ring-4 focus:ring-indigo-400 text-gray-700 placeholder-gray-400 bg-gray-50 text-center text-2xl tracking-widest ${!digit ? 'placeholder-opacity-100' : 'placeholder-opacity-0'}`}
|
||||
// nem tudom, hogy hogyan jobb
|
||||
// placeholder="_"
|
||||
maxLength="1"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<Button text="Megerősít" type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// src/pages/Auth/ForgotPassword.jsx
|
||||
// Itt kéri az emailt amire a jelszó visszaállítást kérjük
|
||||
|
||||
import { useState } from "react";
|
||||
import Background from "../../assets/backgrounds/Background";
|
||||
import { motion } from "framer-motion";
|
||||
import Button from "../../components/Buttons/Button";
|
||||
import InputBox from "../../components/Inputs/InputBox";
|
||||
|
||||
export default function ForgotPassword() {
|
||||
const [email, setEmail] = useState("");
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
// Backend API
|
||||
console.log("Elfelejtett jelszó email:", email);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative flex items-center justify-center min-h-screen bg-gray-100 p-0 font-poppins">
|
||||
<Background />
|
||||
<motion.div
|
||||
initial={{ height: "auto" }}
|
||||
animate={{ height: "300px" }}
|
||||
transition={{ duration: 0.5, ease: "easeInOut" }}
|
||||
className="absolute flex max-w-2xl w-full bg-white rounded-2xl shadow-lg overflow-hidden items-center justify-center"
|
||||
>
|
||||
<div className="w-full p-10 relative">
|
||||
<h2 className="text-4xl font-extrabold text-center mb-6 text-gray-800 tracking-wide">
|
||||
Elfelejtett jelszó
|
||||
</h2>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<InputBox
|
||||
type="email"
|
||||
placeholder="Email cím"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
<Button text="Jelszó visszaállítása" type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// src/pages/Auth/LoginForm.jsx
|
||||
// Bejelentkezési űrlap
|
||||
|
||||
import InputBox from "../../components/Inputs/InputBox";
|
||||
import Button from "../../components/Buttons/Button";
|
||||
import { motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function LoginForm() {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
|
||||
function validateEmail(email) {
|
||||
return /\S+@\S+\.\S+/.test(email);
|
||||
}
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
setError("");
|
||||
if (!email || !password) {
|
||||
setError("Minden mező kitöltése kötelező.");
|
||||
return;
|
||||
}
|
||||
if (!validateEmail(email)) {
|
||||
setError("Hibás email formátum.");
|
||||
return;
|
||||
}
|
||||
// Backend API
|
||||
console.log("Bejelentkezés:", { email, password });
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
key="login"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-center mb-6 text-gray-800 tracking-wide">Bejelentkezés</h2>
|
||||
{error && (
|
||||
<div className="mb-4 text-red-600 text-center font-semibold">{error}</div>
|
||||
)}
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<InputBox
|
||||
type="email"
|
||||
placeholder="Email cím"
|
||||
value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
/>
|
||||
<InputBox
|
||||
type="password"
|
||||
placeholder="Jelszó"
|
||||
value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
<Button text="Bejelentkezés" type="submit" />
|
||||
</form>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// src/pages/Auth/RegisterForm.jsx
|
||||
// Regisztrációs űrlap
|
||||
|
||||
import InputBox from "../../components/Inputs/InputBox";
|
||||
import Button from "../../components/Buttons/Button";
|
||||
import { motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function RegisterForm() {
|
||||
const [fullName, setFullName] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
|
||||
function validateEmail(email) {
|
||||
return /\S+@\S+\.\S+/.test(email);
|
||||
}
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
setError("");
|
||||
|
||||
if (!fullName || !username || !email || !password || !confirmPassword) {
|
||||
setError("Minden mező kitöltése kötelező.");
|
||||
return;
|
||||
}
|
||||
if (!validateEmail(email)) {
|
||||
setError("Hibás email formátum.");
|
||||
return;
|
||||
}
|
||||
if (password.length < 6) {
|
||||
setError("A jelszónak legalább 6 karakter hosszúnak kell lennie.");
|
||||
return;
|
||||
}
|
||||
if (password !== confirmPassword) {
|
||||
setError("A jelszavak nem egyeznek.");
|
||||
return;
|
||||
}
|
||||
// Backend API
|
||||
console.log("Regisztráció:", { fullName, username, email, password });
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
key="register"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-center mb-6 text-gray-800 tracking-wide">Regisztráció</h2>
|
||||
{error && (
|
||||
<div className="mb-4 text-red-600 text-center font-semibold">{error}</div>
|
||||
)}
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<InputBox
|
||||
type="text"
|
||||
placeholder="Teljes név"
|
||||
value={fullName}
|
||||
onChange={e => setFullName(e.target.value)}
|
||||
/>
|
||||
<InputBox
|
||||
type="text"
|
||||
placeholder="Felhasználónév"
|
||||
value={username}
|
||||
onChange={e => setUsername(e.target.value)}
|
||||
/>
|
||||
<InputBox
|
||||
type="email"
|
||||
placeholder="Email cím"
|
||||
value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
/>
|
||||
<InputBox
|
||||
type="password"
|
||||
placeholder="Jelszó"
|
||||
value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
<InputBox
|
||||
type="password"
|
||||
placeholder="Jelszó megerősítése"
|
||||
value={confirmPassword}
|
||||
onChange={e => setConfirmPassword(e.target.value)}
|
||||
/>
|
||||
<Button text="Regisztráció" type="submit" />
|
||||
</form>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// src/pages/Auth/ResetPassword.jsx
|
||||
// Új jelszó megadása
|
||||
|
||||
import { useState } from "react";
|
||||
import Background from "../../assets/backgrounds/Background";
|
||||
import { motion } from "framer-motion";
|
||||
import Button from "../../components/Buttons/Button";
|
||||
import InputBox from "../../components/Inputs/InputBox";
|
||||
|
||||
export default function ResetPassword() {
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (password !== confirmPassword) {
|
||||
setError("A jelszavak nem egyeznek.");
|
||||
return;
|
||||
}
|
||||
setError("");
|
||||
// Backend API
|
||||
console.log("Új jelszó:", password);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative flex items-center justify-center min-h-screen bg-gray-100 p-0 font-poppins">
|
||||
<Background />
|
||||
<motion.div
|
||||
initial={{ height: "auto" }}
|
||||
animate={{ height: "350px" }}
|
||||
transition={{ duration: 0.5, ease: "easeInOut" }}
|
||||
className="absolute flex max-w-2xl w-full bg-white rounded-2xl shadow-lg overflow-hidden items-center justify-center"
|
||||
>
|
||||
<div className="w-full p-10 relative">
|
||||
<h2 className="text-4xl font-extrabold text-center mb-6 text-gray-800 tracking-wide">
|
||||
Új jelszó megadása
|
||||
</h2>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<InputBox
|
||||
type="password"
|
||||
placeholder="Új jelszó"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<InputBox
|
||||
type="password"
|
||||
placeholder="Új jelszó megerősítése"
|
||||
value={confirmPassword}
|
||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||
/>
|
||||
{error && (
|
||||
<div className="text-red-500 text-sm mb-2">{error}</div>
|
||||
)}
|
||||
<Button text="Jelszó beállítása" type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
import React from "react"
|
||||
import Navbar from "../../components/Navbar/Navbar.jsx"
|
||||
import Footer from "../../components/Footer/Footer.jsx"
|
||||
import Background from "../../assets/backgrounds/Background"
|
||||
import {
|
||||
FaBuilding,
|
||||
FaEnvelope,
|
||||
FaHandshake,
|
||||
FaPalette,
|
||||
FaTags,
|
||||
FaUserCheck,
|
||||
FaDollarSign,
|
||||
FaChartLine,
|
||||
FaVideo,
|
||||
FaHandsHelping,
|
||||
FaTrophy,
|
||||
FaChartBar,
|
||||
FaUsers,
|
||||
FaHeadset,
|
||||
} from "react-icons/fa"
|
||||
|
||||
const Card = ({ icon, label, description, targetId, className }) => {
|
||||
const handleClick = () => {
|
||||
const section = document.getElementById(targetId)
|
||||
if (section) {
|
||||
section.scrollIntoView({ behavior: "smooth" })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={handleClick}
|
||||
className={`cursor-pointer hover:scale-105 transition-all duration-300 border border-gray-400 shadow-lg rounded-2xl p-8 w-72 text-center animate-fadeInUp ${className}`}
|
||||
>
|
||||
<div className="text-5xl mb-4 flex justify-center">{icon}</div>
|
||||
<h3 className="text-2xl font-bold mb-2">{label}</h3>
|
||||
<p className="text-white/90 text-sm">{description}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const SectionContainer = ({ id, title, children }) => {
|
||||
return (
|
||||
<section
|
||||
id={id}
|
||||
className="mt-20 mb-28 px-4 md:px-0 opacity-100 animate-fadeInUp"
|
||||
>
|
||||
<div className="text-center mb-12">
|
||||
<h2 className="text-4xl font-bold border-b-4 inline-block border-emerald-400 pb-2 text-white">
|
||||
{title}
|
||||
</h2>
|
||||
</div>
|
||||
{children}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
const CompanyHub = () => {
|
||||
return (
|
||||
<div className="relative min-h-screen text-white">
|
||||
{/* Background fixed behind everything */}
|
||||
<div className="fixed inset-0 -z-10">
|
||||
<Background />
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 flex flex-col min-h-screen">
|
||||
<Navbar />
|
||||
|
||||
<main className="flex-grow relative px-4 py-8 md:px-12 md:py-16 overflow-y-auto scroll-smooth">
|
||||
<div className="flex justify-center gap-6 mt-8 flex-wrap">
|
||||
<Card
|
||||
icon={<FaBuilding />}
|
||||
label="Mit nyújtunk"
|
||||
description="Játékosított tanulási platform cégeknek."
|
||||
targetId="intro"
|
||||
className="bg-gradient-to-br from-pink-500 via-purple-600 to-purple-800"
|
||||
/>
|
||||
<Card
|
||||
icon={<FaEnvelope />}
|
||||
label="Kapcsolat"
|
||||
description="Lépj kapcsolatba velünk vagy kérj ajánlatot!"
|
||||
targetId="contact"
|
||||
className="bg-gradient-to-br from-blue-700 to-blue-500"
|
||||
/>
|
||||
<Card
|
||||
icon={<FaHandshake />}
|
||||
label="Csatlakozás"
|
||||
description="Legyél partnerünk, és fejlődj velünk!"
|
||||
targetId="join"
|
||||
className="bg-gradient-to-br from-green-700 to-green-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Mit nyújtunk */}
|
||||
<SectionContainer id="intro" title="Mit nyújtunk cégeknek">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-10">
|
||||
{/* Egyénre szabás */}
|
||||
<div className="bg-white/5 rounded-3xl border border-gray-700 shadow-lg p-10 flex flex-col gap-8">
|
||||
<h3 className="text-2xl font-extrabold flex items-center gap-4 text-emerald-400">
|
||||
<FaPalette className="text-4xl" />
|
||||
Egyénre szabás
|
||||
</h3>
|
||||
<ul className="list-disc ml-6 space-y-4 text-white/90 text-lg">
|
||||
<li className="flex items-center gap-4">
|
||||
<FaUserCheck className="text-green-400 text-2xl" />
|
||||
Testreszabható design és színek
|
||||
</li>
|
||||
<li className="flex items-center gap-4">
|
||||
<FaTrophy className="text-yellow-400 text-2xl" />
|
||||
Egyedi badge és jutalmazási rendszer
|
||||
</li>
|
||||
<li className="flex items-center gap-4">
|
||||
<FaChartBar className="text-blue-400 text-2xl" />
|
||||
Fejlődési útvonalak
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Árazás */}
|
||||
<div className="bg-white/5 rounded-3xl border border-gray-700 shadow-lg p-10 flex flex-col gap-8">
|
||||
<h3 className="text-2xl font-extrabold flex items-center gap-4 text-emerald-400">
|
||||
<FaDollarSign className="text-4xl" />
|
||||
Árazás
|
||||
</h3>
|
||||
<ul className="list-disc ml-6 space-y-4 text-white/90 text-lg">
|
||||
<li className="flex items-center gap-4">
|
||||
<FaUsers className="text-purple-400 text-2xl" />
|
||||
Kedvezményes csomagok KKV-knak
|
||||
</li>
|
||||
<li className="flex items-center gap-4">
|
||||
<FaChartLine className="text-indigo-400 text-2xl" />
|
||||
Testreszabott megoldások
|
||||
</li>
|
||||
<li className="flex items-center gap-4">
|
||||
<FaTags className="text-pink-400 text-2xl" />
|
||||
Nincs rejtett költség
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Demó videó */}
|
||||
<div className="bg-white/5 rounded-3xl border border-gray-700 shadow-lg p-10 flex flex-col gap-8">
|
||||
<h3 className="text-2xl font-extrabold flex items-center gap-4 text-emerald-400">
|
||||
<FaVideo className="text-4xl" />
|
||||
Csapatunk videó
|
||||
</h3>
|
||||
<video controls className="w-full rounded-xl shadow-xl">
|
||||
<source src="/demo.mp4" type="video/mp4" />
|
||||
A böngésződ nem támogatja a videó lejátszását.
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
</SectionContainer>
|
||||
|
||||
{/* Contact + Join Section */}
|
||||
<section className="grid md:grid-cols-2 gap-10 max-w-6xl mx-auto mt-20 mb-28 px-4 md:px-0">
|
||||
{/* Contact */}
|
||||
<div
|
||||
id="contact"
|
||||
className="bg-white/10 p-8 rounded-xl border border-gray-500 shadow-lg"
|
||||
>
|
||||
<h2 className="text-3xl font-bold mb-6 text-center border-b-4 border-emerald-400 pb-2 text-white">
|
||||
Kapcsolatfelvétel cégeknek
|
||||
</h2>
|
||||
<form className="grid gap-6 md:grid-cols-2">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Cég neve"
|
||||
className="bg-white/20 text-white placeholder-white px-5 py-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-400 col-span-2"
|
||||
/>
|
||||
<input
|
||||
type="email"
|
||||
placeholder="Email"
|
||||
className="bg-white/20 text-white placeholder-white px-5 py-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-400 col-span-2 md:col-span-1"
|
||||
/>
|
||||
<textarea
|
||||
placeholder="Üzenet"
|
||||
rows="6"
|
||||
className="bg-white/20 text-white placeholder-white px-5 py-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-400 col-span-2"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-emerald-500 hover:bg-emerald-400 text-white px-8 py-4 rounded-lg font-bold col-span-2 md:col-span-1 transition"
|
||||
>
|
||||
Küldés
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{/* Join */}
|
||||
<div
|
||||
id="join"
|
||||
className="bg-white/10 p-8 rounded-xl border border-gray-500 shadow-lg"
|
||||
>
|
||||
<h2 className="text-3xl font-bold mb-6 text-center border-b-4 border-emerald-400 pb-2 text-white">
|
||||
Csatlakozz partnerként
|
||||
</h2>
|
||||
<ul className="list-disc space-y-4 ml-8 text-base text-white/90">
|
||||
<li className="flex gap-3 items-center">
|
||||
<FaHandsHelping className="text-green-400 text-xl flex-shrink-0" />
|
||||
Gamification a vállalati kultúrában
|
||||
</li>
|
||||
<li className="flex gap-3 items-center">
|
||||
<FaChartBar className="text-blue-400 text-xl flex-shrink-0" />
|
||||
Teljesítménymérés játékosan
|
||||
</li>
|
||||
<li className="flex gap-3 items-center">
|
||||
<FaUserCheck className="text-yellow-400 text-xl flex-shrink-0" />
|
||||
Személyre szabott riportok
|
||||
</li>
|
||||
<li className="flex gap-3 items-center">
|
||||
<FaHeadset className="text-pink-400 text-xl flex-shrink-0" />
|
||||
Dedikált ügyfélszolgálat
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CompanyHub
|
||||
@@ -0,0 +1,16 @@
|
||||
// src/pages/Decks/DeckManagerPage.jsx
|
||||
// Deck Management Page (with Navbar, no Footer)
|
||||
|
||||
import DeckManager from "../../components/Landingpage/DeckManager.jsx"
|
||||
import Navbar from "../../components/Navbar/Navbar.jsx"
|
||||
|
||||
export default function DeckManagerPage() {
|
||||
return (
|
||||
<div className="w-full min-h-screen bg-background flex flex-col relative overflow-x-hidden">
|
||||
<Navbar />
|
||||
<main className="flex-1 flex flex-col items-center justify-start min-h-0">
|
||||
<DeckManager />
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
import React, { useState } from "react"
|
||||
import { getVerticalOffset } from "../../utils/randomUtils"
|
||||
import Dice from "../../utils/dice/Dice"
|
||||
|
||||
const GameScreen = () => {
|
||||
const boardRows = 5
|
||||
const boardCols = 20
|
||||
const totalCells = boardRows * boardCols
|
||||
const cellSize = 40
|
||||
const cellMargin = 2.5
|
||||
const rowSpacing = 70 // Extra spacing between rows
|
||||
const topOffset = rowSpacing * 0.5 // Increase topOffset for more spacing
|
||||
const bottomOffset = rowSpacing * 0.5 // Increase bottomOffset for more spacing
|
||||
const boardWidthPx = boardCols * (cellSize + cellMargin * 2)
|
||||
const boardHeightPx =
|
||||
boardRows * (cellSize + cellMargin * 2 + rowSpacing) + topOffset + bottomOffset - rowSpacing
|
||||
|
||||
// Generate a snake-like path with vertical spacing and vertical offsets
|
||||
const generateWindingPath = () => {
|
||||
const path = []
|
||||
let currentNum = 1
|
||||
|
||||
for (let row = 0; row < boardRows && currentNum <= totalCells; row++) {
|
||||
// Calculate the y position with extra row spacing
|
||||
const baseYPosition = topOffset + row * (cellSize + cellMargin * 2 + rowSpacing)
|
||||
|
||||
// If row number is even, go right; if odd, go left
|
||||
if (row % 2 === 0) {
|
||||
// Left to right
|
||||
for (let col = 0; col < boardCols && currentNum <= totalCells; col++) {
|
||||
path.push({
|
||||
number: currentNum++,
|
||||
x: col * (cellSize + cellMargin * 2),
|
||||
y: baseYPosition + getVerticalOffset(currentNum - 1),
|
||||
type: getFieldType(currentNum - 1),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Right to left
|
||||
for (let col = boardCols - 1; col >= 0 && currentNum <= totalCells; col--) {
|
||||
path.push({
|
||||
number: currentNum++,
|
||||
x: col * (cellSize + cellMargin * 2),
|
||||
y: baseYPosition + getVerticalOffset(currentNum - 1),
|
||||
type: getFieldType(currentNum - 1),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
const getFieldType = (count) => {
|
||||
if (count % 17 === 0) return "clover"
|
||||
if (count % 13 === 0) return "bad"
|
||||
if ((count + 5) % 13 === 0) return "good"
|
||||
return "regular"
|
||||
}
|
||||
|
||||
const [path, setPath] = useState(generateWindingPath())
|
||||
const [players, setPlayers] = useState([
|
||||
{ id: 1, name: "Béla", position: 34, score: 25, color: "bg-blue-600", emoji: "🐍" },
|
||||
{ id: 2, name: "Juci", position: 50, score: 30, color: "bg-green-600", emoji: "🐢" },
|
||||
{ id: 3, name: "Kati", position: 70, score: 15, color: "bg-purple-600", emoji: "🐇" },
|
||||
{ id: 3, name: "Fürtös", position: 68, score: 14, color: "bg-yellow-600", emoji: "😂" },
|
||||
])
|
||||
|
||||
// Sort players by position in descending order
|
||||
const sortedPlayers = [...players].sort((a, b) => b.position - a.position)
|
||||
|
||||
// Handle dice roll
|
||||
const handleDiceRoll = (value) => {
|
||||
console.log("Rolled:", value)
|
||||
// You can add logic here to move the current player based on the dice value
|
||||
}
|
||||
|
||||
console.log("Generated path length:", path.length)
|
||||
|
||||
const getFieldStyle = (type) => {
|
||||
switch (type) {
|
||||
case "clover":
|
||||
return "bg-teal-700 border-teal-500 shadow-teal-800"
|
||||
case "bad":
|
||||
return "bg-red-800 border-red-600 shadow-red-900"
|
||||
case "good":
|
||||
return "bg-blue-800 border-blue-600 shadow-blue-900"
|
||||
default:
|
||||
return "bg-gray-800 border-gray-600 shadow-gray-900"
|
||||
}
|
||||
}
|
||||
|
||||
const getPlayerPosition = (playerPosition) => {
|
||||
const field = path.find((p) => p.number === playerPosition)
|
||||
return field ? { top: `${field.y}px`, left: `${field.x}px` } : { top: 0, left: 0 }
|
||||
}
|
||||
|
||||
// Function to get medal style based on rank
|
||||
const getMedalStyle = (rank) => {
|
||||
switch (rank) {
|
||||
case 1:
|
||||
return "bg-yellow-400 text-yellow-900 border-yellow-500 shadow-yellow-600"
|
||||
case 2:
|
||||
return "bg-gray-400 text-gray-900 border-gray-500 shadow-gray-600"
|
||||
case 3:
|
||||
return "bg-orange-500 text-orange-900 border-orange-600 shadow-orange-700"
|
||||
default:
|
||||
return "bg-gray-700 text-gray-300 border-gray-600 shadow-gray-800"
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-4 bg-gradient-to-br from-gray-900 via-gray-800 to-teal-900 min-h-screen flex items-center justify-center">
|
||||
<div className="w-full">
|
||||
<div className="flex flex-col md:flex-row gap-6 justify-center">
|
||||
{/* Game Board */}
|
||||
<div className="relative bg-gray-800 p-6 rounded-2xl shadow-xl border border-teal-700 flex flex-col items-center justify-center overflow-hidden">
|
||||
{/* Háttér */}
|
||||
<div className="absolute w-full h-full opacity-10 pointer-events-none overflow-hidden">
|
||||
{[...Array(35)].map((_, i) => (
|
||||
// Sajat pulse effect! => node_modules/tailwindcss/index.css:
|
||||
// --animate-pulse8: pulse 6s cubic-bezier(0.4, 0.2, 0.6, 1) infinite;
|
||||
|
||||
<div
|
||||
key={i}
|
||||
className="absolute rounded-full bg-teal-600 animate-pulse8"
|
||||
style={{
|
||||
width: Math.random() * 120 + 40 + "px",
|
||||
height: Math.random() * 120 + 40 + "px",
|
||||
top: Math.random() * 100 + "%",
|
||||
left: Math.random() * 100 + "%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
}}
|
||||
></div>
|
||||
))}
|
||||
</div>
|
||||
<div className="relative" style={{ height: `${boardHeightPx}px`, width: `${boardWidthPx}px` }}>
|
||||
{/* Mezők */}
|
||||
{path.map((field) => (
|
||||
<div
|
||||
key={field.number}
|
||||
className={`absolute w-10 h-10 border-2 flex items-center justify-center transition-all shadow-md hover:scale-110 ${getFieldStyle(
|
||||
field.type
|
||||
)}`}
|
||||
style={{
|
||||
top: `${field.y}px`,
|
||||
left: `${field.x}px`,
|
||||
width: `${cellSize}px`,
|
||||
height: `${cellSize}px`,
|
||||
margin: `${cellMargin}px`,
|
||||
}}
|
||||
>
|
||||
<span className="text-gray-300 text-sm font-bold">{field.number}</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Player tokens */}
|
||||
{players.map((player) => (
|
||||
<div
|
||||
key={player.id}
|
||||
className={`absolute w-6 h-6 ${player.color} rounded-full border-2 border-white shadow-lg flex items-center justify-center text-white text-xs font-bold z-10 animate-bounce`}
|
||||
style={{
|
||||
...getPlayerPosition(player.position),
|
||||
transform: "translate(18px, 18px)",
|
||||
}}
|
||||
>
|
||||
{player.emoji}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Game information */}
|
||||
{/* <div className="bg-white rounded-xl p-2 shadow-lg border border-indigo-100 max-w-3xl mx-auto mt-4 z-10">
|
||||
<p className="text-gray-600 text-sm text-center">
|
||||
<span className="inline-flex items-center mx-2"><span className="w-3 h-3 bg-white border border-gray-300 rounded-full mr-1"></span> Sima</span>
|
||||
<span className="inline-flex items-center mx-2"><span className="w-3 h-3 bg-green-200 border border-green-500 rounded-full mr-1"></span> Lóhere</span>
|
||||
<span className="inline-flex items-center mx-2"><span className="w-3 h-3 bg-red-200 border border-red-500 rounded-full mr-1"></span> Rossz</span>
|
||||
<span className="inline-flex items-center mx-2"><span className="w-3 h-3 bg-blue-200 border border-blue-500 rounded-full mr-1"></span> Jó</span>
|
||||
</p>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
{/* Right sidebar */}
|
||||
<div className="flex-1 max-w-md">
|
||||
<div className="bg-gray-800 rounded-xl p-4 shadow-lg mb-4 border border-teal-700">
|
||||
<h2 className="text-xl font-semibold mb-3 text-teal-300">Játékosok</h2>
|
||||
{sortedPlayers.map((player, index) => (
|
||||
<div
|
||||
key={player.id}
|
||||
className="flex items-center mb-3 p-2 bg-gray-900 rounded-lg hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
<div
|
||||
className={`w-8 h-8 ${player.color} rounded-full mr-3 flex items-center justify-center text-white text-sm font-bold shadow-md`}
|
||||
>
|
||||
{player.emoji}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="font-medium text-sm text-gray-300 flex items-center">
|
||||
{player.name}
|
||||
<span
|
||||
className={`ml-2 px-2 py-1 rounded-full border text-xs font-bold shadow-md ${getMedalStyle(
|
||||
index + 1
|
||||
)}`}
|
||||
>
|
||||
{index + 1 === 1
|
||||
? "🥇 1st"
|
||||
: index + 1 === 2
|
||||
? "🥈 2nd"
|
||||
: index + 1 === 3
|
||||
? "🥉 3rd"
|
||||
: `${index + 1}th`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">
|
||||
Pozíció: {player.position} • Pontszám: {player.score}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Dice Container */}
|
||||
<div className="bg-gray-800 rounded-xl p-4 shadow-lg border border-teal-700 text-center">
|
||||
<h2 className="text-xl font-semibold mb-3 text-teal-300">Dobókocka</h2>
|
||||
<p className="text-gray-300 text-sm mb-4">Kattints a kockára dobáshoz!</p>
|
||||
<Dice onRoll={handleDiceRoll} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default GameScreen
|
||||
@@ -0,0 +1,35 @@
|
||||
// src/pages/Home/Home.jsx
|
||||
// Régi PlayMenu-s oldal, "Home" néven
|
||||
|
||||
import { useState } from "react"
|
||||
import Navbar from "../../components/Navbar/Navbar"
|
||||
import Footer from "../../components/Footer/Footer.jsx"
|
||||
import Background from "../../assets/backgrounds/Background.jsx"
|
||||
import PlayMenu from "../../components/Landingpage/PlayMenu.jsx"
|
||||
|
||||
export default function Home() {
|
||||
// Dummy callbackok és user példa
|
||||
const handleJoinGame = (code) => {
|
||||
alert(`Csatlakozás játékhoz: ${code}`)
|
||||
}
|
||||
const handleCreateGame = () => {
|
||||
alert("Új játék létrehozása")
|
||||
}
|
||||
const user = { name: "Teszt Elek" }
|
||||
|
||||
return (
|
||||
<div className="w-full min-h-screen flex flex-col relative overflow-x-hidden">
|
||||
<div className="fixed inset-0 -z-10 pointer-events-none">
|
||||
<Background />
|
||||
</div>
|
||||
<div className="fixed top-0 left-0 right-0 z-30">
|
||||
<Navbar />
|
||||
</div>
|
||||
<main className="flex-1 flex flex-col items-center justify-start py-15 min-h-0 mt-[64px]">
|
||||
<PlayMenu onJoinGame={handleJoinGame} onCreateGame={handleCreateGame} user={user} />
|
||||
{/* Ide jöhetnek további szekciók, ha szeretnél még tartalmat */}
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// src/pages/Home/Home.jsx
|
||||
// Régi PlayMenu-s oldal, "Home" néven
|
||||
|
||||
import { useState } from "react"
|
||||
import Navbar from "../../components/Navbar/Navbar.jsx"
|
||||
import Footer from "../../components/Footer/Footer.jsx"
|
||||
import Background from "../../assets/backgrounds/Background.jsx"
|
||||
import PlayMenu from "../../components/Landingpage/PlayMenu.jsx"
|
||||
|
||||
export default function Home() {
|
||||
// Dummy callbackok és user példa
|
||||
const handleJoinGame = (code) => {
|
||||
alert(`Csatlakozás játékhoz: ${code}`)
|
||||
}
|
||||
const handleCreateGame = () => {
|
||||
alert("Új játék létrehozása")
|
||||
}
|
||||
const user = { name: "Teszt Elek" }
|
||||
|
||||
return (
|
||||
<div className="w-full min-h-screen flex flex-col relative overflow-x-hidden">
|
||||
<div className="fixed inset-0 -z-10 pointer-events-none">
|
||||
<Background />
|
||||
</div>
|
||||
<div className="fixed top-0 left-0 right-0 z-30">
|
||||
<Navbar />
|
||||
</div>
|
||||
<main className="flex-1 flex flex-col items-center justify-start py-15 min-h-0 mt-[64px]">
|
||||
<PlayMenu onJoinGame={handleJoinGame} onCreateGame={handleCreateGame} user={user} />
|
||||
{/* Ide jöhetnek további szekciók, ha szeretnél még tartalmat */}
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// src/pages/Landing/Landingpage.jsx
|
||||
// Főoldal - Landing Page
|
||||
|
||||
import { useState } from "react"
|
||||
import Navbar from "../../components/Navbar/Navbar"
|
||||
import Footer from "../../components/Footer/Footer.jsx"
|
||||
import Background from "../../assets/backgrounds/Background.jsx"
|
||||
import LandingPage from "../../components/Landingpage/LandingPage.jsx"
|
||||
|
||||
export default function LandingPageMain() {
|
||||
// Navigációs callbackok
|
||||
const handleNavigateToPlay = () => {
|
||||
// Itt lehet navigálni a játék oldalra
|
||||
alert("Navigáció a játék oldalra")
|
||||
}
|
||||
|
||||
const handleNavigateToAuth = () => {
|
||||
// Itt lehet navigálni a bejelentkezés oldalra
|
||||
alert("Navigáció a bejelentkezés oldalra")
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full min-h-screen flex flex-col relative overflow-x-hidden">
|
||||
<div className="fixed inset-0 -z-10 pointer-events-none">
|
||||
<Background />
|
||||
</div>
|
||||
<div className="fixed top-0 left-0 right-0 z-30">
|
||||
<Navbar />
|
||||
</div>
|
||||
<main className="flex-1 flex flex-col items-center justify-start py-15 min-h-0 mt-[64px]">
|
||||
<LandingPage onNavigateToPlay={handleNavigateToPlay} onNavigateToAuth={handleNavigateToAuth} />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import { useState } from "react"
|
||||
import Button from "../../components/Buttons/Button"
|
||||
import InputBox from "../../components/Inputs/InputBox"
|
||||
import PopUp from "../../components/PopUp/PopUp"
|
||||
import Logo from "../../assets/pictures/Logo.jsx"
|
||||
import Navbar from "../../components/Navbar/Navbar"
|
||||
import Footer from "../../components/Footer/Footer.jsx"
|
||||
import UserProfile from "../../components/Userdetails/Userdetails.jsx"
|
||||
import CompanyHub from "../Companies/Companies.jsx"
|
||||
|
||||
import RatingSet from "../../components/PopUp/RatingSet" // <- statisztikai komponens
|
||||
|
||||
export default function Test() {
|
||||
const [showRegistrationPopup, setShowRegistrationPopup] = useState(false)
|
||||
const [showPreviewPopup, setShowPreviewPopup] = useState(false) // <- új state
|
||||
const [inputValue, setInputValue] = useState("")
|
||||
|
||||
return (
|
||||
<div className="w-full h-screen flex flex-col">
|
||||
<Navbar />
|
||||
<UserProfile />
|
||||
<CompanyHub />
|
||||
|
||||
<div className="flex-1 flex flex-col items-center justify-center space-y-6">
|
||||
<InputBox
|
||||
placeholder="E-mail cím"
|
||||
type="text"
|
||||
width="w-1/2"
|
||||
value={inputValue}
|
||||
onChange={(e) => setInputValue(e.target.value)}
|
||||
/>
|
||||
|
||||
<div className="flex flex-col sm:flex-row sm:space-x-4 space-y-4 sm:space-y-0 w-1/2">
|
||||
<Button
|
||||
text="Regisztráció"
|
||||
type="button"
|
||||
width="w-full"
|
||||
onClick={() => setShowRegistrationPopup(true)}
|
||||
/>
|
||||
<Button
|
||||
text="Előnézet"
|
||||
type="button"
|
||||
width="w-full"
|
||||
onClick={() => setShowPreviewPopup(true)} // <- másik state trigger
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Regisztrációs popup */}
|
||||
{showRegistrationPopup && (
|
||||
<PopUp onClose={() => setShowRegistrationPopup(false)}>
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
{/* <Logo size={120} /> */}
|
||||
<h1 className="text-2xl font-bold text-center">Sikeres regisztráció!</h1>
|
||||
<p className="text-center text-gray-600">
|
||||
Kérjük, erősítsd meg az e-mail címedet!
|
||||
<br />
|
||||
Egy megerősítő linket küldtünk az általad megadott e-mail címre
|
||||
<span className="font-semibold text-black"> {inputValue}</span>.
|
||||
</p>
|
||||
<p className="text-center text-sm text-gray-500">
|
||||
Ha nem kaptad meg a levelet, ellenőrizd a spam mappádat is!
|
||||
</p>
|
||||
<Button text="Bezár" type="button" width="w-24" onClick={() => setShowRegistrationPopup(false)} />
|
||||
</div>
|
||||
</PopUp>
|
||||
)}
|
||||
|
||||
{/* Előnézeti popup (RatingSet) */}
|
||||
{showPreviewPopup && (
|
||||
<PopUp onClose={() => setShowPreviewPopup(false)}>
|
||||
<RatingSet />
|
||||
</PopUp>
|
||||
)}
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user