Merge pull request 'initial for website-v2' (#7) from website-v2 into dev
Reviewed-on: #7 Reviewed-by: arthur.wambst
This commit is contained in:
		
						commit
						261ff3a8ae
					
				
							
								
								
									
										68
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								README.md
									
									
									
									
									
								
							| @ -1,2 +1,66 @@ | ||||
| # website-front | ||||
| test | ||||
| # Website Front pour Banquise | ||||
| 
 | ||||
| Ce projet est une application web React développée avec Vite, TypeScript et TailwindCSS. | ||||
| 
 | ||||
| ## Architecture du Projet | ||||
| 
 | ||||
| ``` | ||||
| website-front/ | ||||
| ├── banquise-website/       # Application React principale | ||||
| │   ├── public/             # Fichiers statiques | ||||
| │   ├── src/                # Code source | ||||
| │   │   ├── assets/         # Images et ressources | ||||
| │   │   ├── App.tsx         # Composant principal | ||||
| │   │   └── main.tsx        # Point d'entrée de l'application | ||||
| │   ├── index.html          # Template HTML principal | ||||
| │   ├── package.json        # Configuration des dépendances | ||||
| │   ├── tsconfig.json       # Configuration TypeScript | ||||
| │   ├── vite.config.ts      # Configuration Vite | ||||
| │   └── tailwind.config.js  # Configuration TailwindCSS | ||||
| └── shell.nix              # Configuration pour environnement Nix | ||||
| ``` | ||||
| 
 | ||||
| ## Technologies Utilisées | ||||
| 
 | ||||
| - **React 18** - Bibliothèque d'interface utilisateur | ||||
| - **TypeScript** - Langage de programmation typé | ||||
| - **Vite** - Outil de build et serveur de développement | ||||
| - **TailwindCSS** - Framework CSS utilitaire | ||||
| - **React Router** - Navigation entre les pages | ||||
| - **Zustand** - Gestion d'état | ||||
| - **React Query** - Gestion des requêtes API | ||||
| - **Framer Motion** - Animations | ||||
| 
 | ||||
| ## Pré-requis | ||||
| 
 | ||||
| - Node.js (v16.0.0 ou supérieur) | ||||
| - npm ou yarn | ||||
| 
 | ||||
| ## Installation | ||||
| 
 | ||||
| ```bash | ||||
| # Se déplacer dans le dossier du projet | ||||
| cd banquise-website | ||||
| 
 | ||||
| # Installer les dépendances | ||||
| npm install | ||||
| # ou avec yarn | ||||
| yarn | ||||
| ``` | ||||
| 
 | ||||
| ## Scripts Disponibles | ||||
| 
 | ||||
| - `npm run dev` - Lance le serveur de développement | ||||
| - `npm run build` - Compile le projet pour la production | ||||
| - `npm run preview` - Prévisualise la version de production localement | ||||
| - `npm run lint` - Vérifie la qualité du code avec ESLint | ||||
| 
 | ||||
| ## Déploiement | ||||
| 
 | ||||
| ### Compilation pour la Production | ||||
| 
 | ||||
| ```bash | ||||
| npm run build | ||||
| ``` | ||||
| 
 | ||||
| Cette commande générera un dossier `dist` dans le répertoire `banquise-website/` contenant tous les fichiers optimisés pour la production. | ||||
							
								
								
									
										24
									
								
								banquise-website/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								banquise-website/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| # Logs | ||||
| logs | ||||
| *.log | ||||
| npm-debug.log* | ||||
| yarn-debug.log* | ||||
| yarn-error.log* | ||||
| pnpm-debug.log* | ||||
| lerna-debug.log* | ||||
| 
 | ||||
| node_modules | ||||
| dist | ||||
| dist-ssr | ||||
| *.local | ||||
| 
 | ||||
| # Editor directories and files | ||||
| .vscode/* | ||||
| !.vscode/extensions.json | ||||
| .idea | ||||
| .DS_Store | ||||
| *.suo | ||||
| *.ntvs* | ||||
| *.njsproj | ||||
| *.sln | ||||
| *.sw? | ||||
							
								
								
									
										54
									
								
								banquise-website/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								banquise-website/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| # React + TypeScript + Vite | ||||
| 
 | ||||
| This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. | ||||
| 
 | ||||
| Currently, two official plugins are available: | ||||
| 
 | ||||
| - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh | ||||
| - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh | ||||
| 
 | ||||
| ## Expanding the ESLint configuration | ||||
| 
 | ||||
| If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: | ||||
| 
 | ||||
| ```js | ||||
| export default tseslint.config({ | ||||
|   extends: [ | ||||
|     // Remove ...tseslint.configs.recommended and replace with this | ||||
|     ...tseslint.configs.recommendedTypeChecked, | ||||
|     // Alternatively, use this for stricter rules | ||||
|     ...tseslint.configs.strictTypeChecked, | ||||
|     // Optionally, add this for stylistic rules | ||||
|     ...tseslint.configs.stylisticTypeChecked, | ||||
|   ], | ||||
|   languageOptions: { | ||||
|     // other options... | ||||
|     parserOptions: { | ||||
|       project: ['./tsconfig.node.json', './tsconfig.app.json'], | ||||
|       tsconfigRootDir: import.meta.dirname, | ||||
|     }, | ||||
|   }, | ||||
| }) | ||||
| ``` | ||||
| 
 | ||||
| You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: | ||||
| 
 | ||||
| ```js | ||||
| // eslint.config.js | ||||
| import reactX from 'eslint-plugin-react-x' | ||||
| import reactDom from 'eslint-plugin-react-dom' | ||||
| 
 | ||||
| export default tseslint.config({ | ||||
|   plugins: { | ||||
|     // Add the react-x and react-dom plugins | ||||
|     'react-x': reactX, | ||||
|     'react-dom': reactDom, | ||||
|   }, | ||||
|   rules: { | ||||
|     // other rules... | ||||
|     // Enable its recommended typescript rules | ||||
|     ...reactX.configs['recommended-typescript'].rules, | ||||
|     ...reactDom.configs.recommended.rules, | ||||
|   }, | ||||
| }) | ||||
| ``` | ||||
							
								
								
									
										2
									
								
								banquise-website/build.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								banquise-website/build.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,2 @@ | ||||
| npm install | ||||
| npm run build | ||||
							
								
								
									
										28
									
								
								banquise-website/eslint.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								banquise-website/eslint.config.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| import js from '@eslint/js' | ||||
| import globals from 'globals' | ||||
| import reactHooks from 'eslint-plugin-react-hooks' | ||||
| import reactRefresh from 'eslint-plugin-react-refresh' | ||||
| import tseslint from 'typescript-eslint' | ||||
| 
 | ||||
| export default tseslint.config( | ||||
|   { ignores: ['dist'] }, | ||||
|   { | ||||
|     extends: [js.configs.recommended, ...tseslint.configs.recommended], | ||||
|     files: ['**/*.{ts,tsx}'], | ||||
|     languageOptions: { | ||||
|       ecmaVersion: 2020, | ||||
|       globals: globals.browser, | ||||
|     }, | ||||
|     plugins: { | ||||
|       'react-hooks': reactHooks, | ||||
|       'react-refresh': reactRefresh, | ||||
|     }, | ||||
|     rules: { | ||||
|       ...reactHooks.configs.recommended.rules, | ||||
|       'react-refresh/only-export-components': [ | ||||
|         'warn', | ||||
|         { allowConstantExport: true }, | ||||
|       ], | ||||
|     }, | ||||
|   }, | ||||
| ) | ||||
							
								
								
									
										19
									
								
								banquise-website/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								banquise-website/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <!doctype html> | ||||
