WIP: update to next.js #37
@ -18,6 +18,12 @@
|
|||||||
--color-banquise-blue-lightest-hex: #A5F0FF;
|
--color-banquise-blue-lightest-hex: #A5F0FF;
|
||||||
--color-banquise-gray: #F6F6F6;
|
--color-banquise-gray: #F6F6F6;
|
||||||
|
|
||||||
|
/* Couleurs Discord officielles */
|
||||||
|
--color-discord-blurple: #5865F2;
|
||||||
|
--color-discord-dark: #4752C4;
|
||||||
|
--color-discord-old-blurple: #7289DA;
|
||||||
|
--color-discord-old-dark: #5B6EAE;
|
||||||
|
|
||||||
/* Transitions communes */
|
/* Transitions communes */
|
||||||
--transition-default: all 0.3s ease-in-out;
|
--transition-default: all 0.3s ease-in-out;
|
||||||
--transition-fast: all 0.2s ease-in-out;
|
--transition-fast: all 0.2s ease-in-out;
|
||||||
@ -35,6 +41,7 @@
|
|||||||
.text-banquise-blue-light { color: var(--color-banquise-blue-light-hex); }
|
.text-banquise-blue-light { color: var(--color-banquise-blue-light-hex); }
|
||||||
.text-banquise-blue-lightest { color: var(--color-banquise-blue-lightest-hex); }
|
.text-banquise-blue-lightest { color: var(--color-banquise-blue-lightest-hex); }
|
||||||
.text-banquise-gray { color: var(--color-banquise-gray); }
|
.text-banquise-gray { color: var(--color-banquise-gray); }
|
||||||
|
.text-discord { color: var(--color-discord-blurple); }
|
||||||
|
|
||||||
/* Background colors */
|
/* Background colors */
|
||||||
.bg-banquise-blue { background-color: var(--color-banquise-blue-hex); }
|
.bg-banquise-blue { background-color: var(--color-banquise-blue-hex); }
|
||||||
@ -42,6 +49,7 @@
|
|||||||
.bg-banquise-blue-light { background-color: var(--color-banquise-blue-light-hex); }
|
.bg-banquise-blue-light { background-color: var(--color-banquise-blue-light-hex); }
|
||||||
.bg-banquise-blue-lightest { background-color: var(--color-banquise-blue-lightest-hex); }
|
.bg-banquise-blue-lightest { background-color: var(--color-banquise-blue-lightest-hex); }
|
||||||
.bg-banquise-gray { background-color: var(--color-banquise-gray); }
|
.bg-banquise-gray { background-color: var(--color-banquise-gray); }
|
||||||
|
.bg-discord { background-color: var(--color-discord-blurple); }
|
||||||
|
|
||||||
/* Opacity helpers using rgba() */
|
/* Opacity helpers using rgba() */
|
||||||
.bg-banquise-blue-5 { background-color: rgba(var(--color-banquise-blue), 0.05); }
|
.bg-banquise-blue-5 { background-color: rgba(var(--color-banquise-blue), 0.05); }
|
||||||
|
@ -20,7 +20,7 @@ const sizeClasses = {
|
|||||||
|
|
||||||
const variantClasses = {
|
const variantClasses = {
|
||||||
primary: 'bg-gradient-to-r from-blue-600 to-blue-500 text-white shadow-lg hover:shadow-xl hover:from-blue-700 hover:to-blue-600 border-2 border-blue-600/20',
|
primary: 'bg-gradient-to-r from-blue-600 to-blue-500 text-white shadow-lg hover:shadow-xl hover:from-blue-700 hover:to-blue-600 border-2 border-blue-600/20',
|
||||||
discord: 'bg-gradient-to-r from-indigo-600 to-purple-600 text-white shadow-lg hover:shadow-xl hover:from-indigo-700 hover:to-purple-700 border-2 border-indigo-600/20',
|
discord: 'bg-gradient-to-r from-[#5865F2] to-[#7289DA] text-white shadow-lg hover:shadow-xl hover:from-[#4752C4] hover:to-[#5B6EAE] border-2 border-[#5865F2]/20',
|
||||||
auth: 'bg-gradient-to-r from-blue-500 to-blue-400 text-white shadow-lg hover:shadow-xl hover:from-blue-600 hover:to-blue-500 border-2 border-blue-500/20',
|
auth: 'bg-gradient-to-r from-blue-500 to-blue-400 text-white shadow-lg hover:shadow-xl hover:from-blue-600 hover:to-blue-500 border-2 border-blue-500/20',
|
||||||
secondary: 'bg-white text-blue-700 border-2 border-blue-600 shadow-md hover:shadow-lg hover:bg-blue-50',
|
secondary: 'bg-white text-blue-700 border-2 border-blue-600 shadow-md hover:shadow-lg hover:bg-blue-50',
|
||||||
outline: 'bg-transparent text-gray-700 border-2 border-gray-300 hover:bg-gray-50 hover:border-gray-400',
|
outline: 'bg-transparent text-gray-700 border-2 border-gray-300 hover:bg-gray-50 hover:border-gray-400',
|
||||||
|
@ -3,13 +3,7 @@ import { URLS, SITE_CONFIG } from '@/lib/config/constants';
|
|||||||
import { BookOpen, GitBranch, Gamepad2, Cloud, Rocket, Heart } from 'lucide-react';
|
import { BookOpen, GitBranch, Gamepad2, Cloud, Rocket, Heart } from 'lucide-react';
|
||||||
import { useTranslation } from '@/lib/hooks/useTranslation';
|
import { useTranslation } from '@/lib/hooks/useTranslation';
|
||||||
import { cn, commonClasses } from '@/lib/utils';
|
import { cn, commonClasses } from '@/lib/utils';
|
||||||
|
import { DiscordIcon } from '@/components/ui/DiscordLogo';
|
||||||
// Factorisation des icônes SVG
|
|
||||||
const DiscordIcon = () => (
|
|
||||||
<svg className="w-6 h-6" 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"/>
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
|
|
||||||
const EmailIcon = () => (
|
const EmailIcon = () => (
|
||||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
import Link from 'next/link';
|
||||||
import { Button } from '@/components/common/Button';
|
import { Button } from '@/components/common/Button';
|
||||||
import { Logo } from './navbar/Logo';
|
import { Logo } from './navbar/Logo';
|
||||||
import { URLS } from '@/lib/config/constants';
|
import { X, Menu, Globe, Home, Info, Package, Phone, User } from 'lucide-react';
|
||||||
import { useTranslation } from '@/lib/hooks/useTranslation';
|
import { useTranslation } from '@/lib/hooks/useTranslation';
|
||||||
import { cn, createNavClickHandler, commonClasses } from '@/lib/utils';
|
import { URLS } from '@/lib/config/constants';
|
||||||
|
import { cn, commonClasses, createNavClickHandler } from '@/lib/utils';
|
||||||
|
import { DiscordLogo } from '@/components/ui/DiscordLogo';
|
||||||
import type { Translation } from '@/types/i18n';
|
import type { Translation } from '@/types/i18n';
|
||||||
|
|
||||||
interface MobileMenuProps {
|
interface MobileMenuProps {
|
||||||
@ -125,9 +128,7 @@ export const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose, transla
|
|||||||
</svg>
|
</svg>
|
||||||
),
|
),
|
||||||
discord: (
|
discord: (
|
||||||
<svg className="w-5 h-5 text-[#5865F2]" fill="currentColor" viewBox="0 0 24 24">
|
<DiscordLogo size="sm" className="text-[#5865F2]" />
|
||||||
<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"/>
|
|
||||||
</svg>
|
|
||||||
),
|
),
|
||||||
user: (
|
user: (
|
||||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
@ -1,72 +1,278 @@
|
|||||||
import React from 'react';
|
import React from 'react';import React from 'react';import React from 'react';import React from 'react';
|
||||||
import { Button } from '../../common/Button';
|
|
||||||
import { URLS } from '@/lib/config/constants';
|
import { DiscordLogo } from '@/components/ui/DiscordLogo';
|
||||||
|
|
||||||
|
import { URLS } from '@/lib/config/constants';import { Button } from '../../common/Button';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Fonction utilitaire simple pour combiner les classesimport { URLS } from '@/lib/config/constants';import { Button } from '../../common/Button';import { Button } from '../../common/ >
|
||||||
|
|
||||||
// Fonction utilitaire simple pour combiner les classes
|
|
||||||
const mergeClasses = (...classes: (string | undefined | null | false)[]): string => {
|
const mergeClasses = (...classes: (string | undefined | null | false)[]): string => {
|
||||||
return classes.filter(Boolean).join(' ');
|
|
||||||
|
return classes.filter(Boolean).join(' ');import { DiscordLogo } from '@/components/ui/DiscordLogo';
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
import { URLS } from '@/lib/config/constants'; <DiscordLogo size="sm" className="text-white" />
|
||||||
|
|
||||||
interface ActionButtonsProps {
|
interface ActionButtonsProps {
|
||||||
scrolled?: boolean;
|
|
||||||
|
scrolled?: boolean;// Fonction utilitaire simple pour combiner les classes
|
||||||
|
|
||||||
languageSwitcher: React.ReactElement;
|
languageSwitcher: React.ReactElement;
|
||||||
className?: string;
|
|
||||||
|
className?: string;const mergeClasses = (...classes: (string | undefined | null | false)[]): string => {import { DiscordLogo } from '@/components/ui/DiscordLogo'; </button>n';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ActionButtons: React.FC<ActionButtonsProps> = ({
|
return classes.filter(Boolean).join(' ');
|
||||||
scrolled = false,
|
|
||||||
languageSwitcher,
|
export const ActionButtons: React.FC<ActionButtonsProps> = ({
|
||||||
className
|
|
||||||
}) => {
|
scrolled = false, };import { URLS } from '@/lib/config/constants';
|
||||||
return (
|
|
||||||
<div className={mergeClasses(
|
languageSwitcher,
|
||||||
'hidden md:flex items-center space-x-3',
|
|
||||||
className
|
className
|
||||||
)}>
|
|
||||||
{/* Sélecteur de langue moderne */}
|
}) => {
|
||||||
<div className="relative">
|
|
||||||
{languageSwitcher}
|
return (interface ActionButtonsProps {// Fonction utilitaire simple pour combiner les classesimport { DiscordLogo } from '@/components/ui/DiscordLogo';
|
||||||
</div>
|
|
||||||
|
<div className={mergeClasses(
|
||||||
{/* Bouton Discord moderne */}
|
|
||||||
<button
|
'hidden md:flex items-center space-x-3', scrolled?: boolean;
|
||||||
onClick={() => window.open(URLS.social.discord, '_blank')}
|
|
||||||
className={mergeClasses(
|
className
|
||||||
// Base styles
|
|
||||||
'inline-flex items-center px-4 py-2.5 text-sm font-medium',
|
)}> languageSwitcher: React.ReactElement;const mergeClasses = (...classes: (string | undefined | null | false)[]): string => {
|
||||||
'bg-indigo-600 text-white rounded-xl border border-indigo-500/20',
|
|
||||||
'transition-all duration-200 ease-in-out',
|
{/* Sélecteur de langue moderne */}
|
||||||
'hover:bg-indigo-700 hover:scale-[1.02] hover:shadow-lg hover:shadow-indigo-500/25',
|
|
||||||
'focus:outline-none focus:ring-2 focus:ring-indigo-400/50',
|
<div className="relative"> className?: string;
|
||||||
'active:scale-[0.98]',
|
|
||||||
|
{languageSwitcher}
|
||||||
// Mobile adaptation
|
|
||||||
'hidden lg:flex'
|
</div>} return classes.filter(Boolean).join(' ');// Fonction utilitaire simple pour combiner les classes
|
||||||
)}
|
|
||||||
aria-label="Rejoindre notre Discord"
|
|
||||||
>
|
|
||||||
<svg className="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
{/* Bouton Discord moderne */}
|
||||||
<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"/>
|
|
||||||
</svg>
|
|
||||||
Discord
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Version icon seulement pour les écrans moyens */}
|
|
||||||
<button
|
<button
|
||||||
onClick={() => window.open(URLS.social.discord, '_blank')}
|
|
||||||
|
onClick={() => window.open(URLS.social.discord, '_blank')}export const ActionButtons: React.FC<ActionButtonsProps> = ({ };const mergeClasses = (...classes: (string | undefined | null | false)[]): string => {
|
||||||
|
|
||||||
className={mergeClasses(
|
className={mergeClasses(
|
||||||
'flex lg:hidden items-center justify-center w-10 h-10',
|
|
||||||
'bg-indigo-600 text-white rounded-xl border border-indigo-500/20',
|
// Base styles scrolled = false,
|
||||||
|
|
||||||
|
'inline-flex items-center px-4 py-2.5 text-sm font-medium',
|
||||||
|
|
||||||
|
'bg-[#5865F2] text-white rounded-xl border border-[#5865F2]/20', languageSwitcher, return classes.filter(Boolean).join(' ');
|
||||||
|
|
||||||
'transition-all duration-200 ease-in-out',
|
'transition-all duration-200 ease-in-out',
|
||||||
'hover:bg-indigo-700 hover:scale-[1.02] hover:shadow-lg hover:shadow-indigo-500/25',
|
|
||||||
'focus:outline-none focus:ring-2 focus:ring-indigo-400/50',
|
'hover:bg-[#4752C4] hover:scale-[1.02] hover:shadow-lg hover:shadow-[#5865F2]/25', className
|
||||||
'active:scale-[0.98]'
|
|
||||||
|
'focus:outline-none focus:ring-2 focus:ring-[#5865F2]/50',
|
||||||
|
|
||||||
|
'active:scale-[0.98]',}) => {interface ActionButtonsProps {};
|
||||||
|
|
||||||
|
// Mobile adaptation
|
||||||
|
|
||||||
|
'hidden lg:flex' return (
|
||||||
|
|
||||||
)}
|
)}
|
||||||
aria-label="Rejoindre Discord"
|
|
||||||
|
aria-label="Rejoindre notre Discord" <div className={mergeClasses( scrolled?: boolean;
|
||||||
|
|
||||||
>
|
>
|
||||||
<svg className="w-5 h-5" 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"/>
|
<DiscordLogo size="sm" className="text-white mr-2" /> 'hidden md:flex items-center space-x-3',
|
||||||
</svg>
|
|
||||||
|
Discord
|
||||||
|
|
||||||
|
</button> className languageSwitcher: React.ReactElement;interface ActionButtonsProps {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{/* Version icon seulement pour les écrans moyens */} )}>
|
||||||
|
|
||||||
|
<button
|
||||||
|
|
||||||
|
onClick={() => window.open(URLS.social.discord, '_blank')} {/* Sélecteur de langue moderne */} className?: string; scrolled?: boolean;
|
||||||
|
|
||||||
|
className={mergeClasses(
|
||||||
|
|
||||||
|
'flex lg:hidden items-center justify-center w-10 h-10', <div className="relative">
|
||||||
|
|
||||||
|
'bg-[#5865F2] text-white rounded-xl border border-[#5865F2]/20',
|
||||||
|
|
||||||
|
'transition-all duration-200 ease-in-out', {languageSwitcher}} languageSwitcher: React.ReactElement;
|
||||||
|
|
||||||
|
'hover:bg-[#4752C4] hover:scale-[1.02] hover:shadow-lg hover:shadow-[#5865F2]/25',
|
||||||
|
|
||||||
|
'focus:outline-none focus:ring-2 focus:ring-[#5865F2]/50', </div>
|
||||||
|
|
||||||
|
'active:scale-[0.98]'
|
||||||
|
|
||||||
|
)} className?: string;
|
||||||
|
|
||||||
|
aria-label="Rejoindre Discord"
|
||||||
|
|
||||||
|
> {/* Bouton Discord moderne */}
|
||||||
|
|
||||||
|
<DiscordLogo size="sm" className="text-white" />
|
||||||
|
|
||||||
|
</button> <buttonexport const ActionButtons: React.FC<ActionButtonsProps> = ({ }
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
); onClick={() => window.open(URLS.social.discord, '_blank')}
|
||||||
|
|
||||||
|
};
|
||||||
|
className={mergeClasses( scrolled = false,
|
||||||
|
|
||||||
|
// Base styles
|
||||||
|
|
||||||
|
'inline-flex items-center px-4 py-2.5 text-sm font-medium', languageSwitcher, export const ActionButtons: React.FC<ActionButtonsProps> = ({
|
||||||
|
|
||||||
|
'bg-[#5865F2] text-white rounded-xl border border-[#5865F2]/20',
|
||||||
|
|
||||||
|
'transition-all duration-200 ease-in-out', className scrolled = false,
|
||||||
|
|
||||||
|
'hover:bg-[#4752C4] hover:scale-[1.02] hover:shadow-lg hover:shadow-[#5865F2]/25',
|
||||||
|
|
||||||
|
'focus:outline-none focus:ring-2 focus:ring-[#5865F2]/50',}) => { languageSwitcher,
|
||||||
|
|
||||||
|
'active:scale-[0.98]',
|
||||||
|
|
||||||
|
return ( className
|
||||||
|
|
||||||
|
// Mobile adaptation
|
||||||
|
|
||||||
|
'hidden lg:flex' <div className={mergeClasses(}) => {
|
||||||
|
|
||||||
|
)}
|
||||||
|
|
||||||
|
aria-label="Rejoindre notre Discord" 'hidden md:flex items-center space-x-3', return (
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
<DiscordLogo size="sm" className="text-white mr-2" /> className <div className={mergeClasses(
|
||||||
|
|
||||||
|
Discord
|
||||||
|
|
||||||
|
</button> )}> 'hidden md:flex items-center space-x-3',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{/* Version icon seulement pour les écrans moyens */} {/* Sélecteur de langue moderne */} className
|
||||||
|
|
||||||
|
<button
|
||||||
|
|
||||||
|
onClick={() => window.open(URLS.social.discord, '_blank')} <div className="relative"> )}>
|
||||||
|
|
||||||
|
className={mergeClasses(
|
||||||
|
|
||||||
|
'flex lg:hidden items-center justify-center w-10 h-10', {languageSwitcher} {/* Sélecteur de langue moderne */}
|
||||||
|
|
||||||
|
'bg-[#5865F2] text-white rounded-xl border border-[#5865F2]/20',
|
||||||
|
|
||||||
|
'transition-all duration-200 ease-in-out', </div> <div className="relative">
|
||||||
|
|
||||||
|
'hover:bg-[#4752C4] hover:scale-[1.02] hover:shadow-lg hover:shadow-[#5865F2]/25',
|
||||||
|
|
||||||
|
'focus:outline-none focus:ring-2 focus:ring-[#5865F2]/50', {languageSwitcher}
|
||||||
|
|
||||||
|
'active:scale-[0.98]'
|
||||||
|
|
||||||
|
)} {/* Bouton Discord moderne */} </div>
|
||||||
|
|
||||||
|
aria-label="Rejoindre Discord"
|
||||||
|
|
||||||
|
> <button
|
||||||
|
|
||||||
|
<DiscordLogo size="sm" className="text-white" />
|
||||||
|
|
||||||
|
</button> onClick={() => window.open(URLS.social.discord, '_blank')} {/* Bouton Discord moderne */}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
); className={mergeClasses( <button
|
||||||
|
|
||||||
|
};
|
||||||
|
// Base styles onClick={() => window.open(URLS.social.discord, '_blank')}
|
||||||
|
|
||||||
|
'inline-flex items-center px-4 py-2.5 text-sm font-medium', className={mergeClasses(
|
||||||
|
|
||||||
|
'bg-[#5865F2] text-white rounded-xl border border-[#5865F2]/20', // Base styles
|
||||||
|
|
||||||
|
'transition-all duration-200 ease-in-out', 'inline-flex items-center px-4 py-2.5 text-sm font-medium',
|
||||||
|
|
||||||
|
'hover:bg-[#4752C4] hover:scale-[1.02] hover:shadow-lg hover:shadow-[#5865F2]/25', 'bg-[#5865F2] text-white rounded-xl border border-[#5865F2]/20',
|
||||||
|
|
||||||
|
'focus:outline-none focus:ring-2 focus:ring-[#5865F2]/50', 'transition-all duration-200 ease-in-out',
|
||||||
|
|
||||||
|
'active:scale-[0.98]', 'hover:bg-[#4752C4] hover:scale-[1.02] hover:shadow-lg hover:shadow-[#5865F2]/25',
|
||||||
|
|
||||||
|
'focus:outline-none focus:ring-2 focus:ring-[#5865F2]/50',
|
||||||
|
|
||||||
|
// Mobile adaptation 'active:scale-[0.98]',
|
||||||
|
|
||||||
|
'hidden lg:flex'
|
||||||
|
|
||||||
|
)} // Mobile adaptation
|
||||||
|
|
||||||
|
aria-label="Rejoindre notre Discord" 'hidden lg:flex'
|
||||||
|
|
||||||
|
> )}
|
||||||
|
|
||||||
|
<DiscordLogo size="sm" className="text-white mr-2" /> aria-label="Rejoindre notre Discord"
|
||||||
|
|
||||||
|
Discord >
|
||||||
|
|
||||||
|
</button> <DiscordLogo size="sm" className="text-white mr-2" />
|
||||||
|
|
||||||
|
Discord
|
||||||
|
|
||||||
|
{/* Version icon seulement pour les écrans moyens */} </button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
|
||||||
|
onClick={() => window.open(URLS.social.discord, '_blank')} {/* Version icon seulement pour les écrans moyens */}
|
||||||
|
|
||||||
|
className={mergeClasses( <button
|
||||||
|
|
||||||
|
'flex lg:hidden items-center justify-center w-10 h-10', onClick={() => window.open(URLS.social.discord, '_blank')}
|
||||||
|
|
||||||
|
'bg-[#5865F2] text-white rounded-xl border border-[#5865F2]/20', className={mergeClasses(
|
||||||
|
|
||||||
|
'transition-all duration-200 ease-in-out', 'flex lg:hidden items-center justify-center w-10 h-10',
|
||||||
|
|
||||||
|
'hover:bg-[#4752C4] hover:scale-[1.02] hover:shadow-lg hover:shadow-[#5865F2]/25', 'bg-[#5865F2] text-white rounded-xl border border-[#5865F2]/20',
|
||||||
|
|
||||||
|
'focus:outline-none focus:ring-2 focus:ring-[#5865F2]/50', 'transition-all duration-200 ease-in-out',
|
||||||
|
|
||||||
|
'active:scale-[0.98]' 'hover:bg-[#4752C4] hover:scale-[1.02] hover:shadow-lg hover:shadow-[#5865F2]/25',
|
||||||
|
|
||||||
|
)} 'focus:outline-none focus:ring-2 focus:ring-[#5865F2]/50',
|
||||||
|
|
||||||
|
aria-label="Rejoindre Discord" 'active:scale-[0.98]'
|
||||||
|
|
||||||
|
> )}
|
||||||
|
|
||||||
|
<DiscordLogo size="sm" className="text-white" /> aria-label="Rejoindre Discord"
|
||||||
|
|
||||||
|
</button> >
|
||||||
|
|
||||||
|
</div> <svg className="w-5 h-5" 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"/>
|
||||||
|
|
||||||
|
}; </svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
47
banquise-website/components/ui/DiscordButton.tsx
Normal file
47
banquise-website/components/ui/DiscordButton.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Button } from '@/components/common/Button';
|
||||||
|
import { DiscordLogo } from './DiscordLogo';
|
||||||
|
import { URLS } from '@/lib/config/constants';
|
||||||
|
|
||||||
|
interface DiscordButtonProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
href?: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
size?: 'sm' | 'md' | 'lg';
|
||||||
|
className?: string;
|
||||||
|
showIcon?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DiscordButton: React.FC<DiscordButtonProps> = ({
|
||||||
|
children,
|
||||||
|
href = URLS.social.discord,
|
||||||
|
onClick,
|
||||||
|
size = 'md',
|
||||||
|
className = '',
|
||||||
|
showIcon = true
|
||||||
|
}) => {
|
||||||
|
const content = (
|
||||||
|
<>
|
||||||
|
{showIcon && <DiscordLogo size={size === 'sm' ? 'sm' : 'md'} className="text-white mr-2" />}
|
||||||
|
{children}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (href) {
|
||||||
|
return (
|
||||||
|
<a href={href} target="_blank" rel="noopener noreferrer">
|
||||||
|
<Button variant="discord" size={size} className={className}>
|
||||||
|
{content}
|
||||||
|
</Button>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button variant="discord" size={size} onClick={onClick} className={className}>
|
||||||
|
{content}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DiscordButton;
|
62
banquise-website/components/ui/DiscordLogo.tsx
Normal file
62
banquise-website/components/ui/DiscordLogo.tsx
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
interface DiscordLogoProps {
|
||||||
|
size?: 'sm' | 'md' | 'lg' | 'xl';
|
||||||
|
variant?: 'svg' | 'png';
|
||||||
|
className?: string;
|
||||||
|
alt?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sizeClasses = {
|
||||||
|
sm: 'w-4 h-4',
|
||||||
|
md: 'w-6 h-6',
|
||||||
|
lg: 'w-8 h-8',
|
||||||
|
xl: 'w-12 h-12'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Logo Discord officiel en SVG
|
||||||
|
const DiscordSVG: React.FC<{ className?: string }> = ({ className }) => (
|
||||||
|
<svg
|
||||||
|
className={className}
|
||||||
|
viewBox="0 0 127.14 96.36"
|
||||||
|
fill="currentColor"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const DiscordLogo: React.FC<DiscordLogoProps> = ({
|
||||||
|
size = 'md',
|
||||||
|
variant = 'svg',
|
||||||
|
className = '',
|
||||||
|
alt = 'Discord'
|
||||||
|
}) => {
|
||||||
|
const baseClasses = sizeClasses[size];
|
||||||
|
const finalClassName = `${baseClasses} ${className}`;
|
||||||
|
|
||||||
|
if (variant === 'png') {
|
||||||
|
return (
|
||||||
|
<Image
|
||||||
|
src="/assets/discord-mark-blurple.png"
|
||||||
|
alt={alt}
|
||||||
|
width={size === 'sm' ? 16 : size === 'md' ? 24 : size === 'lg' ? 32 : 48}
|
||||||
|
height={size === 'sm' ? 16 : size === 'md' ? 24 : size === 'lg' ? 32 : 48}
|
||||||
|
className={finalClassName}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <DiscordSVG className={finalClassName} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Export du composant SVG pour usage direct
|
||||||
|
export const DiscordIcon = () => (
|
||||||
|
<DiscordLogo size="md" variant="svg" className="text-[#5865F2]" />
|
||||||
|
);
|
||||||
|
|
||||||
|
export default DiscordLogo;
|
@ -6,8 +6,8 @@ export const designSystem = {
|
|||||||
primaryBr: "bg-gradient-to-br from-banquise-blue to-banquise-blue-light",
|
primaryBr: "bg-gradient-to-br from-banquise-blue to-banquise-blue-light",
|
||||||
card: "bg-gradient-to-br from-banquise-blue-dark/10 to-banquise-blue-dark/5",
|
card: "bg-gradient-to-br from-banquise-blue-dark/10 to-banquise-blue-dark/5",
|
||||||
cardHover: "hover:from-banquise-blue-dark/15 hover:to-banquise-blue-dark/8",
|
cardHover: "hover:from-banquise-blue-dark/15 hover:to-banquise-blue-dark/8",
|
||||||
discord: "bg-gradient-to-r from-indigo-600 to-purple-600",
|
discord: "bg-gradient-to-r from-[#5865F2] to-[#7289DA]", // Couleurs officielles Discord
|
||||||
discordHover: "hover:from-indigo-500 hover:to-purple-500",
|
discordHover: "hover:from-[#4752C4] hover:to-[#5B6EAE]", // Couleurs Discord hover officielles
|
||||||
hero: "bg-gradient-to-br from-banquise-blue to-banquise-blue-dark",
|
hero: "bg-gradient-to-br from-banquise-blue to-banquise-blue-dark",
|
||||||
section: "bg-gradient-to-b from-white/95 to-white"
|
section: "bg-gradient-to-b from-white/95 to-white"
|
||||||
},
|
},
|
||||||
@ -18,7 +18,7 @@ export const designSystem = {
|
|||||||
effects: "hover:shadow-xl hover:-translate-y-1 hover:scale-105",
|
effects: "hover:shadow-xl hover:-translate-y-1 hover:scale-105",
|
||||||
variants: {
|
variants: {
|
||||||
primary: "text-white",
|
primary: "text-white",
|
||||||
discord: "group relative overflow-hidden text-white font-semibold rounded-xl hover:shadow-indigo-500/25",
|
discord: "group relative overflow-hidden text-white font-semibold rounded-xl hover:shadow-[#5865F2]/25", // Ombre officielle Discord
|
||||||
auth: "group relative overflow-hidden text-white font-semibold rounded-xl",
|
auth: "group relative overflow-hidden text-white font-semibold rounded-xl",
|
||||||
secondary: "bg-white/10 backdrop-blur-sm text-white border border-white/20",
|
secondary: "bg-white/10 backdrop-blur-sm text-white border border-white/20",
|
||||||
outline: "bg-transparent border-2 border-banquise-blue text-banquise-blue hover:bg-banquise-blue hover:text-white"
|
outline: "bg-transparent border-2 border-banquise-blue text-banquise-blue hover:bg-banquise-blue hover:text-white"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user