Translate event details and UI text to French, including event names, descriptions, and status labels. Update navigation styles for consistency.

This commit is contained in:
Julien Froidefond
2025-12-08 17:22:14 +01:00
parent 4e6ce54e0f
commit c5bd94ec69
5 changed files with 196 additions and 48 deletions

View File

@@ -12,55 +12,55 @@ interface Event {
const events: Event[] = [
{
id: 1,
date: "NOVEMBER 18th, 2023",
name: "Tech Innovation Summit",
date: "18 NOVEMBRE 2023",
name: "Sommet de l'Innovation Tech",
description:
"Join industry leaders and innovators for a day of cutting-edge technology discussions, AI breakthroughs, and networking opportunities.",
"Rejoignez les leaders de l'industrie et les innovateurs pour une journée de discussions sur les technologies de pointe, les percées de l'IA et des opportunités de networking.",
type: "summit",
status: "past",
},
{
id: 2,
date: "DECEMBER 3rd, 2023",
name: "AI Revolution Launch",
date: "3 DÉCEMBRE 2023",
name: "Lancement de la Révolution IA",
description:
"Witness the launch of revolutionary AI systems that will reshape the gaming landscape. Exclusive previews and early access opportunities.",
"Assistez au lancement de systèmes d'IA révolutionnaires qui vont remodeler le paysage du gaming. Aperçus exclusifs et opportunités d'accès anticipé.",
type: "launch",
status: "past",
},
{
id: 3,
date: "DECEMBER 22nd, 2023",
name: "Winter Code Festival",
date: "22 DÉCEMBRE 2023",
name: "Festival du Code d'Hiver",
description:
"A celebration of coding excellence with hackathons, coding challenges, and prizes. Showcase your skills and compete with the best developers.",
"Une célébration de l'excellence en programmation avec des hackathons, des défis de codage et des prix. Montrez vos compétences et rivalisez avec les meilleurs développeurs.",
type: "festival",
status: "past",
},
{
id: 4,
date: "JANUARY 15th, 2024",
name: "Quantum Computing Expo",
date: "15 JANVIER 2024",
name: "Expo Informatique Quantique",
description:
"Explore the future of quantum computing in gaming. Interactive demos, expert talks, and hands-on workshops for all skill levels.",
"Explorez l'avenir de l'informatique quantique dans le gaming. Démonstrations interactives, conférences d'experts et ateliers pratiques pour tous les niveaux.",
type: "summit",
status: "upcoming",
},
{
id: 5,
date: "FEBRUARY 8th, 2024",
name: "Cyber Arena Championship",
date: "8 FÉVRIER 2024",
name: "Championnat Cyber Arena",
description:
"The ultimate competitive gaming event. Compete for glory, exclusive rewards, and the title of Cyber Arena Champion. Registration now open.",
"L'événement de gaming compétitif ultime. Compétissez pour la gloire, des récompenses exclusives et le titre de Champion Cyber Arena. Inscriptions ouvertes.",
type: "competition",
status: "upcoming",
},
{
id: 6,
date: "MARCH 12th, 2024",
name: "Spring Tech Gala",
date: "12 MARS 2024",
name: "Gala Tech du Printemps",
description:
"An elegant evening celebrating technological achievements. Awards ceremony, networking, and exclusive announcements from top tech companies.",
"Une soirée élégante célébrant les réalisations technologiques. Cérémonie de remise de prix, networking et annonces exclusives des plus grandes entreprises tech.",
type: "festival",
status: "upcoming",
},
@@ -81,24 +81,39 @@ const getEventTypeColor = (type: Event["type"]) => {
}
};
const getEventTypeLabel = (type: Event["type"]) => {
switch (type) {
case "summit":
return "Sommet";
case "launch":
return "Lancement";
case "festival":
return "Festival";
case "competition":
return "Compétition";
default:
return type;
}
};
const getStatusBadge = (status: Event["status"]) => {
switch (status) {
case "upcoming":
return (
<span className="px-3 py-1 bg-green-900/50 border border-green-500/50 text-green-400 text-xs uppercase tracking-widest rounded">
Upcoming
À venir
</span>
);
case "live":
return (
<span className="px-3 py-1 bg-red-900/50 border border-red-500/50 text-red-400 text-xs uppercase tracking-widest rounded animate-pulse">
Live Now
En direct
</span>
);
case "past":
return (
<span className="px-3 py-1 bg-gray-800/50 border border-gray-600/50 text-gray-400 text-xs uppercase tracking-widest rounded">
Past
Pas
</span>
);
}
@@ -134,12 +149,12 @@ export default function EventsPageSection() {
</h1>
<div className="text-pixel-gold text-lg md:text-xl font-gaming-subtitle font-semibold flex items-center justify-center gap-2 mb-6 tracking-wide">
<span></span>
<span>Upcoming & Past Events</span>
<span>Événements à venir et passés</span>
<span></span>
</div>
<p className="text-gray-400 text-sm max-w-2xl mx-auto">
Join us for exciting tech events, competitions, and celebrations
throughout the year
Rejoignez-nous pour des événements tech passionnants, des
compétitions et des célébrations tout au long de l'année
</p>
</div>
@@ -163,7 +178,7 @@ export default function EventsPageSection() {
<div className="flex justify-between items-start mb-4">
{getStatusBadge(event.status)}
<span className="text-pixel-gold text-xs uppercase tracking-widest">
{event.type}
{getEventTypeLabel(event.type)}
</span>
</div>
@@ -185,17 +200,17 @@ export default function EventsPageSection() {
{/* Action Button */}
{event.status === "upcoming" && (
<button className="w-full px-4 py-2 border border-pixel-gold/50 bg-black/40 text-white uppercase text-xs tracking-widest rounded hover:bg-pixel-gold/10 hover:border-pixel-gold transition">
Register Now
S'inscrire maintenant
</button>
)}
{event.status === "live" && (
<button className="w-full px-4 py-2 border border-red-500/50 bg-red-900/20 text-red-400 uppercase text-xs tracking-widest rounded hover:bg-red-900/30 transition animate-pulse">
Join Live
Rejoindre en direct
</button>
)}
{event.status === "past" && (
<button className="w-full px-4 py-2 border border-gray-600/50 bg-gray-900/20 text-gray-500 uppercase text-xs tracking-widest rounded cursor-not-allowed">
Event Ended
Événement terminé
</button>
)}
</div>
@@ -206,7 +221,7 @@ export default function EventsPageSection() {
{/* Footer Info */}
<div className="mt-12 text-center">
<p className="text-gray-500 text-sm">
Stay updated with our latest events and announcements
Restez informé de nos derniers événements et annonces
</p>
</div>
</div>

View File

@@ -7,16 +7,16 @@ interface Event {
const events: Event[] = [
{
date: "NOVEMBER 18th, 2023",
name: "Tech Innovation Summit",
date: "18 NOVEMBRE 2023",
name: "Sommet de l'Innovation Tech",
},
{
date: "DECEMBER 3rd, 2023",
name: "AI Revolution Launch",
date: "3 DÉCEMBRE 2023",
name: "Lancement de la Révolution IA",
},
{
date: "DECEMBER 22nd, 2023",
name: "Winter Code Festival",
date: "22 DÉCEMBRE 2023",
name: "Festival du Code d'Hiver",
},
];
@@ -29,7 +29,7 @@ export default function EventsSection() {
<div key={index} className="flex flex-col items-center">
<div className="flex flex-col items-center mb-4">
<span className="text-pixel-gold text-xs uppercase tracking-widest mb-2">
Event
Événement
</span>
<div className="w-16 h-px bg-pixel-gold"></div>
</div>
@@ -46,4 +46,3 @@ export default function EventsSection() {
</section>
);
}

View File

@@ -37,10 +37,11 @@ export default function HeroSection() {
{/* Description */}
<p className="text-white text-base md:text-lg max-w-3xl mx-auto mb-12 leading-relaxed px-4">
In a digital world of cutting-edge technology, where AI systems are
evolving and ancient code awaits discovery. Go on an epic journey to
forge alliances, conquer challenges and tell your story of innovation
as part of a flourishing tech gaming community.
Dans un monde numérique de technologie de pointe, les systèmes d'IA
évoluent et où d'anciens codes attendent d'être découverts. Partez
pour un voyage épique pour forger des alliances, conquérir des défis
et raconter votre histoire d'innovation au sein d'une communauté de
gaming tech florissante.
</p>
{/* Call-to-Action Buttons */}

View File

@@ -1,15 +1,17 @@
"use client";
import PlayerStats from "./PlayerStats";
export default function Navigation() {
return (
<nav className="w-full fixed top-0 left-0 z-50 px-8 py-6 bg-black/80 backdrop-blur-sm border-b border-gray-800/30">
<nav className="w-full fixed top-0 left-0 z-50 px-8 py-3 bg-black/80 backdrop-blur-sm border-b border-gray-800/30">
<div className="max-w-7xl mx-auto flex items-center justify-between">
{/* Logo - Left */}
<div className="flex flex-col">
<div className="text-white text-2xl font-gaming font-bold tracking-tight">
<div className="text-white text-xl font-gaming font-bold tracking-tight">
GAME.OF.TECH
</div>
<div className="text-pixel-gold text-sm font-gaming-subtitle font-semibold flex items-center gap-1 tracking-wide">
<div className="text-pixel-gold text-xs font-gaming-subtitle font-semibold flex items-center gap-1 tracking-wide">
<span></span>
<span>Game of Tech</span>
<span></span>
@@ -38,11 +40,9 @@ export default function Navigation() {
</a>
</div>
{/* Play Now Button - Right */}
{/* Player Stats - Right */}
<div>
<button className="px-6 py-2 border border-pixel-gold/50 bg-black/40 text-white uppercase text-xs tracking-widest rounded hover:bg-pixel-gold/10 hover:border-pixel-gold transition">
PLAY NOW
</button>
<PlayerStats />
</div>
</div>
</nav>

133
components/PlayerStats.tsx Normal file
View File

@@ -0,0 +1,133 @@
"use client";
import { useEffect, useState } from "react";
interface PlayerStatsProps {
username?: string;
avatar?: string;
hp?: number;
maxHp?: number;
xp?: number;
maxXp?: number;
level?: number;
}
// Format number with consistent locale to avoid hydration mismatch
const formatNumber = (num: number): string => {
return num.toLocaleString("en-US");
};
export default function PlayerStats({
username = "DragonSlayer99",
avatar = "/got-2.jpg",
hp = 750,
maxHp = 1000,
xp = 3250,
maxXp = 5000,
level = 42,
}: PlayerStatsProps) {
const [hpPercentage, setHpPercentage] = useState(0);
const [xpPercentage, setXpPercentage] = useState(0);
useEffect(() => {
// Animate HP bar
const hpTimer = setTimeout(() => {
setHpPercentage((hp / maxHp) * 100);
}, 100);
// Animate XP bar
const xpTimer = setTimeout(() => {
setXpPercentage((xp / maxXp) * 100);
}, 200);
return () => {
clearTimeout(hpTimer);
clearTimeout(xpTimer);
};
}, [hp, maxHp, xp, maxXp]);
const hpColor =
hpPercentage > 60
? "from-green-600 to-green-700"
: hpPercentage > 30
? "from-yellow-600 to-orange-700"
: "from-red-700 to-red-900";
return (
<div className="flex items-center gap-3">
{/* Avatar */}
<div className="w-10 h-10 rounded-full border border-pixel-gold/20 overflow-hidden bg-gray-900">
<img
src={avatar}
alt={username}
className="w-full h-full object-cover"
/>
</div>
{/* Stats */}
<div className="flex flex-col gap-1.5 min-w-[200px]">
{/* Username & Level */}
<div className="flex items-center gap-2">
<div className="text-pixel-gold font-gaming font-bold text-sm tracking-wider">
{username}
</div>
<div className="text-gray-400 font-pixel text-xs uppercase border border-pixel-gold/30 px-1.5 py-0.5 bg-black/40">
Lv.{level}
</div>
</div>
{/* Bars side by side */}
<div className="flex flex-col gap-1">
<div className="flex items-center gap-2">
{/* HP Bar */}
<div className="relative h-2 flex-1 bg-gray-900 border border-gray-700 rounded overflow-hidden">
<div
className={`absolute inset-0 bg-gradient-to-r ${hpColor} transition-all duration-1000 ease-out`}
style={{ width: `${hpPercentage}%` }}
>
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/10 to-transparent animate-shimmer"></div>
</div>
{hpPercentage < 30 && (
<div className="absolute inset-0 border border-red-500 rounded animate-pulse"></div>
)}
</div>
{/* XP Bar */}
<div className="relative h-2 flex-1 bg-gray-900 border border-pixel-gold/30 rounded overflow-hidden">
<div
className="absolute inset-0 bg-gradient-to-r from-pixel-gold/80 via-pixel-gold/70 to-pixel-gold/80 transition-all duration-1000 ease-out"
style={{ width: `${xpPercentage}%` }}
>
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/10 to-transparent animate-shimmer"></div>
</div>
</div>
</div>
{/* Labels */}
<div className="flex items-center gap-2 text-[8px] font-pixel text-gray-400">
<div className="flex-1 text-left">
HP {hp} / {maxHp}
</div>
<div className="flex-1 text-right">
XP {formatNumber(xp)} / {formatNumber(maxXp)}
</div>
</div>
</div>
</div>
<style jsx>{`
@keyframes shimmer {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
.animate-shimmer {
animation: shimmer 2s infinite;
}
`}</style>
</div>
);
}