merge commit

This commit is contained in:
2025-08-25 22:16:00 +02:00
23927 changed files with 1148493 additions and 2711691 deletions
+27
View File
@@ -0,0 +1,27 @@
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
.cache
logs
*.log
.DS_Store
.vscode
.idea
*.swp
*.swo
dist
build
.next
.nuxt
.vuepress/dist
.serverless
.fusebox/
.dynamodb/
.tern-port
+60
View File
@@ -0,0 +1,60 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
# Enable gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Handle client routing
location / {
try_files $uri $uri/ /index.html;
}
# API proxy to backend
location /api/ {
proxy_pass http://backend:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
# WebSocket support
location /socket.io/ {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Static assets caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
+3 -4
View File
@@ -10,10 +10,8 @@ import Landingpage from "./pages/Landing/Landingpage"
import Home from "./pages/Landing/Home"
import DeckManagerPage from "./pages/Decks/DeckManagerPage"
import CompanyHub from "./pages/Companies/Companies"
import About from "./pages/About/About"
import ScrollToTop from "./components/ScrollToTop";
function App() {
const [isMobile, setIsMobile] = useState(false)
@@ -44,6 +42,7 @@ function App() {
return (
<Router>
<Routes>
<Route path="/about" element={<About />} />
<Route path="/register" element={<AuthRegister />} />
<Route path="/login" element={<AuthLogin />} />
<Route path="/verify-email" element={<EmailVerification />} />
@@ -93,3 +93,4 @@
fill: #ffffff;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

@@ -1,54 +1,112 @@
import React from "react"
import React, { useEffect, useRef, useState } from "react"
import { Link } from "react-router-dom"
import Logo from "../../assets/pictures/Logo"
const Footer = () => (
<footer className="bg-zinc-900 text-white border-t-2 border-zinc-800 mt-auto py-8">
<div className="max-w-6xl mx-auto flex flex-wrap justify-between items-start gap-8 px-4">
<div className="flex flex-col items-center">
<Logo size={100} />
<span className="font-bold text-lg mt-2">SerpentRace</span>
const ArrowUpIcon = () => <span style={{ fontSize: "1.25rem" }}></span>
const Footer = () => {
const [isVisible, setIsVisible] = useState(false)
const footerRef = useRef(null)
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
setIsVisible(entry.isIntersecting)
},
{ threshold: 0.3 }
)
if (footerRef.current) {
observer.observe(footerRef.current)
}
return () => {
if (footerRef.current) {
observer.unobserve(footerRef.current)
}
}
}, [])
const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: "smooth" })
}
return (
<footer
ref={footerRef}
className={`relative bg-zinc-900 text-white border-t-2 border-zinc-800 mt-auto py-8 transition-all duration-700 ease-out ${
isVisible ? "opacity-100 scale-100 translate-y-0" : "opacity-0 scale-95 translate-y-10"
}`}
style={{ transformOrigin: "bottom center" }}
>
<style>
{`
.footer-animate {
transition: opacity 0.8s ease, transform 0.8s ease;
}
`}
</style>
<div className="max-w-6xl mx-auto flex flex-wrap justify-between items-start gap-8 px-4">
{/* Logó */}
<div className="flex flex-col items-center footer-animate">
<a
href="/"
className="transition-transform duration-500 hover:scale-105 hover:brightness-125"
>
<Logo size={100} />
</a>
<span className="font-extrabold text-xl mt-2 tracking-wide">SerpentRace</span>
</div>
{/* Oldalak */}
<div className="flex flex-col gap-1 footer-animate">
<span className="text-lg font-semibold text-green-400 underline underline-offset-4 mb-2 drop-shadow-sm">
Oldalak
</span>
<a href="/" className="hover:underline hover:text-green-400 transition">Főoldal</a>
<a href="/about" className="hover:underline hover:text-green-400 transition">
Rólunk
</a>
<a href="/contact" className="hover:underline hover:text-green-400 transition">Kapcsolat</a>
</div>
{/* Közösség */}
<div className="flex flex-col gap-1 footer-animate">
<span className="text-lg font-semibold text-green-400 underline underline-offset-4 mb-2 drop-shadow-sm">
Közösség
</span>
<a href="https://discord.gg/" target="_blank" rel="noopener noreferrer" className="hover:underline hover:text-green-400 transition">Discord</a>
<a href="https://github.com/" target="_blank" rel="noopener noreferrer" className="hover:underline hover:text-green-400 transition">GitHub</a>
</div>
{/* Elérhetőség */}
<div className="flex flex-col gap-1 footer-animate">
<span className="text-lg font-semibold text-green-400 underline underline-offset-4 mb-2 drop-shadow-sm">
Elérhetőség
</span>
<span className="opacity-80">Email: info@serpentrace.hu</span>
<span className="opacity-80">Telefon: +36 30 123 4567</span>
</div>
</div>
<div className="flex flex-col gap-1">
<span className="font-bold mb-2">Oldalak</span>
<a href="/" className="hover:underline hover:text-green-400 transition">
Főoldal
</a>
<a href="/about" className="hover:underline hover:text-green-400 transition">
Rólunk
</a>
<a href="/contact" className="hover:underline hover:text-green-400 transition">
Kapcsolat
</a>
<div className="text-center mt-8 text-sm opacity-70 footer-animate">
© {new Date().getFullYear()} SerpentRace. Minden jog fenntartva.
</div>
<div className="flex flex-col gap-1">
<span className="font-bold mb-2">Közösség</span>
<a
href="https://discord.gg/"
target="_blank"
rel="noopener noreferrer"
className="hover:underline hover:text-green-400 transition"
{/* Scroll to top */}
{isVisible && (
<button
onClick={scrollToTop}
className="fixed bottom-6 right-6 bg-green-500 hover:bg-green-600 text-white p-3 rounded-full shadow-lg transition transform hover:scale-110"
aria-label="Ugrás az oldal tetejére"
>
Discord
</a>
<a
href="https://github.com/"
target="_blank"
rel="noopener noreferrer"
className="hover:underline hover:text-green-400 transition"
>
GitHub
</a>
</div>
<div className="flex flex-col gap-1">
<span className="font-bold mb-2">Elérhetőség</span>
<span className="opacity-80">Email: info@serpentrace.hu</span>
<span className="opacity-80">Telefon: +36 30 123 4567</span>
</div>
</div>
<div className="text-center mt-8 text-sm opacity-70">
© {new Date().getFullYear()} SerpentRace. Minden jog fenntartva.
</div>
</footer>
)
<ArrowUpIcon />
</button>
)}
</footer>
)
}
export default Footer
@@ -1,5 +1,6 @@
import React, { useState } from "react"
import Logo from "../../assets/pictures/Logo"
import About from "../../pages/About/About"
const navLinkClass = "px-3 py-2 rounded-lg text-white transition-all duration-200 hover:bg-white/10"
@@ -7,6 +8,7 @@ const Navbar = () => {
const [menuOpen, setMenuOpen] = useState(false)
return (
<nav className="bg-gradient-to-r from-green-700 to-emerald-500 shadow-lg">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16 items-center">
@@ -27,7 +29,7 @@ const Navbar = () => {
<a href="#" className={navLinkClass}>
Leaderboard
</a>
<a href="#" className={navLinkClass}>
<a href="/about" className={navLinkClass}>
About
</a>
<a href="#" className={navLinkClass}>
@@ -0,0 +1,59 @@
import { useState } from "react";
import Button from "../../components/Buttons/Button";
import InputBox from "../../components/Inputs/InputBox";
import PopUp from "../../components/PopUp/PopUp";
const jatekEredmenyek = [
{ helyezes: 1, datum: "2025-03-24 14:22" },
{ helyezes: 5, datum: "2025-03-24 14:20" },
{ helyezes: 3, datum: "2025-03-24 14:18" },
{ helyezes: 4, datum: "2025-03-24 14:15" },
];
export default function Test() {
const [showPopup, setShowPopup] = useState(false);
const [inputValue, setInputValue] = useState("");
return (
<div className="w-full h-screen 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)}
/>
<Button
text="Játék Előzmények"
type="button"
width="w-1/2"
onClick={() => setShowPopup(true)}
/>
{showPopup && (
<PopUp onClose={() => setShowPopup(false)}>
<div className="p-6 w-full max-w-md">
<h1 className="text-2xl font-bold text-center mb-4">Játék Előzmények</h1>
<div className="space-y-3">
{jatekEredmenyek.map((eredmeny, index) => (
<div
key={index}
className={`flex justify-between items-center rounded-lg p-4 shadow-md ${
eredmeny.helyezes <= 3 ? "border-l-4 border-green-500" : "border-l-4 border-blue-500"
} bg-gray-50`}
>
<p className="text-gray-800 font-semibold">
Felhasználónév {eredmeny.helyezes}. helyezés
</p>
<span className="text-sm text-gray-500">{eredmeny.datum}</span>
</div>
))}
</div>
<div className="flex justify-center mt-6">
<Button text="Bezár" type="button" width="w-24" onClick={() => setShowPopup(false)} />
</div>
</div>
</PopUp>
)}
</div>
);
}
@@ -0,0 +1,27 @@
// src/components/PopUp/RatingSet.jsx
export default function RatingSet() {
// Ezeket lehet később props-ból vagy API-ból is betölteni
const stats = [
{ label: "Win Rate", value: "68%" },
{ label: "Success Rate", value: "85%" },
{ label: "My cards rate", value: "72%" },
];
return (
<div className="p-6 w-full max-w-md">
<h1 className="text-2xl font-bold text-center mb-4">Statisztikák</h1>
<div className="space-y-6">
{stats.map((stat, index) => (
<div
key={index}
className="flex justify-between items-center rounded-lg p-4 shadow-md bg-gray-50 border-l-4 border-indigo-500"
>
<p className="text-gray-800 font-semibold">{stat.label}</p>
<span className="text-lg font-bold text-indigo-700">{stat.value}</span>
</div>
))}
</div>
</div>
);
}
@@ -0,0 +1,14 @@
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
const ScrollToTop = () => {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo({ top: 0, behavior: "smooth" });
}, [pathname]);
return null;
};
export default ScrollToTop;
@@ -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
@@ -1,6 +1,3 @@
// src/pages/Testing/Test.jsx
// itt tesztelhetjük a komponenseket illetve bármit
import { useState } from "react"
import Button from "../../components/Buttons/Button"
import InputBox from "../../components/Inputs/InputBox"
@@ -11,10 +8,12 @@ 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 [showPopup, setShowPopup] = useState(false)
const [inputValue, setInputValue] = useState("") // input értékének tárolása
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">
@@ -30,9 +29,25 @@ export default function Test() {
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<Button text="Regisztráció" type="button" width="w-1/2" onClick={() => setShowPopup(true)} />
{showPopup && (
<PopUp onClose={() => setShowPopup(false)}>
<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>
@@ -45,10 +60,17 @@ export default function Test() {
<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={() => setShowPopup(false)} />
<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>
+14
View File
@@ -5,6 +5,20 @@ import tailwindcss from '@tailwindcss/vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), tailwindcss(),],
server: {
host: '0.0.0.0',
port: 5173,
watch: {
usePolling: true,
},
hmr: {
clientPort: 5173,
}
},
preview: {
host: '0.0.0.0',
port: 5173,
}
})