| <html lang="fr"> <!-- Changement de "en" à "fr" pour refléter la langue du contenu --> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <!-- Remplacement du favicon par le logo de La Banquise --> | ||||
|     <link rel="icon" type="image/png" href="/src/assets/banquise.png" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" /> | ||||
|     <meta name="description" content="Services d'hébergement La Banquise - Accédez à notre Wiki, Gitea et Panel de jeux" /> | ||||
|     <title>La Banquise - Services d'hébergement</title> | ||||
|     <!-- Ajout des polices Google Fonts --> | ||||
|     <link rel="preconnect" href="https://fonts.googleapis.com"> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||||
|     <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div id="root"></div> | ||||
|     <script type="module" src="/src/main.tsx"></script> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										44
									
								
								banquise-website/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								banquise-website/package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| { | ||||
|   "name": "banquise-website", | ||||
|   "private": true, | ||||
|   "version": "0.0.0", | ||||
|   "type": "module", | ||||
|   "scripts": { | ||||
|     "dev": "vite", | ||||
|     "build": "tsc -b && vite build", | ||||
|     "lint": "eslint .", | ||||
|     "preview": "vite preview" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "axios": "^1.6.5", | ||||
|     "clsx": "^2.1.0", | ||||
|     "framer-motion": "^10.18.0", | ||||
|     "react": "^18.2.0", | ||||
|     "react-dom": "^18.2.0", | ||||
|     "react-icons": "^4.12.0", | ||||
|     "react-router-dom": "^6.22.0", | ||||
|     "@tanstack/react-query": "^5.17.9", | ||||
|     "tailwind-merge": "^2.2.0", | ||||
|     "zustand": "^4.4.7" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@eslint/js": "^9.25.0", | ||||
|     "@tailwindcss/forms": "^0.5.7", | ||||
|     "@tailwindcss/typography": "^0.5.10", | ||||
|     "@types/react": "^18.2.58", | ||||
|     "@types/react-dom": "^18.2.19", | ||||
|     "@vitejs/plugin-react": "^4.4.1", | ||||
|     "autoprefixer": "^10.4.16", | ||||
|     "eslint": "^9.25.0", | ||||
|     "eslint-plugin-react-hooks": "^5.2.0", | ||||
|     "eslint-plugin-react-refresh": "^0.4.19", | ||||
|     "eslint-plugin-tailwindcss": "^3.14.0", | ||||
|     "globals": "^16.0.0", | ||||
|     "postcss": "^8.4.33", | ||||
|     "typescript": "~5.8.3", | ||||
|     "typescript-eslint": "^8.30.1", | ||||
|     "vite": "^6.3.5", | ||||
|     "vite-plugin-compression": "^0.5.1", | ||||
|     "tailwindcss": "^3.4.1" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										6
									
								
								banquise-website/postcss.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								banquise-website/postcss.config.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| export default { | ||||
|   plugins: { | ||||
|     tailwindcss: {}, | ||||
|     autoprefixer: {}, | ||||
|   }, | ||||
| } | ||||
							
								
								
									
										1124
									
								
								banquise-website/src/App.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1124
									
								
								banquise-website/src/App.css
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										525
									
								
								banquise-website/src/App.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										525
									
								
								banquise-website/src/App.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,525 @@ | ||||
| import { FiUser, FiDatabase, FiShield, FiChevronDown } from 'react-icons/fi' | ||||
| import { FaDiscord, FaArrowRight, FaEnvelope, FaGithub, FaNetworkWired, FaServer, FaLaptopCode, FaCloudUploadAlt, FaExternalLinkAlt } from 'react-icons/fa' | ||||
| import { FiX, FiExternalLink } from 'react-icons/fi' | ||||
| import './App.css' | ||||
| import icebergImage from './assets/iceberg.png' | ||||
| import logoImage from './assets/banquise.png' | ||||
| import { useEffect, useState, useMemo, useCallback, useRef } from 'react' | ||||
| 
 | ||||
| import aboutImage from './assets/banquise.png' | ||||
| 
 | ||||
| function App() { | ||||
|   const [selectedService, setSelectedService] = useState<number | null>(null); | ||||
|   const [mobileMenuOpen, setMobileMenuOpen] = useState(false); | ||||
|   const mobileMenuRef = useRef<HTMLDivElement>(null); | ||||
|    | ||||
|   const services = useMemo(() => [ | ||||
|     {  | ||||
|       name: "Notre Wiki",  | ||||
|       url: "https://wiki.la-banquise.fr/en/home", | ||||
|       description: "Notre Wiki est une base de connaissances collaborative où vous trouverez toute la documentation relative à nos projets et services. Apprenez, contribuez et partagez vos connaissances avec la communauté La Banquise." | ||||
|     }, | ||||
|     {  | ||||
|       name: "Gitea",  | ||||
|       url: "https://git.la-banquise.fr/", | ||||
|       description: "Gitea est notre plateforme de gestion de code source, similaire à GitHub mais hébergée par nos soins. Créez des dépôts, collaborez sur des projets et participez au développement d'applications open-source dans un environnement sécurisé." | ||||
|     }, | ||||
|     {  | ||||
|       name: "Panel de jeux",  | ||||
|       url: "https://panel.la-banquise.fr/auth/login", | ||||
|       description: "Interface de connection à notre panel Pterodactyl, qui vous permet de gérer vos serveurs de jeux. Créez, gérez et configurez vos serveurs de jeux préférés en toute simplicité." | ||||
|     }, | ||||
|   ], []); | ||||
| 
 | ||||
|   const [icebergs, setIcebergs] = useState<Array<{ | ||||
|     id: number, | ||||
|     x: number, | ||||
|     y: number, | ||||
|     scale: number, | ||||
|     rotation: number, | ||||
|     service: typeof services[0], | ||||
|     floatClass: string | ||||
|   }>>([]) | ||||
|    | ||||
|   const [reducedMotion, setReducedMotion] = useState(false); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; | ||||
|     setReducedMotion(prefersReducedMotion); | ||||
| 
 | ||||
|     const startTime = performance.now(); | ||||
|     let count = 0; | ||||
|     while (performance.now() - startTime < 5) { | ||||
|       count++; | ||||
|     } | ||||
| 
 | ||||
|     if (count < 1000) { | ||||
|       setReducedMotion(true); | ||||
|     } | ||||
|   }, []); | ||||
| 
 | ||||
|   const positionIcebergs = useCallback(() => { | ||||
|     const newIcebergs = []; | ||||
|      | ||||
|     const positions = [ | ||||
|       { x: 25, y: 35, scale: 0.95, rotation: 0 }, | ||||
|       { x: 50, y: 25, scale: 1.1, rotation: 0 }, | ||||
|       { x: 75, y: 35, scale: 0.95, rotation: 0 }, | ||||
|     ]; | ||||
|      | ||||
|     const floatClasses = ['float-1', 'float-2', 'float-3', 'float-4', 'float-5']; | ||||
|      | ||||
|     for (let i = 0; i < services.length; i++) { | ||||
|       const position = positions[i % positions.length]; | ||||
|        | ||||
|       newIcebergs.push({ | ||||
|         id: i, | ||||
|         x: position.x, | ||||
|         y: position.y, | ||||
|         scale: position.scale, | ||||
|         rotation: position.rotation, | ||||
|         service: services[i], | ||||
|         floatClass: reducedMotion ? '' : floatClasses[i % floatClasses.length] | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     return newIcebergs; | ||||
|   }, [services, reducedMotion]); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     setIcebergs(positionIcebergs()); | ||||
|   }, [positionIcebergs]); | ||||
| 
 | ||||
|   const renderBubbles = useMemo(() => { | ||||
|     if (reducedMotion) return null; | ||||
|      | ||||
|     return ( | ||||
|       <div className="bubbles"> | ||||
|         <div className="bubble"></div> | ||||
|         <div className="bubble"></div> | ||||
|         <div className="bubble"></div> | ||||
|         <div className="bubble"></div> | ||||
|         <div className="bubble"></div> | ||||
|         <div className="bubble"></div> | ||||
|         <div className="bubble"></div> | ||||
|       </div> | ||||
|     ); | ||||
|   }, [reducedMotion]); | ||||
| 
 | ||||
|   const handleIcebergClick = (event: React.MouseEvent, serviceId: number) => { | ||||
|     event.preventDefault(); | ||||
|     setSelectedService(serviceId); | ||||
|   }; | ||||
| 
 | ||||
|   const handleClosePopup = () => { | ||||
|     setSelectedService(null); | ||||
|   }; | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     const handleOutsideClick = (event: MouseEvent) => { | ||||
|       if (mobileMenuRef.current && !mobileMenuRef.current.contains(event.target as Node)) { | ||||
|         setMobileMenuOpen(false); | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     if (mobileMenuOpen) { | ||||
|       document.addEventListener('mousedown', handleOutsideClick); | ||||
|     } | ||||
| 
 | ||||
|     return () => { | ||||
|       document.removeEventListener('mousedown', handleOutsideClick); | ||||
|     }; | ||||
|   }, [mobileMenuOpen]); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     if (mobileMenuOpen) { | ||||
|       document.body.style.overflow = 'hidden'; | ||||
|     } else { | ||||
|       document.body.style.overflow = 'auto'; | ||||
|     } | ||||
|      | ||||
|     return () => { | ||||
|       document.body.style.overflow = 'auto'; | ||||
|     }; | ||||
|   }, [mobileMenuOpen]); | ||||
| 
 | ||||
