wip: started to add translations
All checks were successful
Build / Explore-Gitea-Actions (push) Successful in 35s
All checks were successful
Build / Explore-Gitea-Actions (push) Successful in 35s
This commit is contained in:
parent
34531fd2cf
commit
81dad2b6ba
@ -2,13 +2,15 @@ import React, { useEffect } from 'react';
|
||||
import banquiseServer from '../../assets/banquise_server.svg'
|
||||
import { URLS, SITE_CONFIG } from '../../config/constants';
|
||||
import { commonStyles } from '../../styles/components';
|
||||
import type { Translation } from '../../types/i18n';
|
||||
|
||||
interface MobileMenuProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
translations: Translation['navigation'];
|
||||
}
|
||||
|
||||
export const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose }) => {
|
||||
export const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose, translations }) => {
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
document.body.style.overflow = 'hidden';
|
||||
@ -76,7 +78,7 @@ export const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose }) => {
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<span className="font-semibold text-lg">Nos Services</span>
|
||||
<span className="font-semibold text-lg">{translations.services}</span>
|
||||
<p className="text-white/60 text-sm">Découvrir notre offre</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -93,7 +95,7 @@ export const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose }) => {
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<span className="font-semibold text-lg">À propos</span>
|
||||
<span className="font-semibold text-lg">{translations.about}</span>
|
||||
<p className="text-white/60 text-sm">En savoir plus sur nous</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -106,7 +108,7 @@ export const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose }) => {
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className={`${commonStyles.icons.small} ${commonStyles.gradients.discord} group-hover:scale-110 transition-transform duration-200`}>
|
||||
<svg className="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.211.375-.445.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z"/>
|
||||
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.211.375-.445.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.30z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -3,8 +3,14 @@ import { MobileMenu } from './MobileMenu';
|
||||
import banquiseServer from '/src/assets/banquise_server.svg'
|
||||
import { URLS, SITE_CONFIG } from '../../config/constants';
|
||||
import { commonStyles } from '../../styles/components';
|
||||
import type { Translation } from '../../types/i18n';
|
||||
|
||||
export const Navigation: React.FC = () => {
|
||||
interface NavigationProps {
|
||||
translations: Translation['navigation'];
|
||||
languageSwitcher: React.ReactElement;
|
||||
}
|
||||
|
||||
export const Navigation: React.FC<NavigationProps> = ({ translations, languageSwitcher }) => {
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
|
||||
@ -13,7 +19,6 @@ export const Navigation: React.FC = () => {
|
||||
const isScrolled = window.scrollY > 20;
|
||||
setScrolled(isScrolled);
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
@ -24,7 +29,6 @@ export const Navigation: React.FC = () => {
|
||||
setMobileMenuOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
@ -32,22 +36,21 @@ export const Navigation: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<nav className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
||||
scrolled
|
||||
? 'bg-banquise-blue-dark/98 backdrop-blur-xl shadow-2xl border-b border-banquise-blue-lightest/30'
|
||||
scrolled
|
||||
? 'bg-banquise-blue-dark/98 backdrop-blur-xl shadow-2xl border-b border-banquise-blue-lightest/30'
|
||||
: 'bg-banquise-blue-dark/95 backdrop-blur-lg shadow-xl border-b border-banquise-blue-lightest/20'
|
||||
}`}>
|
||||
<div className={commonStyles.layout.container}>
|
||||
<div className="flex justify-between items-center h-16 sm:h-18 lg:h-20 px-4 sm:px-6 lg:px-8">
|
||||
|
||||
{/* Logo section */}
|
||||
<div className="flex items-center space-x-3 sm:space-x-4 group">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-banquise-blue-light/20 to-banquise-blue/20 rounded-full blur-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
||||
<img
|
||||
<img
|
||||
src={banquiseServer}
|
||||
alt="Logo La Banquise"
|
||||
className="h-10 sm:h-12 lg:h-14 w-auto relative z-10 transition-transform duration-300 group-hover:scale-110"
|
||||
style={{ filter: 'drop-shadow(0 0 12px rgba(168, 218, 255, 0.4))' }}
|
||||
alt="Logo La Banquise"
|
||||
className="h-10 sm:h-12 lg:h-14 w-auto relative z-10 transition-transform duration-300 group-hover:scale-110"
|
||||
style={{ filter: 'drop-shadow(0 0 12px rgba(168, 218, 255, 0.4))' }}
|
||||
/>
|
||||
</div>
|
||||
<div className="hidden sm:block">
|
||||
@ -62,20 +65,30 @@ export const Navigation: React.FC = () => {
|
||||
|
||||
{/* Navigation links desktop */}
|
||||
<div className="hidden md:flex items-center space-x-1 lg:space-x-2">
|
||||
<a href="#services" className={commonStyles.nav.link}>
|
||||
<span className="relative z-10">Services</span>
|
||||
<a href="#home" className={commonStyles.nav.link}>
|
||||
<span className="relative z-10">{translations.home}</span>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-banquise-blue-light/20 to-banquise-blue/20 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
||||
</a>
|
||||
<a href="#services" className={commonStyles.nav.link}>
|
||||
<span className="relative z-10">{translations.services}</span>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-banquise-blue-light/20 to-banquise-blue/20 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
||||
</a>
|
||||
|
||||
<a href="#about" className={commonStyles.nav.link}>
|
||||
<span className="relative z-10">À propos</span>
|
||||
<span className="relative z-10">{translations.about}</span>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-banquise-blue-light/20 to-banquise-blue/20 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
||||
</a>
|
||||
<a href="#contact" className={commonStyles.nav.link}>
|
||||
<span className="relative z-10">{translations.contact}</span>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-banquise-blue-light/20 to-banquise-blue/20 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Action buttons desktop */}
|
||||
<div className="hidden md:flex items-center space-x-3 lg:space-x-4">
|
||||
<a
|
||||
{/* Language switcher */}
|
||||
{languageSwitcher}
|
||||
|
||||
<a
|
||||
href={URLS.social.discord}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@ -89,20 +102,19 @@ export const Navigation: React.FC = () => {
|
||||
<span>Discord</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a
|
||||
<a
|
||||
href={URLS.services.auth}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={`${commonStyles.buttons.auth} ${
|
||||
scrolled
|
||||
? `${commonStyles.gradients.primary} border border-banquise-blue-lightest/30 hover:shadow-banquise-blue/25`
|
||||
scrolled
|
||||
? `${commonStyles.gradients.primary} border border-banquise-blue-lightest/30 hover:shadow-banquise-blue/25`
|
||||
: 'bg-gradient-to-r from-banquise-blue-light to-banquise-blue border-2 border-white/20 hover:shadow-banquise-blue-light/25'
|
||||
}`}
|
||||
>
|
||||
<div className={`absolute inset-0 transition-opacity duration-300 opacity-0 group-hover:opacity-100 ${
|
||||
scrolled
|
||||
? 'bg-gradient-to-r from-banquise-blue-light to-banquise-blue'
|
||||
scrolled
|
||||
? 'bg-gradient-to-r from-banquise-blue-light to-banquise-blue'
|
||||
: 'bg-gradient-to-r from-white/10 to-banquise-blue-lightest/20'
|
||||
}`}></div>
|
||||
<div className="relative z-10 flex items-center space-x-2">
|
||||
@ -115,32 +127,32 @@ export const Navigation: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* Mobile menu button */}
|
||||
<button
|
||||
<button
|
||||
className="md:hidden relative p-3 rounded-xl bg-white/10 hover:bg-white/20 transition-all duration-300 hover:scale-105 active:scale-95 group"
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
aria-label={mobileMenuOpen ? "Fermer le menu" : "Ouvrir le menu"}
|
||||
aria-expanded={mobileMenuOpen}
|
||||
>
|
||||
<div className="w-6 h-6 relative">
|
||||
<span className={`absolute block w-6 h-0.5 bg-white transition-all duration-300 ${mobileMenuOpen ? 'rotate-45 top-3' : 'top-1'}`}></span>
|
||||
<span className={`absolute block w-6 h-6 bg-white transition-all duration-300 ${mobileMenuOpen ? 'rotate-45 top-3' : 'top-1'}`}></span>
|
||||
<span className={`absolute block w-6 h-0.5 bg-white transition-all duration-300 top-3 ${mobileMenuOpen ? 'opacity-0 scale-0' : 'opacity-100'}`}></span>
|
||||
<span className={`absolute block w-6 h-0.5 bg-white transition-all duration-300 ${mobileMenuOpen ? '-rotate-45 top-3' : 'top-5'}`}></span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Glassmorphism effect bar */}
|
||||
<div className="absolute bottom-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-banquise-blue-lightest/30 to-transparent"></div>
|
||||
</nav>
|
||||
|
||||
|
||||
{/* Spacer pour compenser la navbar fixed */}
|
||||
<div className="h-16 sm:h-18 lg:h-20"></div>
|
||||
|
||||
|
||||
{/* Menu mobile */}
|
||||
<MobileMenu
|
||||
isOpen={mobileMenuOpen}
|
||||
onClose={() => setMobileMenuOpen(false)}
|
||||
<MobileMenu
|
||||
isOpen={mobileMenuOpen}
|
||||
onClose={() => setMobileMenuOpen(false)}
|
||||
translations={translations}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
@ -1,7 +1,12 @@
|
||||
import React from 'react';
|
||||
import banquiseServer from '/src/assets/banquise_server.svg'
|
||||
import type { Translation } from '../../types/i18n';
|
||||
|
||||
export const HeroSection: React.FC = () => (
|
||||
interface HeroSectionProps {
|
||||
translations: Translation['hero'];
|
||||
}
|
||||
|
||||
export const HeroSection: React.FC<HeroSectionProps> = ({ translations }) => (
|
||||
<section className="min-h-[calc(80vh-72px)] flex flex-col justify-center items-center text-center py-12 sm:py-16 md:py-20 w-full max-w-6xl mx-auto px-4 sm:px-6 md:px-8 relative z-3">
|
||||
<div className="mb-8 sm:mb-10 md:mb-12 w-32 h-32 sm:w-40 sm:h-40 md:w-48 md:h-48 rounded-full bg-gradient-to-br from-banquise-blue-dark/20 to-banquise-blue/10 p-4 sm:p-5 md:p-6 shadow-2xl backdrop-blur-sm border border-banquise-blue-lightest/30 relative group">
|
||||
<img
|
||||
@ -15,15 +20,15 @@ export const HeroSection: React.FC = () => (
|
||||
</div>
|
||||
|
||||
<h1 className="text-banquise-gray text-3xl sm:text-4xl md:text-5xl lg:text-6xl mb-6 sm:mb-7 md:mb-8 font-extrabold leading-tight max-w-4xl font-heading px-2 relative z-10" style={{ textShadow: '0 2px 10px rgba(0, 0, 0, 0.3)' }}>
|
||||
Bienvenue sur La Banquise
|
||||
{translations.title}
|
||||
</h1>
|
||||
|
||||
<p className="text-banquise-gray text-lg sm:text-xl md:text-2xl mb-8 sm:mb-10 md:mb-12 max-w-3xl font-normal opacity-90 leading-relaxed px-2 relative z-10" style={{ textShadow: '0 1px 4px rgba(0, 0, 0, 0.2)' }}>
|
||||
Association d'hébergement et lab réseau pour tous les étudiants et associations de l'EPITA !
|
||||
{translations.subtitle}
|
||||
</p>
|
||||
|
||||
<a href="#services" className="inline-flex items-center justify-center bg-gradient-to-r from-banquise-gray to-white text-banquise-blue-dark border-0 py-4 sm:py-5 px-8 sm:px-10 md:px-12 rounded-2xl text-base sm:text-lg font-bold no-underline shadow-xl transition-all duration-300 min-w-48 sm:min-w-56 md:min-w-64 hover:-translate-y-2 hover:shadow-2xl hover:scale-105 backdrop-blur-sm border border-banquise-blue-lightest/20 mx-4 group relative z-10">
|
||||
<span className="text-center text-banquise-blue-dark">Découvrir nos services</span>
|
||||
<span className="text-center text-banquise-blue-dark">{translations.cta}</span>
|
||||
<span className="ml-2 sm:ml-3 text-lg sm:text-xl transition-transform duration-300 group-hover:translate-x-1 text-banquise-blue-dark">→</span>
|
||||
</a>
|
||||
</section>
|
||||
|
@ -1,25 +1,19 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { URLS } from '../../config/constants';
|
||||
|
||||
interface Service {
|
||||
name: string;
|
||||
url: string;
|
||||
image: string;
|
||||
icon: string;
|
||||
description: string;
|
||||
features: string[];
|
||||
}
|
||||
import type { Service } from '../../types/service';
|
||||
import type { Translation } from '../../types/i18n';
|
||||
|
||||
interface PopupProps {
|
||||
service: Service;
|
||||
onClose: () => void;
|
||||
translations: Translation['common'];
|
||||
}
|
||||
|
||||
export const Popup: React.FC<PopupProps> = ({ service, onClose }) => {
|
||||
export const Popup: React.FC<PopupProps> = ({ service, onClose, translations }) => {
|
||||
// Empêcher le scroll du body quand la popup est ouverte
|
||||
useEffect(() => {
|
||||
document.body.style.overflow = 'hidden';
|
||||
|
||||
|
||||
return () => {
|
||||
document.body.style.overflow = 'unset';
|
||||
};
|
||||
@ -28,18 +22,18 @@ export const Popup: React.FC<PopupProps> = ({ service, onClose }) => {
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/60 flex justify-center items-center z-50 p-4 backdrop-blur-md animate-fadeIn">
|
||||
<div className="bg-white text-banquise-blue-dark rounded-3xl max-w-4xl w-full max-h-[90vh] shadow-2xl relative animate-slideUp border border-banquise-blue-lightest/20 overflow-hidden">
|
||||
|
||||
|
||||
{/* Bouton de fermeture fixe au-dessus du contenu */}
|
||||
<div className="absolute top-4 right-4 z-50">
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="bg-white/90 hover:bg-white border border-banquise-blue/20 text-xl cursor-pointer text-banquise-blue-dark flex items-center justify-center w-10 h-10 sm:w-12 sm:h-12 rounded-full transition-all duration-200 hover:scale-110 active:scale-95 shadow-lg backdrop-blur-sm"
|
||||
aria-label="Fermer la popup"
|
||||
aria-label={translations.close}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Contenu avec scroll vertical uniquement */}
|
||||
<div className="overflow-y-auto overflow-x-hidden max-h-[90vh] popup-content">
|
||||
{/* Header */}
|
||||
@ -100,7 +94,7 @@ export const Popup: React.FC<PopupProps> = ({ service, onClose }) => {
|
||||
{/* Fonctionnalités */}
|
||||
<h3 className="text-xl sm:text-2xl lg:text-3xl mb-4 lg:mb-6 text-banquise-blue-dark font-heading font-bold flex items-center">
|
||||
<span className="text-xl sm:text-2xl lg:text-3xl mr-3">⚡</span>
|
||||
Fonctionnalités principales
|
||||
{translations.discoverFeatures}
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-8">
|
||||
{service.features.map((feature, index) => (
|
||||
@ -124,7 +118,7 @@ export const Popup: React.FC<PopupProps> = ({ service, onClose }) => {
|
||||
<span className="mr-3 text-xl lg:text-2xl">🚀</span>
|
||||
<span>Accéder à {service.name}</span>
|
||||
</a>
|
||||
|
||||
|
||||
<p className="text-center text-sm text-banquise-blue-dark/60 mt-4">
|
||||
Besoin d'aide ? Rejoignez notre <a href={URLS.social.discord} className="text-banquise-blue hover:text-banquise-blue-dark transition-colors duration-200 font-medium">Discord</a> pour obtenir du support
|
||||
</p>
|
||||
|
Loading…
x
Reference in New Issue
Block a user