2 Commits

Author SHA1 Message Date
mategergely33 322059ace0 telos nezet landin, home, navbar, footer 2025-11-13 18:54:06 +01:00
mategergely33 0ac5ead63a joker/szerencse kartyak kezelese 2025-11-11 19:00:14 +01:00
7 changed files with 402 additions and 155 deletions
@@ -12,9 +12,9 @@ const Animation = ({ sizePercentage = 100 }) => {
const pathRefs = Array.from({ length: 11 }, () => useRef(null));
return (
<div>
<div className="w-full flex justify-center">
{/* prettier-ignore */}
<svg className={styles.animation} width={width} height={height} viewBox="0 0 1319 198" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg className={styles.animation} width="100%" height="auto" viewBox="0 0 1319 198" fill="none" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" style={{ maxWidth: `${width}px`, maxHeight: `${height}px` }}>
<path ref={pathRefs[0]} className={styles.path0} d="M1261.64 32.9C1272.02 32.9 1281.15 34.9576 1289.1 39.0094L1289.86 39.4078C1297.97 43.7136 1304.29 49.9037 1308.86 58.026L1308.86 58.0328L1308.87 58.0406C1313.41 65.9983 1315.74 75.4878 1315.74 86.6002C1315.74 88.8329 1315.63 91.0662 1315.41 93.3004H1240.77L1240.94 95.9625C1241.36 102.425 1243.14 107.682 1246.63 111.328L1246.67 111.368L1246.71 111.407C1250.29 114.831 1254.8 116.5 1260.04 116.5C1263.69 116.5 1266.97 115.677 1269.77 113.917C1272.15 112.419 1274.06 110.315 1275.55 107.7H1312.61C1310.88 113.608 1308.06 118.989 1304.16 123.859L1303.71 124.408L1303.71 124.413C1299.18 129.919 1293.45 134.322 1286.48 137.611L1285.8 137.925C1278.56 141.229 1270.51 142.9 1261.64 142.9C1250.94 142.9 1241.49 140.648 1233.23 136.205C1225.37 131.905 1219.12 125.83 1214.46 117.933L1214.01 117.164C1209.46 108.936 1207.14 99.1765 1207.14 87.8004C1207.14 76.4113 1209.46 66.7169 1214.01 58.6256L1214.02 58.6187L1214.02 58.6109C1218.45 50.6085 1224.53 44.4249 1232.28 40.0143L1233.04 39.5934C1241.29 35.1536 1250.8 32.9 1261.64 32.9ZM1261.44 58.9C1256.17 58.9 1251.64 60.3691 1248.04 63.4723C1244.4 66.4788 1242.18 70.8761 1241.18 76.3473L1240.63 79.3004H1280.74V76.8004C1280.74 71.5541 1279.01 67.178 1275.39 63.985L1275.04 63.6793C1271.33 60.4557 1266.74 58.9 1261.44 58.9Z" stroke="white" strokeWidth="5"/>
<path ref={pathRefs[1]} className={styles.path1} d="M1139.95 32.9C1153.73 32.9 1165.15 36.6867 1174.38 44.1441L1174.39 44.151L1174.4 44.1578C1182.91 50.9203 1188.68 60.2478 1191.63 72.3004H1154.9C1153.61 69.0944 1151.8 66.4744 1149.4 64.5846C1146.55 62.349 1143.08 61.3004 1139.15 61.3004C1133.38 61.3004 1128.7 63.7808 1125.31 68.5533L1125.31 68.5602L1125.3 68.566C1122.08 73.1723 1120.65 79.708 1120.65 87.8004C1120.65 95.9013 1122.08 102.479 1125.28 107.202L1125.31 107.247C1128.7 112.019 1133.38 114.5 1139.15 114.5C1143.13 114.5 1146.64 113.458 1149.5 111.215C1151.9 109.324 1153.68 106.702 1154.93 103.5H1191.63C1188.77 115.027 1183.29 124.135 1175.24 130.949L1174.38 131.656C1165.15 139.113 1153.73 142.9 1139.95 142.9C1129.25 142.9 1119.8 140.648 1111.55 136.205C1103.69 131.908 1097.51 125.841 1092.97 117.958L1092.54 117.189C1087.98 108.956 1085.65 99.188 1085.65 87.8004C1085.65 76.9027 1087.83 67.4559 1092.12 59.3873L1092.54 58.6109C1096.97 50.6085 1103.05 44.4249 1110.8 40.0143L1111.55 39.5934C1119.81 35.1513 1129.25 32.9 1139.95 32.9Z" stroke="white" strokeWidth="5"/>
<path ref={pathRefs[2]} className={styles.path2} d="M995.014 32.9C1002.18 32.9 1008.26 34.2763 1013.33 36.9322L1013.81 37.193C1019.04 40.0563 1023.04 43.8802 1025.86 48.6695L1030.51 56.5602V34.3004H1064.71V141.5H1030.51V119.24L1025.86 127.13C1023.04 131.905 1019 135.728 1013.63 138.595L1013.61 138.607C1008.45 141.437 1002.27 142.9 995.014 142.9C986.807 142.9 979.357 140.83 972.608 136.697L971.956 136.291C965.401 132.037 960.089 125.994 956.045 118.069L955.657 117.296C951.72 108.895 949.714 99.0842 949.714 87.8004C949.714 76.5091 951.722 66.7655 955.656 58.5035L955.657 58.5045C959.747 50.1977 965.189 43.9003 971.956 39.5094C978.877 35.1054 986.542 32.9 995.014 32.9ZM1007.61 62.1002C1001.29 62.1002 995.894 64.2893 991.601 68.6617L991.217 69.0621C986.771 73.6617 984.714 80.0315 984.714 87.8004C984.714 95.4589 986.781 101.845 991.161 106.678L991.175 106.694L991.189 106.708C995.547 111.367 1001.08 113.7 1007.61 113.7C1014.02 113.7 1019.47 111.363 1023.81 106.738L1023.81 106.739C1028.38 102.021 1030.51 95.5962 1030.51 87.8004C1030.51 80.1231 1028.37 73.771 1023.81 69.0611H1023.81C1019.47 64.436 1014.01 62.1003 1007.61 62.1002Z" stroke="white" strokeWidth="5"/>
@@ -33,10 +33,84 @@ const Footer = () => {
return (
<footer
ref={footerRef}
className="relative bg-zinc-900 text-zinc-400 border-t-2 border-zinc-800 mt-auto py-8"
className="relative bg-zinc-900 text-zinc-400 border-t-2 border-zinc-800 mt-auto py-6 md:py-8"
style={{ transformOrigin: "bottom center" }}
>
<div className="max-w-6xl mx-auto flex flex-wrap justify-between items-start gap-8 px-4">
<div className="max-w-6xl mx-auto px-4">
{/* Mobile: Logo középen, majd grid alatta */}
<div className="flex flex-col items-center md:hidden gap-6 mb-6">
<div className="flex flex-col items-center">
<button
onClick={goLanding}
className="hover:scale-105 hover:brightness-110 transition-transform"
>
<Logo size={80} />
</button>
<button
onClick={goLanding}
className="font-extrabold text-lg mt-2 tracking-wide text-white hover:text-green-500 transition-colors"
>
SerpentRace
</button>
</div>
</div>
{/* Mobile: 2 oszlopos grid */}
<div className="grid grid-cols-2 gap-6 md:hidden mb-6">
{/* Oldalak */}
<div className="flex flex-col gap-1">
<span className="text-base font-semibold text-green-600 underline underline-offset-4 mb-2 drop-shadow-sm">
Oldalak
</span>
<button
onClick={goLanding}
className="text-left text-sm hover:underline hover:text-green-500 transition-colors"
>
Főoldal
</button>
<button
onClick={goAbout}
className="text-left text-sm hover:underline hover:text-green-500 transition-colors"
>
Rólunk
</button>
</div>
{/* Közösség */}
<div className="flex flex-col gap-1">
<span className="text-base font-semibold text-green-600 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="text-sm hover:underline hover:text-green-500"
>
Discord
</a>
<a
href="https://github.com/"
target="_blank"
rel="noopener noreferrer"
className="text-sm hover:underline hover:text-green-500"
>
GitHub
</a>
</div>
</div>
{/* Mobile: Elérhetőség teljes széles */}
<div className="flex flex-col gap-1 md:hidden mb-6">
<span className="text-base font-semibold text-green-600 underline underline-offset-4 mb-2 drop-shadow-sm">
Elérhetőség
</span>
<span className="text-sm opacity-85">Email: info@serpentrace.hu</span>
<span className="text-sm opacity-85">Telefon: +36 30 123 4567</span>
</div>
{/* Desktop: Original flex layout */}
<div className="hidden md:flex flex-wrap justify-between items-start gap-8">
{/* Logó */}
<div className="flex flex-col items-center">
<button
@@ -104,6 +178,7 @@ const Footer = () => {
<span className="opacity-85">Telefon: +36 30 123 4567</span>
</div>
</div>
</div>
<div className="text-center mt-8 text-sm opacity-70">
© {new Date().getFullYear()} SerpentRace. Minden jog fenntartva.
@@ -18,19 +18,21 @@ const LandingPage = () => {
<div className="w-full">
{/* Hero Section */}
<motion.section
className="min-h-[80vh] flex flex-col items-center justify-center text-center px-4 py-20"
className="min-h-[80vh] flex flex-col items-center justify-center text-center px-4 sm:px-6 py-12 sm:py-16 md:py-20"
initial={{ opacity: 0, y: 40 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
>
<div className="max-w-4xl mx-auto">
<div className="max-w-4xl mx-auto w-full">
{/* Animált logo és cím */}
<div className="mb-8">
<div className="mb-6 sm:mb-8 flex justify-center">
<div className="w-full max-w-[90%] sm:max-w-[70%] md:max-w-full">
<SerpentRaceAnimation sizePercentage={70} />
</div>
</div>
<motion.h1
className="text-3xl md:text-5xl font-bold text-white mb-4 leading-tight"
className="text-2xl sm:text-3xl md:text-5xl font-bold text-white mb-3 sm:mb-4 leading-tight px-2"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, delay: 0.4 }}
@@ -39,7 +41,7 @@ const LandingPage = () => {
</motion.h1>
<motion.p
className="text-lg md:text-xl text-gray-300 mb-4 max-w-3xl mx-auto leading-relaxed"
className="text-base sm:text-lg md:text-xl text-gray-300 mb-3 sm:mb-4 max-w-3xl mx-auto leading-relaxed px-2"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, delay: 0.6 }}
@@ -49,7 +51,7 @@ const LandingPage = () => {
</motion.p>
<motion.div
className="text-xl md:text-2xl font-bold text-emerald-400 mb-10"
className="text-lg sm:text-xl md:text-2xl font-bold text-emerald-400 mb-6 sm:mb-8 md:mb-10 px-2"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, delay: 0.8 }}
@@ -58,7 +60,7 @@ const LandingPage = () => {
</motion.div>
<motion.div
className="flex flex-col sm:flex-row gap-4 justify-center items-center"
className="flex flex-col sm:flex-row gap-3 sm:gap-4 justify-center items-center px-2"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, delay: 1 }}
@@ -66,12 +68,12 @@ const LandingPage = () => {
{/* If not authenticated show Login/Register; if authenticated show Home button */}
{!auth ? (
<>
<ButtonGreen text="Bejelentkezés" onClick={goLogin} width="w-60" />
<ButtonGreen text="Regisztráció" onClick={goAuth} width="w-60" />
<ButtonGreen text="Játék" onClick={goHome} width="w-60" />
<ButtonGreen text="Bejelentkezés" onClick={goLogin} width="w-full sm:w-60" />
<ButtonGreen text="Regisztráció" onClick={goAuth} width="w-full sm:w-60" />
<ButtonGreen text="Játék" onClick={goHome} width="w-full sm:w-60" />
</>
) : (
<ButtonGreen text="Játék" onClick={goHome} width="w-60" />
<ButtonGreen text="Játék" onClick={goHome} width="w-full sm:w-60" />
)}
</motion.div>
</div>
@@ -79,7 +81,7 @@ const LandingPage = () => {
{/* Features Section */}
<motion.section
className="py-20 px-4"
className="py-12 sm:py-16 md:py-20 px-4 sm:px-6"
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true, amount: 0.2 }}
@@ -87,7 +89,7 @@ const LandingPage = () => {
>
<div className="max-w-6xl mx-auto">
<motion.h2
className="text-2xl md:text-3xl font-bold text-white text-center mb-12"
className="text-xl sm:text-2xl md:text-3xl font-bold text-white text-center mb-8 sm:mb-10 md:mb-12 px-2"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
@@ -96,19 +98,19 @@ const LandingPage = () => {
Miért a SerpentRace a legjobb választás?
</motion.h2>
<div className="grid md:grid-cols-3 gap-8">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 sm:gap-8">
{/* Feature 1 */}
<motion.div
className="bg-white/10 backdrop-blur-lg rounded-2xl p-8 text-center"
className="bg-white/10 backdrop-blur-lg rounded-xl sm:rounded-2xl p-6 sm:p-8 text-center"
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.7, delay: 0.3 }}
>
<div className="w-16 h-16 mx-auto mb-6 bg-emerald-500 rounded-full flex items-center justify-center">
<FaUsers className="w-8 h-8 text-white" />
<div className="w-12 h-12 sm:w-16 sm:h-16 mx-auto mb-4 sm:mb-6 bg-emerald-500 rounded-full flex items-center justify-center">
<FaUsers className="w-6 h-6 sm:w-8 sm:h-8 text-white" />
</div>
<h3 className="text-lg font-semibold text-white mb-2">Közösségi élmény</h3>
<h3 className="text-base sm:text-lg font-semibold text-white mb-2">Közösségi élmény</h3>
<p className="text-gray-300 text-sm">
Ismerkedj, nevess, tanulj! A SerpentRace összehozza a társaságot, legyen szó baráti
összejövetelről vagy csapatépítésről.
@@ -117,16 +119,16 @@ const LandingPage = () => {
{/* Feature 2 */}
<motion.div
className="bg-white/10 backdrop-blur-lg rounded-2xl p-8 text-center"
className="bg-white/10 backdrop-blur-lg rounded-xl sm:rounded-2xl p-6 sm:p-8 text-center"
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.7, delay: 0.5 }}
>
<div className="w-16 h-16 mx-auto mb-6 bg-emerald-500 rounded-full flex items-center justify-center">
<FaPaintBrush className="w-8 h-8 text-white" />
<div className="w-12 h-12 sm:w-16 sm:h-16 mx-auto mb-4 sm:mb-6 bg-emerald-500 rounded-full flex items-center justify-center">
<FaPaintBrush className="w-6 h-6 sm:w-8 sm:h-8 text-white" />
</div>
<h3 className="text-lg font-semibold text-white mb-2">Személyre szabható</h3>
<h3 className="text-base sm:text-lg font-semibold text-white mb-2">Személyre szabható</h3>
<p className="text-gray-300 text-sm">
Kérdéskártyák, szabályok, design minden a te igényeidhez igazítható, akár céges brandinggel
is!
@@ -135,16 +137,16 @@ const LandingPage = () => {
{/* Feature 3 */}
<motion.div
className="bg-white/10 backdrop-blur-lg rounded-2xl p-8 text-center"
className="bg-white/10 backdrop-blur-lg rounded-xl sm:rounded-2xl p-6 sm:p-8 text-center"
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.7, delay: 0.7 }}
>
<div className="w-16 h-16 mx-auto mb-6 bg-emerald-500 rounded-full flex items-center justify-center">
<FaHeadset className="w-8 h-8 text-white" />
<div className="w-12 h-12 sm:w-16 sm:h-16 mx-auto mb-4 sm:mb-6 bg-emerald-500 rounded-full flex items-center justify-center">
<FaHeadset className="w-6 h-6 sm:w-8 sm:h-8 text-white" />
</div>
<h3 className="text-lg font-semibold text-white mb-2">Folyamatos támogatás</h3>
<h3 className="text-base sm:text-lg font-semibold text-white mb-2">Folyamatos támogatás</h3>
<p className="text-gray-300 text-sm">
Gyors, segítőkész ügyfélszolgálat ha bármilyen kérdésed vagy problémád van, mindig
számíthatsz ránk!
@@ -156,7 +158,7 @@ const LandingPage = () => {
{/* Call to Action Section */}
<motion.section
className="py-20 px-4"
className="py-12 sm:py-16 md:py-20 px-4 sm:px-6"
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.2 }}
@@ -164,17 +166,17 @@ const LandingPage = () => {
>
<div className="max-w-4xl mx-auto text-center">
<motion.div
className="bg-gradient-to-r from-emerald-500/20 to-green-500/20 backdrop-blur-lg rounded-3xl p-12"
className="bg-gradient-to-r from-emerald-500/20 to-green-500/20 backdrop-blur-lg rounded-2xl sm:rounded-3xl p-6 sm:p-8 md:p-12"
initial={{ opacity: 0, scale: 0.95 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.7, delay: 0.3 }}
>
<h2 className="text-2xl md:text-3xl font-bold text-white mb-4">
<h2 className="text-xl sm:text-2xl md:text-3xl font-bold text-white mb-3 sm:mb-4 px-2">
Próbáld ki te is a SerpentRace-t!
</h2>
<p className="text-lg text-gray-300 mb-6">
<p className="text-base sm:text-lg text-gray-300 mb-4 sm:mb-6 px-2">
Legyél részese egy új közösségi élménynek, vagy rendeld meg saját, személyre szabott
társasjátékodat mi mindenben segítünk!
</p>
@@ -182,7 +184,8 @@ const LandingPage = () => {
<ButtonGreen
text="Kapcsolatfelvétel"
onClick={goAbout}
className="px-12 py-4 text-xl font-bold"
className="px-8 sm:px-12 py-3 sm:py-4 text-lg sm:text-xl font-bold"
width="w-full sm:w-auto"
/>
</motion.div>
</div>
@@ -38,19 +38,20 @@ const PlayMenu = ({ onJoinGame, onCreateGame, user, setUser }) => {
return (
<section
className="w-[95%] max-w-6xl mx-auto my-16 flex flex-col md:flex-row items-center justify-center rounded-3xl shadow-2xl overflow-hidden"
className="w-[95%] max-w-6xl mx-auto my-8 md:my-16 flex flex-col md:flex-row items-center justify-center rounded-2xl md:rounded-3xl shadow-2xl overflow-hidden"
style={{
background: "linear-gradient(90deg, var(--color-surface) 30%, var(--color-mint) 100%)",
}}
>
{/* Bal oldali animáció/kép */}
<div className="flex-1 flex items-center justify-center w-full h-full py-10 md:py-0 md:pl-10">
<div className="flex-1 flex items-center justify-center w-full h-full py-6 md:py-10 md:pl-10">
<div className="w-[200px] h-[200px] sm:w-[300px] sm:h-[300px] md:w-[420px] md:h-[420px]">
<LogoCard
imageSrc={logoImg}
containerHeight="420px"
containerWidth="420px"
imageHeight="420px"
imageWidth="420px"
containerHeight="100%"
containerWidth="100%"
imageHeight="100%"
imageWidth="100%"
rotateAmplitude={7}
scaleOnHover={1.03}
showMobileWarning={false}
@@ -58,23 +59,24 @@ const PlayMenu = ({ onJoinGame, onCreateGame, user, setUser }) => {
displayOverlayContent={false}
/>
</div>
</div>
{/* Jobb oldali panel */}
<div className="flex-1 w-full flex items-center justify-center px-6 md:px-12 py-8">
<div className="flex-1 w-full flex items-center justify-center px-4 sm:px-6 md:px-12 py-6 md:py-8">
<div
className="w-full max-w-md rounded-2xl p-6 md:p-8 flex flex-col gap-6"
className="w-full max-w-md rounded-xl md:rounded-2xl p-4 sm:p-6 md:p-8 flex flex-col gap-4 md:gap-6"
style={{ background: "rgba(0,0,0,0.15)", backdropFilter: "blur(6px)" }}
>
<div className="flex items-center justify-between">
{username ? (
<div className="flex items-center gap-3">
<div className="flex items-center gap-2 md:gap-3">
<div
className="w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold"
className="w-8 h-8 md:w-10 md:h-10 rounded-full flex items-center justify-center text-xs md:text-sm font-semibold"
style={{ background: "rgba(34,197,94,0.12)", color: "var(--color-mint)" }}
>
{initials}
</div>
<div className="text-[32px]" style={{ color: "var(--color-muted, #cbd5e1)" }}>
<div className="text-xl sm:text-2xl md:text-[32px]" style={{ color: "var(--color-muted, #cbd5e1)" }}>
<span className="font-medium" style={{ color: "var(--color-text, #fff)" }}>
{username}
</span>
@@ -82,7 +84,7 @@ const PlayMenu = ({ onJoinGame, onCreateGame, user, setUser }) => {
</div>
) : (
<div className="w-full">
<div className="font-semibold mb-3 text-text">Nincs bejelentkezve játssz vendégként:</div>
<div className="font-semibold mb-2 md:mb-3 text-sm md:text-base text-text">Nincs bejelentkezve játssz vendégként:</div>
<InputBoxDark
type="text"
placeholder="Nickname..."
@@ -99,7 +101,7 @@ const PlayMenu = ({ onJoinGame, onCreateGame, user, setUser }) => {
</div>
<div>
<h2 className="font-semibold mb-3 text-text">Csatlakozás játékhoz</h2>
<h2 className="font-semibold mb-2 md:mb-3 text-sm md:text-base text-text">Csatlakozás játékhoz</h2>
<div className={`${error ? "border border-error rounded-lg p-2" : ""}`}>
<InputBoxDark
type="text"
@@ -110,15 +112,15 @@ const PlayMenu = ({ onJoinGame, onCreateGame, user, setUser }) => {
/>
</div>
{error && <div className="text-xs mt-2 text-error">{error}</div>}
<div className="mt-4">
<div className="mt-3 md:mt-4">
<ButtonDark text="Csatlakozás" type="button" onClick={handleJoin} width="w-full" />
</div>
</div>
{username ? (
<div className="border-t border-white/10 pt-4">
<div className="border-t border-white/10 pt-3 md:pt-4">
{username && (
<div>
<h3 className="font-semibold mb-3 text-text">Új játék létrehozása</h3>
<h3 className="font-semibold mb-2 md:mb-3 text-sm md:text-base text-text">Új játék létrehozása</h3>
<ButtonDark text="Játék létrehozása" type="button" onClick={handleCreate} width="w-full" />
</div>
)}
@@ -233,18 +233,17 @@ const Navbar = () => {
</Link>
</div>
) : (
<div className="flex justify-end px-2 pb-2">
<button
onClick={() => {
handleLogout()
setMenuOpen(false)
}}
className="p-2 rounded-full bg-[#166534] hover:bg-[#1f7a45] text-white shadow-lg hover:shadow-green-400/40 transition-all transform hover:scale-105 cursor-pointer flex items-center gap-2"
className="flex items-center gap-2 px-3 py-2 rounded-lg bg-red-600 hover:bg-red-700 text-white transition-all"
title="Kijelentkezés"
>
<FaSignOutAlt className="h-6 w-6" />
<FaSignOutAlt className="h-4 w-4" />
<span>Kijelentkezés</span>
</button>
</div>
)}
</div>
)}
@@ -145,6 +145,8 @@ const Card_display = () => {
"QUESTION": "Kérdés",
"LUCK": "Szerencse",
"JOKER": "Joker",
"joker": "Joker",
"luck": "Szerencse",
// If backend converts to different numbers, map them:
"0": "Igaz/Hamis", // truefalse = 0
"1": "Feleletválasztós", // multiplechoice = 1
@@ -352,7 +354,7 @@ const Card_display = () => {
)}
{paginatedCards.map((card, idx) => {
const cardIndex = startIndex + idx + 1
const questionText = card.question || card.statement || 'Kérdés hiányzik'
const questionText = card.text || card.question || card.statement || 'Kérdés hiányzik'
// Get answers based on card type
let answerOptions = []
@@ -364,13 +366,30 @@ const Card_display = () => {
// Detect card type by fields if subType is missing
let detectedType = subType
if (subType === 'undefined' || subType === 'null') {
// Check by numeric type field first
if (card.type === 3) {
// First check deck type - if deck is JOKER or LUCK type, cards inherit that
if (deck.type === 1) {
// Deck type 1 = Joker deck
detectedType = 'joker'
} else if (deck.type === 0) {
// Deck type 0 = Luck deck
detectedType = 'luck'
} else if (card.type !== undefined) {
// Check by card.type field (string or numeric)
const cardType = typeof card.type === 'string' ? card.type.toLowerCase() : card.type
if (cardType === 'joker' || card.type === 'JOKER') {
// Joker card
detectedType = 'joker'
} else if (cardType === 'luck' || card.type === 'LUCK') {
// Luck card
detectedType = 'luck'
} else if (card.type === 3) {
// type 3 = True/False
detectedType = 'truefalse'
} else if (card.type === 2) {
// type 2 = Text answer
detectedType = 'text'
}
} else if (card.leftItems && card.rightItems && card.correctPairs) {
// Has leftItems, rightItems AND correctPairs = matching
detectedType = 'matching'
@@ -385,6 +404,28 @@ const Card_display = () => {
}
}
// Extract consequence info for JOKER and LUCK cards
let consequenceText = null
if ((detectedType === 'joker' || detectedType === 'luck') && card.consequence) {
const consequenceLabels = {
0: 'Lépj előre',
1: 'Lépj hátra',
2: 'Kör kihagyás',
3: 'Extra kör',
5: 'Vissza a starthoz'
}
const consequenceType = consequenceLabels[card.consequence.type] || 'Ismeretlen hatás'
const consequenceValue = card.consequence.value
if (consequenceValue && [0, 1].includes(card.consequence.type)) {
consequenceText = `${consequenceType} ${consequenceValue} mezőt`
} else if (consequenceValue && [2, 3].includes(card.consequence.type)) {
consequenceText = `${consequenceType} (${consequenceValue} kör)`
} else {
consequenceText = consequenceType
}
}
if (detectedType === 'truefalse' || detectedType === '0') {
// True/False cards
answerOptions = ['Igaz', 'Hamis']
@@ -432,16 +473,92 @@ const Card_display = () => {
return (
<div
key={cardId}
className="relative h-80 cursor-pointer"
className="relative h-80"
style={{ perspective: "1000px" }}
onClick={() => toggleCardFlip(cardId)}
>
{detectedType === 'joker' ? (
// Joker card - no flip, just show the task
<div
className={`relative w-full h-full transition-transform duration-500`}
className="w-full h-full bg-[color:var(--color-card)] rounded-2xl p-6 shadow-lg border-l-4 flex flex-col"
style={{
borderLeftColor: "var(--color-fun)",
}}
>
<div className="flex items-center justify-between mb-3">
<span className="text-[color:var(--color-text-muted)] text-sm font-medium">
Kártya #{cardIndex}
</span>
<span
className="inline-block px-2 py-1 rounded-full text-xs font-bold"
style={{
background: "var(--color-fun)",
color: "var(--color-text-inverse)",
}}
>
🃏 JOKER
</span>
</div>
<div className="flex-1 flex flex-col items-center justify-center">
<div className="text-6xl mb-4">🃏</div>
<div className="text-[color:var(--color-text)] text-center text-lg font-medium bg-[color:var(--color-fun)]/20 rounded-lg px-6 py-4 border-2 border-[color:var(--color-fun)]">
{questionText}
</div>
</div>
<div className="pt-3 border-t border-[color:var(--color-surface-selected)] text-xs text-[color:var(--color-text-muted)] text-center">
<div>Típus: <span className="font-semibold">Joker</span></div>
</div>
</div>
) : detectedType === 'luck' ? (
// Luck card - no flip, show text and consequence
<div
className="w-full h-full bg-[color:var(--color-card)] rounded-2xl p-6 shadow-lg border-l-4 flex flex-col"
style={{
borderLeftColor: "var(--color-luck)",
}}
>
<div className="flex items-center justify-between mb-3">
<span className="text-[color:var(--color-text-muted)] text-sm font-medium">
Kártya #{cardIndex}
</span>
<span
className="inline-block px-2 py-1 rounded-full text-xs font-bold"
style={{
background: "var(--color-luck)",
color: "var(--color-text-inverse)",
}}
>
🎲 SZERENCSE
</span>
</div>
<div className="flex-1 flex flex-col items-center justify-center">
<div className="text-6xl mb-4">🎲</div>
<div className="text-[color:var(--color-text)] text-center text-lg font-medium bg-[color:var(--color-luck)]/20 rounded-lg px-6 py-4 border-2 border-[color:var(--color-luck)] mb-4">
{questionText}
</div>
{consequenceText && (
<div className="text-[color:var(--color-text)] text-center">
<div className="text-xl font-bold bg-[color:var(--color-luck)]/30 rounded-lg px-6 py-3 border-2 border-[color:var(--color-luck)]">
{consequenceText}
</div>
</div>
)}
</div>
<div className="pt-3 border-t border-[color:var(--color-surface-selected)] text-xs text-[color:var(--color-text-muted)] text-center">
<div>Típus: <span className="font-semibold">Szerencse</span></div>
</div>
</div>
) : (
<div
className={`relative w-full h-full transition-transform duration-500 ${detectedType !== 'joker' && detectedType !== 'luck' ? 'cursor-pointer' : ''}`}
style={{
transformStyle: "preserve-3d",
transform: isFlipped ? "rotateY(180deg)" : "rotateY(0deg)"
}}
onClick={detectedType !== 'joker' && detectedType !== 'luck' ? () => toggleCardFlip(cardId) : undefined}
>
{/* Front side - Question */}
<div
@@ -455,6 +572,7 @@ const Card_display = () => {
<span className="text-[color:var(--color-text-muted)] text-sm font-medium">
Kártya #{cardIndex}
</span>
{detectedType !== 'joker' && detectedType !== 'luck' && (
<span
className="inline-block px-2 py-1 rounded-full text-xs font-bold"
style={{
@@ -464,6 +582,29 @@ const Card_display = () => {
>
{answerCount} válasz
</span>
)}
{detectedType === 'joker' && (
<span
className="inline-block px-2 py-1 rounded-full text-xs font-bold"
style={{
background: "var(--color-fun)",
color: "var(--color-text-inverse)",
}}
>
🃏 JOKER
</span>
)}
{detectedType === 'luck' && (
<span
className="inline-block px-2 py-1 rounded-full text-xs font-bold"
style={{
background: "var(--color-luck)",
color: "var(--color-text-inverse)",
}}
>
🎲 SZERENCSE
</span>
)}
</div>
<h3 className="text-lg font-bold text-[color:var(--color-text)] mb-3">
@@ -492,7 +633,7 @@ const Card_display = () => {
>
<div className="flex items-center justify-between mb-3">
<span className="text-[color:var(--color-text-muted)] text-sm font-medium">
Megoldás
{detectedType === 'joker' || detectedType === 'luck' ? 'Kártya hatás' : 'Megoldás'}
</span>
<span
className="inline-block px-2 py-1 rounded-full text-xs font-bold"
@@ -501,11 +642,37 @@ const Card_display = () => {
color: "var(--color-text-inverse)",
}}
>
{answerCount} válasz
{detectedType === 'joker' || detectedType === 'luck' ? (detectedType === 'joker' ? '🃏 JOKER' : '🎲 SZERENCSE') : `${answerCount} válasz`}
</span>
</div>
{answerCount > 0 ? (
{detectedType === 'joker' ? (
// Joker card - just show the task/challenge
<div className="flex flex-col items-center justify-center h-full py-8">
<div className="text-6xl mb-4">🃏</div>
<div className="text-[color:var(--color-text)] text-center text-lg font-medium bg-[color:var(--color-fun)]/20 rounded-lg px-6 py-4 border-2 border-[color:var(--color-fun)]">
{questionText}
</div>
<div className="text-[color:var(--color-text-muted)] text-sm mt-4 text-center italic">
A játékmester dönti el a teljesítést
</div>
</div>
) : detectedType === 'luck' ? (
// Luck card - show consequence
<div className="flex flex-col items-center justify-center h-full py-8">
<div className="text-6xl mb-4">🎲</div>
{consequenceText && (
<div className="text-[color:var(--color-text)] text-center">
<div className="text-2xl font-bold mb-4 bg-[color:var(--color-luck)]/20 rounded-lg px-6 py-3 border-2 border-[color:var(--color-luck)]">
{consequenceText}
</div>
</div>
)}
<div className="text-[color:var(--color-text-muted)] text-sm mt-2 text-center italic">
Azonnal végrehajt
</div>
</div>
) : answerCount > 0 ? (
<div className="space-y-2">
<div className="text-[color:var(--color-text-muted)] text-sm font-medium mb-2">
Helyes válasz:
@@ -563,6 +730,7 @@ const Card_display = () => {
</div>
</div>
</div>
)}
</div>
)
})}
@@ -31,7 +31,7 @@ export default function Home() {
<div className="fixed top-0 left-0 right-0 z-30">
<Navbar />
</div>
<main className="flex-1 min-h-[calc(100vh-64px)] flex mt-[64px] flex-col items-center justify-center">
<main className="flex-1 min-h-[calc(100vh-64px)] flex mt-[64px] flex-col items-center justify-center px-2 sm:px-4">
<PlayMenu
onJoinGame={handleJoinGame}
onCreateGame={handleCreateGame}