|   const [activeAccordion, setActiveAccordion] = useState<number | null>(null); | ||||
|    | ||||
|   // FAQ items for the about section
 | ||||
|   const faqItems = useMemo(() => [ | ||||
|     { | ||||
|       question: "Qui sommes-nous ?", | ||||
|       answer: ( | ||||
|         <> | ||||
|           <p>La Banquise est une initiative d'étudiants de l'EPITA Lyon dont l'objectif est de rendre plus accessible l'hébergement de services informatiques. Fondée en 2023, notre association à but non lucratif vise à permettre à ceux qui le souhaitent de se former sur des technologies d'hébergement et de réseau.</p> | ||||
|           <p>Notre équipe est composée d'étudiants passionnés par l'informatique, le réseau et le partage de connaissances. Nous mettons notre expertise au service des étudiants et des associations de l'EPITA.</p> | ||||
|         </> | ||||
|       ) | ||||
|     }, | ||||
|     { | ||||
|       question: "Comment candidater pour rejoindre La Banquise ?", | ||||
|       answer: ( | ||||
|         <> | ||||
|           <p>Pour rejoindre notre équipe, rien de plus simple :</p> | ||||
|           <ul> | ||||
|             <li>Rejoignez notre serveur Discord</li> | ||||
|             <li>Présentez-vous et expliquez votre motivation dans un ticket</li> | ||||
|             <li>Précisez vos compétences ou les domaines qui vous intéressent</li> | ||||
|             <li>Un membre de notre équipe vous contactera pour un échange</li> | ||||
|           </ul> | ||||
|           <p>Nous recherchons des personnes motivées, peu importe votre niveau technique actuel !</p> | ||||
|           <a href="https://discord.com/invite/QQWwzX5ptY" className="accordion-cta" target="_blank" rel="noopener noreferrer"> | ||||
|             Rejoindre le Discord <FaExternalLinkAlt className="accordion-cta-icon" /> | ||||
|           </a> | ||||
|         </> | ||||
|       ) | ||||
|     }, | ||||
|     { | ||||
|       question: "Quels sont nos objectifs ?", | ||||
|       answer: ( | ||||
|         <> | ||||
|           <p>Nos principaux objectifs sont :</p> | ||||
|           <ul> | ||||
|             <li>Former les étudiants aux technologies d'hébergement et de réseau</li> | ||||
|             <li>Fournir des services informatiques de qualité aux étudiants et associations de l'EPITA</li> | ||||
|             <li>Promouvoir le partage de connaissances et l'entraide</li> | ||||
|             <li>Créer un environnement d'apprentissage pratique par l'expérience</li> | ||||
|             <li>Maintenir une infrastructure robuste et sécurisée</li> | ||||
|           </ul> | ||||
|         </> | ||||
|       ) | ||||
|     }, | ||||
|     { | ||||
|       question: "Comment utiliser nos services ?", | ||||
|       answer: ( | ||||
|         <> | ||||
|           <p>Pour accéder à nos services :</p> | ||||
|           <ol> | ||||
|             <li>Créez un compte sur notre plateforme d'authentification</li> | ||||
|             <li>Connectez-vous au service souhaité avec vos identifiants</li> | ||||
|             <li>Consultez notre Wiki pour obtenir de l'aide sur l'utilisation de chaque service</li> | ||||
|           </ol> | ||||
|           <p>Si vous rencontrez des difficultés, n'hésitez pas à demander de l'aide sur notre Discord.</p> | ||||
|           <a href="https://auth.la-banquise.fr/" className="accordion-cta" target="_blank" rel="noopener noreferrer"> | ||||
|             Créer un compte <FaExternalLinkAlt className="accordion-cta-icon" /> | ||||
|           </a> | ||||
|         </> | ||||
|       ) | ||||
|     }, | ||||
|     { | ||||
|       question: "Comment contribuer au projet ?", | ||||
|       answer: ( | ||||
|         <> | ||||
|           <p>Il existe plusieurs façons de contribuer au projet La Banquise :</p> | ||||
|           <ul> | ||||
|             <li>Rejoindre l'équipe en tant que membre actif</li> | ||||
|             <li>Contribuer au code source de nos projets via Gitea</li> | ||||
|             <li>Rédiger ou améliorer la documentation sur notre Wiki</li> | ||||
|             <li>Proposer de nouvelles idées de services ou d'améliorations</li> | ||||
|             <li>Aider d'autres utilisateurs sur notre Discord</li> | ||||
|           </ul> | ||||
|           <p>Toutes les contributions sont les bienvenues, même les plus modestes !</p> | ||||
|         </> | ||||
|       ) | ||||
|     }, | ||||
|   ], []); | ||||
| 
 | ||||
|   const toggleAccordion = (index: number) => { | ||||
|     setActiveAccordion(activeAccordion === index ? null : index); | ||||
|   }; | ||||
|    | ||||
|   return ( | ||||
|     <div className="app-container"> | ||||
|       <a href="#main-content" className="sr-only focus:not-sr-only">Passer au contenu principal</a> | ||||
|        | ||||
|       <header> | ||||
|         <nav className="navbar" aria-label="Navigation principale"> | ||||
|           <div className="navbar-left"> | ||||
|             <img src={logoImage} alt="Logo La Banquise" className="site-logo" /> | ||||
|             <h1 className="site-name">La Banquise</h1> | ||||
|           </div> | ||||
|            | ||||
|           <button  | ||||
|             className={`navbar-mobile-toggle ${mobileMenuOpen ? 'active' : ''}`} | ||||
|             onClick={() => setMobileMenuOpen(!mobileMenuOpen)} | ||||
|             aria-expanded={mobileMenuOpen} | ||||
|             aria-label="Menu de navigation" | ||||
|           > | ||||
|             <span></span> | ||||
|             <span></span> | ||||
|             <span></span> | ||||
|           </button> | ||||
|            | ||||
|           <div  | ||||
|             className={`navbar-right ${mobileMenuOpen ? 'mobile-active' : ''}`} | ||||
|             ref={mobileMenuRef} | ||||
|           > | ||||
|             <a  | ||||
|               href="https://discord.com/invite/QQWwzX5ptY"  | ||||
|               className="discord-button"  | ||||
|               target="_blank"  | ||||
|               rel="noopener noreferrer" | ||||
|               aria-label="Rejoindre notre Discord" | ||||
|               onClick={() => setMobileMenuOpen(false)} | ||||
|             > | ||||
|               <FaDiscord className="discord-icon" aria-hidden="true" /> | ||||
|               <span>Discord</span> | ||||
|             </a> | ||||
|             <a  | ||||
|               href="https://auth.la-banquise.fr/"  | ||||
|               className="login-button" | ||||
|               aria-label="Se connecter à votre compte" | ||||
|               onClick={() => setMobileMenuOpen(false)} | ||||
|             > | ||||
|               <FiUser className="login-icon" aria-hidden="true" /> | ||||
|               <span>Se connecter</span> | ||||
|             </a> | ||||
|           </div> | ||||
|            | ||||
|           <div  | ||||
|             className={`mobile-menu-overlay ${mobileMenuOpen ? 'active' : ''}`} | ||||
|             onClick={() => setMobileMenuOpen(false)} | ||||
|           ></div> | ||||
|         </nav> | ||||
|       </header> | ||||
|        | ||||
|       <main id="main-content" className="content"> | ||||
|         <div className="ocean" role="region" aria-label="Services La Banquise"> | ||||
|           {renderBubbles} | ||||
|            | ||||
|           <section className="page-section hero-section"> | ||||
|             <div className="hero-tech-elements"> | ||||
|               <div className="tech-element tech-element-1"><FaServer /></div> | ||||
|               <div className="tech-element tech-element-2"><FaLaptopCode /></div> | ||||
|               <div className="tech-element tech-element-3"><FaNetworkWired /></div> | ||||
|               <div className="tech-element tech-element-4"><FaCloudUploadAlt /></div> | ||||
|             </div> | ||||
|              | ||||
|             <div className="hero-logo-container"> | ||||
|               <img src={logoImage} alt="Logo La Banquise" className="hero-logo" /> | ||||
|             </div> | ||||
|             <h2 className="hero-title">Association La Banquise</h2> | ||||
|             <p className="hero-subtitle"> | ||||
|               Association d'hébergement et lab réseau pour tous les étudiants et associations de l'EPITA | ||||
|             </p> | ||||
|             <div> | ||||
|               <a href="https://discord.com/invite/QQWwzX5ptY" className="cta-button" target="_blank" rel="noopener noreferrer"> | ||||
|                 Notre Discord | ||||
|                 <FaArrowRight className="cta-icon" /> | ||||
|               </a> | ||||
|             </div> | ||||
|           </section> | ||||
| 
 | ||||
|           <section className="page-section tech-features-section"> | ||||
|             <div className="section-divider"></div> | ||||
|             <h2 className="section-title">Notre infrastructure</h2> | ||||
|             <p className="section-subtitle"> | ||||
|               Des services robustes et sécurisés pour répondre à vos besoins | ||||
|             </p> | ||||
|              | ||||
|             <div className="tech-features-grid"> | ||||
|               <div className="tech-feature-card"> | ||||
|                 <div className="tech-feature-icon"> | ||||
|                   <FaServer /> | ||||
|                 </div> | ||||
|                 <h3 className="tech-feature-title">Serveurs performants</h3> | ||||
|                 <p className="tech-feature-description"> | ||||
|                   Infrastructure optimisée pour assurer des performances élevées et une disponibilité maximale de vos applications | ||||
|                 </p> | ||||
|               </div> | ||||
|                | ||||
|               <div className="tech-feature-card"> | ||||
|                 <div className="tech-feature-icon"> | ||||
|                   <FiDatabase /> | ||||
|                 </div> | ||||
|                 <h3 className="tech-feature-title">Stockage sécurisé</h3> | ||||
|                 <p className="tech-feature-description"> | ||||
|                   Solutions de stockage distribuées avec redondance pour garantir l'intégrité et la durabilité de vos données | ||||
|                 </p> | ||||
|               </div> | ||||
|                | ||||
|               <div className="tech-feature-card"> | ||||
|                 <div className="tech-feature-icon"> | ||||
|                   <FaNetworkWired /> | ||||
|                 </div> | ||||
|                 <h3 className="tech-feature-title">Réseau optimisé</h3> | ||||
|                 <p className="tech-feature-description"> | ||||
|                   Architecture réseau à haute disponibilité avec une faible latence pour vos applications critiques | ||||
|                 </p> | ||||
|               </div> | ||||
|                | ||||
|               <div className="tech-feature-card"> | ||||
|                 <div className="tech-feature-icon"> | ||||
|                   <FiShield /> | ||||
|                 </div> | ||||
|                 <h3 className="tech-feature-title">Sécurité renforcée</h3> | ||||
|                 <p className="tech-feature-description"> | ||||
|                   Protection contre les menaces avec systèmes de sécurité modernes et mises à jour régulières | ||||
|                 </p> | ||||
|               </div> | ||||
|             </div> | ||||
|           </section> | ||||
|            | ||||
|           <section className="page-section services-section" id="services"> | ||||
|             <div className="section-divider"></div> | ||||
|             <h2 className="section-title">Nos services</h2> | ||||
|             <p className="section-subtitle"> | ||||
|               Explorez notre écosystème de services conçus pour répondre à vos besoins. | ||||
|             </p> | ||||
|              | ||||
|             <div  | ||||
|               className="icebergs-container" | ||||
|               role="list"  | ||||
|               aria-label="Liste des services disponibles" | ||||
|             > | ||||
|               {icebergs.map((iceberg) => ( | ||||
|                 <a | ||||
|                   key={iceberg.id} | ||||
|                   href={iceberg.service.url} | ||||
|                   className={`iceberg ${iceberg.floatClass}`} | ||||
|                   style={{ | ||||
|                     transform: `rotate(${iceberg.rotation}deg) scale(${iceberg.scale}) translateZ(0)`, | ||||
|                   }} | ||||
|                   role="listitem" | ||||
|                   aria-label={`En savoir plus sur ${iceberg.service.name}`} | ||||
|                   onClick={(e) => handleIcebergClick(e, iceberg.id)} | ||||
|                 > | ||||
|                   <img  | ||||
|                     src={icebergImage}  | ||||
|                     alt=""  | ||||
|                     className="iceberg-image" | ||||
|                     loading="lazy" | ||||
|                     aria-hidden="true" | ||||
|                   /> | ||||
|                   <div className="service-name">{iceberg.service.name}</div> | ||||
|                 </a> | ||||
|               ))} | ||||
|             </div> | ||||
|           </section> | ||||
|            | ||||
|           <section className="page-section about-section" id="about"> | ||||
|             <div className="section-divider"></div> | ||||
|             <h2 className="section-title">À propos de nous</h2> | ||||
|             <p className="section-subtitle"> | ||||
|               Découvrez notre mission et posez-nous vos questions | ||||
|             </p> | ||||
|              | ||||
|             <div className="about-container"> | ||||
|               <div className="about-image-container"> | ||||
|                 <img src={aboutImage} alt="Logo La Banquise" className="about-logo" /> | ||||
|               </div> | ||||
|                | ||||
|               <p className="about-intro"> | ||||
|                 La Banquise est une association étudiante dédiée à l'hébergement de services et à la formation sur les technologies réseau, au service de la communauté EPITA. | ||||
|               </p> | ||||
|                | ||||
|               <div className="accordion-group" role="region" aria-label="Foire aux questions"> | ||||
|                 {faqItems.map((item, index) => ( | ||||
|                   <div  | ||||
|                     key={index}  | ||||
|                     className={`accordion-item ${activeAccordion === index ? 'active' : ''}`} | ||||
|                   > | ||||
|                     <div  | ||||
|                       className="accordion-header"  | ||||
|                       onClick={() => toggleAccordion(index)} | ||||
|                       role="button" | ||||
|                       aria-expanded={activeAccordion === index} | ||||
|                       aria-controls={`accordion-content-${index}`} | ||||
|                       tabIndex={0} | ||||
|                       onKeyPress={(e) => { | ||||
|                         if (e.key === 'Enter' || e.key === ' ') { | ||||
|                           toggleAccordion(index); | ||||
|                         } | ||||
|                       }} | ||||
|                     > | ||||
|                       {item.question} | ||||
|                       <FiChevronDown className="accordion-toggle-icon" aria-hidden="true" /> | ||||
|                     </div> | ||||
|                     <div  | ||||
|                       className="accordion-content"  | ||||
|                       id={`accordion-content-${index}`} | ||||
|                       role="region" | ||||
|                     > | ||||
|                       {item.answer} | ||||
|                     </div> | ||||
|                   </div> | ||||
|                 ))} | ||||
|               </div> | ||||
|             </div> | ||||
|           </section> | ||||
|            | ||||
|           {selectedService !== null && ( | ||||
|             <div className="popup-overlay" onClick={handleClosePopup} role="dialog" aria-modal="true" aria-labelledby="popup-title"> | ||||
|               <div className="popup-content" onClick={(e) => e.stopPropagation()}> | ||||
|                 <button className="popup-close" onClick={handleClosePopup} aria-label="Fermer"> | ||||
|                   <FiX /> | ||||
|                 </button> | ||||
|                 <h3 id="popup-title" className="popup-title">{services[selectedService].name}</h3> | ||||
|                 <p className="popup-description">{services[selectedService].description}</p> | ||||
|                 <a  | ||||
|                   href={services[selectedService].url}  | ||||
|                   className="popup-button" | ||||
|                   target="_blank"  | ||||
|                   rel="noopener noreferrer" | ||||
|                 > | ||||
|                   <FiExternalLink className="popup-button-icon" /> | ||||
|                   <span>Accéder au service</span> | ||||
|                 </a> | ||||
|               </div> | ||||
|             </div> | ||||
|           )} | ||||
|            | ||||
|           <div className="code-background"> | ||||
|             <div className="code-line">const banquise = new ServerInfra();</div> | ||||
|             <div className="code-line">banquise.deploy('wiki');</div> | ||||
|             <div className="code-line">banquise.deploy('gitea');</div> | ||||
|             <div className="code-line">banquise.optimize();</div> | ||||
|             <div className="code-line">banquise.monitor();</div> | ||||
|           </div> | ||||
|            | ||||
|           <div className="waves" aria-hidden="true"> | ||||
|             <div className="wave wave1"></div> | ||||
|             <div className="wave wave2"></div> | ||||
|             <div className="wave wave3"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </main> | ||||
|        | ||||
|       <footer className="footer"> | ||||
|         <div className="footer-content"> | ||||
|           <div className="footer-column"> | ||||
|             <h4>La Banquise</h4> | ||||
|             <ul> | ||||
|               <li><a href="#about">À propos</a></li> | ||||
|               <li><a href="#services">Services</a></li> | ||||
|               <li><a href="https://wiki.la-banquise.fr/en/home">Documentation</a></li> | ||||
|               <li><a href="#contact">Contact</a></li> | ||||
|             </ul> | ||||
|           </div> | ||||
|           <div className="footer-column"> | ||||
|             <h4>Services</h4> | ||||
|             <ul> | ||||
|               {services.map((service, index) => ( | ||||
|                 <li key={index}><a href={service.url}>{service.name}</a></li> | ||||
|               ))} | ||||
|             </ul> | ||||
|           </div> | ||||
|           <div className="footer-column"> | ||||
|             <h4>Communauté</h4> | ||||
|             <ul> | ||||
|               <li><a href="https://discord.com/invite/QQWwzX5ptY" target="_blank" rel="noopener noreferrer">Discord</a></li> | ||||
|               <li><a href="https://git.la-banquise.fr/" target="_blank" rel="noopener noreferrer">Gitea</a></li> | ||||
|               <li><a href="mailto:contact@la-banquise.fr"><FaEnvelope style={{marginRight: '0.5rem'}} /> contact@la-banquise.fr</a></li> | ||||
|               <li><a href="https://github.com/la-banquise" target="_blank" rel="noopener noreferrer"><FaGithub style={{marginRight: '0.5rem'}} /> GitHub</a></li> | ||||
|             </ul> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div className="footer-bottom"> | ||||
|           <p>© {new Date().getFullYear()} La Banquise. Tous droits réservés.</p> | ||||
|         </div> | ||||
|       </footer> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export default App; | ||||
							
								
								
									
										
											BIN
										
									
								
								banquise-website/src/assets/banquise.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								banquise-website/src/assets/banquise.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 188 KiB | 
							
								
								
									
										
											BIN
										
									
								
								banquise-website/src/assets/iceberg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								banquise-website/src/assets/iceberg.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 121 KiB | 
							
								
								
									
										103
									
								
								banquise-website/src/index.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								banquise-website/src/index.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | ||||
| @tailwind base; | ||||
| @tailwind components; | ||||
| @tailwind utilities; | ||||
| 
 | ||||
| /* Système typographique moderne */ | ||||
| :root { | ||||
|   --font-heading: 'Space Grotesk', sans-serif; | ||||
|   --font-body: 'Inter', system-ui, sans-serif; | ||||
|    | ||||
|   font-family: var(--font-body); | ||||
|   line-height: 1.5; | ||||
|   font-weight: 400; | ||||
| 
 | ||||
|   color-scheme: light dark; | ||||
|   color: rgba(255, 255, 255, 0.87); | ||||
|   background-color: #242424; | ||||
| 
 | ||||
|   font-synthesis: none; | ||||
|   text-rendering: optimizeLegibility; | ||||
|   -webkit-font-smoothing: antialiased; | ||||
|   -moz-osx-font-smoothing: grayscale; | ||||
| } | ||||
| 
 | ||||
| /* Hiérarchie typographique */ | ||||
| h1, h2, h3, h4, h5, h6, .site-name, .welcome-title { | ||||
|   font-family: var(--font-heading); | ||||
|   font-weight: 600; | ||||
|   line-height: 1.2; | ||||
|   letter-spacing: -0.025em; | ||||
| } | ||||
| 
 | ||||
| h1 { | ||||
|   font-size: 3.2em; | ||||
|   line-height: 1.1; | ||||
|   font-weight: 700; | ||||
| } | ||||
| 
 | ||||
| h2 { | ||||
|   font-size: 2.4em; | ||||
|   font-weight: 600; | ||||
| } | ||||
| 
 | ||||
| h3 { | ||||
|   font-size: 1.8em; | ||||
|   font-weight: 600; | ||||
| } | ||||
| 
 | ||||
| p, span, div, a, button, input { | ||||
|   font-family: var(--font-body); | ||||
| } | ||||
| 
 | ||||
| a { | ||||
|   font-weight: 500; | ||||
|   color: #646cff; | ||||
|   text-decoration: inherit; | ||||
| } | ||||
| 
 | ||||
| a:hover { | ||||
|   color: #535bf2; | ||||
| } | ||||
| 
 | ||||
| body { | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   display: flex; | ||||
|   min-width: 320px; | ||||
|   min-height: 100vh; | ||||
|   width: 100%; | ||||
| } | ||||
| 
 | ||||
| button { | ||||
|   border-radius: 8px; | ||||
|   border: 1px solid transparent; | ||||
|   padding: 0.6em 1.2em; | ||||
|   font-size: 1em; | ||||
|   font-weight: 500; | ||||
|   font-family: var(--font-body); | ||||
|   background-color: #1a1a1a; | ||||
|   cursor: pointer; | ||||
|   transition: border-color 0.25s; | ||||
| } | ||||
| 
 | ||||
| button:hover { | ||||
|   border-color: #646cff; | ||||
| } | ||||
| 
 | ||||
| button:focus, | ||||
| button:focus-visible { | ||||
|   outline: 4px auto -webkit-focus-ring-color; | ||||
| } | ||||
| 
 | ||||
| @media (prefers-color-scheme: light) { | ||||
|   :root { | ||||
|     color: #213547; | ||||
|     background-color: #ffffff; | ||||
|   } | ||||
|   a:hover { | ||||
|     color: #747bff; | ||||
|   } | ||||
|   button { | ||||
|     background-color: #f9f9f9; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										10
									
								
								banquise-website/src/main.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								banquise-website/src/main.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| import { StrictMode } from 'react' | ||||
| import { createRoot } from 'react-dom/client' | ||||
| import './index.css' | ||||
| import App from './App.tsx' | ||||
| 
 | ||||
| createRoot(document.getElementById('root')!).render( | ||||
|   <StrictMode> | ||||
|     <App /> | ||||
|   </StrictMode>, | ||||
| ) | ||||
							
								
								
									
										1
									
								
								banquise-website/src/vite-env.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								banquise-website/src/vite-env.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| /// <reference types="vite/client" />
 | ||||
							
								
								
									
										21
									
								
								banquise-website/tailwind.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								banquise-website/tailwind.config.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| /** @type {import('tailwindcss').Config} */ | ||||
| export default { | ||||
|   content: [ | ||||
|     "./index.html", | ||||
|     "./src/**/*.{js,ts,jsx,tsx}", | ||||
|   ], | ||||
|   theme: { | ||||
|     extend: { | ||||
|       colors: { | ||||
|         // Vous pouvez personnaliser vos couleurs ici
 | ||||
|       }, | ||||
|       fontFamily: { | ||||
|         // Personnalisation des polices
 | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   plugins: [ | ||||
|     require('@tailwindcss/forms'), | ||||
|     require('@tailwindcss/typography'), | ||||
|   ], | ||||
| } | ||||
							
								
								
									
										27
									
								
								banquise-website/tsconfig.app.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								banquise-website/tsconfig.app.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", | ||||
|     "target": "ES2020", | ||||
|     "useDefineForClassFields": true, | ||||
|     "lib": ["ES2020", "DOM", "DOM.Iterable"], | ||||
|     "module": "ESNext", | ||||
|     "skipLibCheck": true, | ||||
| 
 | ||||
|     /* Bundler mode */ | ||||
|     "moduleResolution": "bundler", | ||||
|     "allowImportingTsExtensions": true, | ||||
|     "verbatimModuleSyntax": true, | ||||
|     "moduleDetection": "force", | ||||
|     "noEmit": true, | ||||
|     "jsx": "react-jsx", | ||||
| 
 | ||||
|     /* Linting */ | ||||
|     "strict": true, | ||||
|     "noUnusedLocals": true, | ||||
|     "noUnusedParameters": true, | ||||
|     "erasableSyntaxOnly": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "noUncheckedSideEffectImports": true | ||||
|   }, | ||||
|   "include": ["src"] | ||||
| } | ||||
							
								
								
									
										7
									
								
								banquise-website/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								banquise-website/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| { | ||||
|   "files": [], | ||||
|   "references": [ | ||||
|     { "path": "./tsconfig.app.json" }, | ||||
|     { "path": "./tsconfig.node.json" } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										25
									
								
								banquise-website/tsconfig.node.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								banquise-website/tsconfig.node.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", | ||||
|     "target": "ES2022", | ||||
|     "lib": ["ES2023"], | ||||
|     "module": "ESNext", | ||||
|     "skipLibCheck": true, | ||||
| 
 | ||||
|     /* Bundler mode */ | ||||
|     "moduleResolution": "bundler", | ||||
|     "allowImportingTsExtensions": true, | ||||
|     "verbatimModuleSyntax": true, | ||||
|     "moduleDetection": "force", | ||||
|     "noEmit": true, | ||||
| 
 | ||||
|     /* Linting */ | ||||
|     "strict": true, | ||||
|     "noUnusedLocals": true, | ||||
|     "noUnusedParameters": true, | ||||
|     "erasableSyntaxOnly": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "noUncheckedSideEffectImports": true | ||||
|   }, | ||||
|   "include": ["vite.config.ts"] | ||||
| } | ||||
							
								
								
									
										27
									
								
								banquise-website/vite.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								banquise-website/vite.config.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| import { defineConfig } from 'vite' | ||||
| import react from '@vitejs/plugin-react' | ||||
| import viteCompression from 'vite-plugin-compression' | ||||
| 
 | ||||
| // https://vitejs.dev/config/
 | ||||
| export default defineConfig({ | ||||
|   plugins: [ | ||||
|     react(), | ||||
|     viteCompression({ | ||||
|       verbose: false, | ||||
|       algorithm: 'gzip', | ||||
|       ext: '.gz', | ||||
|     }), | ||||
|   ], | ||||
|   build: { | ||||
|     minify: 'esbuild', | ||||
|     cssMinify: true, | ||||
|     rollupOptions: { | ||||
|       output: { | ||||
|         manualChunks: { | ||||
|           react: ['react', 'react-dom'], | ||||
|           router: ['react-router-dom'], | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
| }) | ||||
| @ -1,24 +0,0 @@ | ||||
| <svg width="1800" height="1000" viewBox="0 -300 1800 1000" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
|   <!-- Mât du drapeau --> | ||||
|   <rect x="910" y="-220" width="50" height="220" fill="#1F5078"/> | ||||
|   <!-- Petit drapeau --> | ||||
|   <polygon points="960,-220 1250,-110 960,0" fill="#F2F2F2" stroke="#1F5078" stroke-width="1"/> | ||||
|   <!-- Fond + contour --> | ||||
|   <polygon fill="#34A6FC" points="0,676 0,725 1779,725 1778,675 1470,675  | ||||
|     1380,600 1275,350  1273,346 1268,338 1263,335 1257,332 1245,338  | ||||
|     1239,341 1131,384 1080,300 1073,260 1020,120 956,15 957,14.7431  | ||||
|     950,6 950,3 935,0 923,0 915,10 913,15 850,200 796.5,256  | ||||
|     730,200 728,200 710,178 697,178 350,676" /> | ||||
|   <!-- Autres conversions en polygon identiques aux points du SVG d'origine --> | ||||
|   <polygon fill="#F2F2F2" points="775,300 707.5,239.5 646,552.5 656.5,548.5 775,300" /> | ||||
|   <polygon fill="#F2F2F2" points="750.5,663 641.5,603.5 938.5,494.5 750.5,663" /> | ||||
|   <polygon fill="#F2F2F2" points="1271,576.5 1277,442 1391.5,637 1271,576.5" /> | ||||
|   <polygon fill="#F2F2F2" points="1366.5,675 1267.5,625.5 1303,675 1366.5,675" /> | ||||
|   <polygon fill="#76BEEE" points="644.5,316.5 592.5,570.5 398,645.5 644.5,316.5" /> | ||||
|   <polygon fill="#76BEEE" points="832,481.5 717.5,523.5 884.5,180.5 832,481.5" /> | ||||
|   <polygon fill="#76BEEE" points="1047.5,458.5 803.5,675 1036.5,675.5 1155.5,562.5 1047.5,458.5" /> | ||||
|   <polygon fill="#76BEEE" points="1230.5,395 1205.5,404.833 1154.9,424.8 1152.5,426 1206.5,543 1227.5,553.5 1230.5,395" /> | ||||
|   <polygon fill="#A0ECF9" points="1021.5,412.5 881.5,463.5 946.5,101.5 1113.5,458.5" /> | ||||
|   <polygon fill="#A0ECF9" points="584.5,622.5 443,676 677.5,676 584.5,622.5" /> | ||||
|   <polygon fill="#A0ECF9" points="1188,596.5 1161.17,621.667 1106.8,672.8 1104,676 1246,676 1188,596.5" /> | ||||
| </svg> | ||||
| Before Width: | Height: | Size: 1.7 KiB | 
| @ -1,31 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="fr"> | ||||
| 
 | ||||
| <head> | ||||
|   <meta charset="UTF-8" /> | ||||
|   <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|   <title>La Banquise</title> | ||||
|   <link rel="stylesheet" href="style.css" /> | ||||
| </head> | ||||
| 
 | ||||
| <body> | ||||
|   <h1 class="title">La Banquise</h1> | ||||
|   <div class="grid-container"> | ||||
| 
 | ||||
|     <a class="grid-item" href="localhost"> | ||||
|       <object data="assets/iceberg.svg" type="image/svg+xml"></object> | ||||
|       <p class="item-name">Placeholder</p> | ||||
|     </a> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="wave hidden"> | ||||
|     <svg viewBox="0 0 1200 120" preserveAspectRatio="none"> | ||||
|       <path d="M0,0 C600,100 600,100 1200,0 V120 H0 V0 Z" class="shape-fill"></path> | ||||
|     </svg> | ||||
|   </div> | ||||
| 
 | ||||
|   <script src="./script.js"></script> | ||||
| 
 | ||||
| </body> | ||||
| 
 | ||||
| </html> | ||||
| @ -1,22 +0,0 @@ | ||||
| const tile = document.querySelectorAll(".grid-container > *")[0]; | ||||
| const parent = tile.parentNode; | ||||
| tile.remove(); | ||||
| 
 | ||||
| const tiles = [ | ||||
|   { name: "Notre wiki", href: "https://wiki.la-banquise.fr" }, | ||||
|   { name: "Notre git", href: "https://git.la-banquise.fr" }, | ||||
|   { name: "Panel jeux", href: "https://panel.la-banquise.fr" }, | ||||
|   { name: "Discord", href: "https://discord.gg/QQWwzX5ptY" }, | ||||
|   { name: "Login", href: "https://auth.la-banquise.fr" }, | ||||
|   { name: "Change password", href: "https://ssp.la-banquise.fr" }, | ||||
| ] | ||||
| 
 | ||||
| tiles.forEach((info) => { | ||||
|   const newTile = tile.cloneNode(true); | ||||
|   newTile.querySelectorAll(".item-name").forEach((el) => { | ||||
|     el.innerText = info.name; | ||||
|   }); | ||||
|   newTile.href = info.href; | ||||
|   parent.appendChild(newTile); | ||||
| }); | ||||
| 
 | ||||
| @ -1,136 +0,0 @@ | ||||
| @import url('https://fonts.googleapis.com/css2?family=League+Spartan:wght@100..900&family=Roboto:ital,wght@0,100..900;1,100..900&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap'); | ||||
| 
 | ||||
| * { | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   box-sizing: border-box; | ||||
|   font-family: Roboto, sans-serif; | ||||
| } | ||||
| 
 | ||||
| body { | ||||
|   margin: 0; | ||||
|   padding: 30px; | ||||
|   min-height: 100vh; | ||||
|   background: linear-gradient(45deg, #001e6c, #5dadc2, #001e6c); | ||||
|   background-size: 400% 400%; | ||||
|   animation: gradient 100s ease infinite; | ||||
| } | ||||
| 
 | ||||
| @keyframes gradient { | ||||
|   0% { | ||||
|     background-position: 0% 50%; | ||||
|   } | ||||
| 
 | ||||
|   50% { | ||||
|     background-position: 100% 50%; | ||||
|   } | ||||
| 
 | ||||
|   100% { | ||||
|     background-position: 0% 50%; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| h1.title { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
| } | ||||
| 
 | ||||
| .hidden { | ||||
|   visibility: hidden; | ||||
| } | ||||
| 
 | ||||
| /* Style de la vague en bas de page */ | ||||
| .wave { | ||||
|   position: absolute; | ||||
|   bottom: 0; | ||||
|   left: 0; | ||||
|   width: 100%; | ||||
|   overflow: hidden; | ||||
|   line-height: 0; | ||||
| } | ||||
| 
 | ||||
| .wave svg { | ||||
|   position: relative; | ||||
|   display: block; | ||||
|   width: calc(100% + 1.3px); | ||||
|   height: 150px; | ||||
| } | ||||
| 
 | ||||
| .wave .shape-fill { | ||||
|   fill: rgba(255, 255, 255, 0.2); | ||||
| } | ||||
| 
 | ||||
| .title { | ||||
|   font-size: 2.5rem; | ||||
|   margin-bottom: 2rem; | ||||
| } | ||||
| 
 | ||||
| /* En-tête du site */ | ||||
| header { | ||||
|   text-align: center; | ||||
|   color: #fff; | ||||
|   padding: 1rem; | ||||
| } | ||||
| 
 | ||||
| /* Container en flexbox pour agencer les éléments dans une "grid" */ | ||||
| .grid-container { | ||||
|   flex: 1; | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   justify-content: center; | ||||
|   align-items: stretch; | ||||
|   gap: 20px; | ||||
|   padding: 1rem; | ||||
| } | ||||
| 
 | ||||
| /* Chaque élément de la grid */ | ||||
| .grid-item { | ||||
|   background: rgba(255, 255, 255, 0); | ||||
|   padding: 2px; | ||||
|   border-radius: 8px; | ||||
|   color: #fff; | ||||
|   text-align: center; | ||||
|   /* Permet de s'étendre sur au moins 300px et de grandir si besoin */ | ||||
|   flex: 0 1 calc(10% - 40px); | ||||
|   /* 3 items par ligne avec 20px de gap */ | ||||
|   max-width: calc(10% - 40px); | ||||
|   box-shadow: 0 4px 6px rgba(0, 0, 0, 0); | ||||
|   transition: transform 0.3s; | ||||
| } | ||||
| 
 | ||||
| .grid-item:hover { | ||||
|   transform: scale(1.05); | ||||
|   background: rgba(255, 255, 255, 0.1); | ||||
|   box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); | ||||
| } | ||||
| 
 | ||||
| .grid-item img, | ||||
| .grid-item object { | ||||
|   max-width: 100%; | ||||
|   height: auto; | ||||
|   display: block; | ||||
|   margin: 0 auto 10px; | ||||
|   /* Pour donner une vue isométrique */ | ||||
|   transform: rotateX(0deg) rotateZ(0deg); | ||||
|   transform-origin: center; | ||||
| } | ||||
| 
 | ||||
| .grid-item p { | ||||
|   font-size: 1.5rem; | ||||
|   margin-top: 0rem; | ||||
|   font-weight: bold; | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 900px) { | ||||
|   .grid-item { | ||||
|     flex: 0 1 calc(25% - 40px); | ||||
|     max-width: calc(25% - 40px); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 600px) { | ||||
|   .grid-item { | ||||
|     flex: 0 1 calc(50% - 40px); | ||||
|     max-width: calc(50% - 40px); | ||||
|   } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user