diff --git a/.gitignore b/.gitignore index a67dd8de..10ab35d1 100644 --- a/.gitignore +++ b/.gitignore @@ -175,3 +175,5 @@ output.css **/src/SmartContract/dump.rdb make/scripts/certs/certs .venv +*.ai +docs/welcomPage.jpg diff --git a/srcs/nginx/src/App.tsx b/srcs/nginx/src/App.tsx index cadd17cc..3cd51a76 100644 --- a/srcs/nginx/src/App.tsx +++ b/srcs/nginx/src/App.tsx @@ -3,11 +3,13 @@ import { ProfilePage } from './pages/ProfilePage'; import { LoginPage } from './pages/LoginRegisterPage'; import { useAuth } from './providers/AuthProvider'; import { AnimationPage } from './pages/AnimationPage'; +import { WelcomePage } from './pages/WelcomePage'; const GuestRoute = ({ children }: { children: React.ReactNode }) => { const { user, isLoggedIn } = useAuth(); if (user && isLoggedIn) { - return ; + return ; + // return ; } return children; }; @@ -24,22 +26,16 @@ export const App = () => {
}> - - - - } - /> - } /> + {/* } - /> + /> */} }> }> diff --git a/srcs/nginx/src/components/molecules/CircleButton.tsx b/srcs/nginx/src/components/molecules/CircleButton.tsx new file mode 100644 index 00000000..90ed8335 --- /dev/null +++ b/srcs/nginx/src/components/molecules/CircleButton.tsx @@ -0,0 +1,28 @@ +import { motion } from 'framer-motion'; + +interface CircleButtonProps { + children?: React.ReactNode; +} + +const dropdownStyle = 'shadow-[0_10px_10px_1px_rgba(205,205,205,0.4)] '; + +export const CircleButton = ({ children }: CircleButtonProps) => ( + +

{children}

+
+); diff --git a/srcs/nginx/src/components/molecules/Halo.tsx b/srcs/nginx/src/components/molecules/Halo.tsx new file mode 100644 index 00000000..73effe05 --- /dev/null +++ b/srcs/nginx/src/components/molecules/Halo.tsx @@ -0,0 +1,40 @@ +import { useState } from 'react'; +import { RegisterForm } from '../organisms/RegisterForm'; +import { LoginForm } from '../organisms/LoginForm'; +import Circle from '../atoms/Circle'; +import { useTranslation } from 'react-i18next'; + +interface HaloProps { + isRegister: boolean; + className?: string; + size?: number; + onToggleForm: () => void; // Add this line +} +const Halo = ({ className = '', size = 80, isRegister, onToggleForm }: HaloProps) => { + const [isHovered, setIsHovered] = useState(false); + const { t } = useTranslation(); + const title = isRegister ? t('auth.signup') : t('auth.login'); + + return ( +
setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > + + {/* PLAY text */} + PLAY + + {/* Forms */} +
+ {isRegister ? ( + + ) : ( + + )} +
+
+
+ ); +}; +export default Halo; diff --git a/srcs/nginx/src/components/organisms/LoginForm.tsx b/srcs/nginx/src/components/organisms/LoginForm.tsx index 3662d951..ed730ecc 100644 --- a/srcs/nginx/src/components/organisms/LoginForm.tsx +++ b/srcs/nginx/src/components/organisms/LoginForm.tsx @@ -79,7 +79,7 @@ async function loginAction(prevState: LoginState | null, formData: FormData) { } } -export const LoginForm = () => { +export const LoginForm = ({ onToggleForm }: { onToggleForm?: () => void }) => { const { t } = useTranslation(); const [state, formAction, isPending] = useActionState(loginAction, null); const navigate = useNavigate(); @@ -88,10 +88,12 @@ export const LoginForm = () => { if (state?.success && state.fields?.username) { const username = state.fields.username; login({ username: username, avatarUrl: null }); - navigate(`/profile/${username}`, { replace: true }); + // navigate(`/profile/${username}`, { replace: true }); + navigate(`/welcome`, { replace: true }); } if (user?.username) { - navigate(`/profile/${user.username}`, { replace: true }); + // navigate(`/profile/${username}`, { replace: true }); + navigate(`/welcome`, { replace: true }); } }, [state?.success, state?.fields?.username, user, navigate, login]); return ( @@ -119,11 +121,9 @@ export const LoginForm = () => {
{t('auth.noAccount')}{' '} - - - {t('auth.signup')} - - +
); diff --git a/srcs/nginx/src/components/organisms/RegisterForm.tsx b/srcs/nginx/src/components/organisms/RegisterForm.tsx index b3ce5f1b..b9d9a2f8 100644 --- a/srcs/nginx/src/components/organisms/RegisterForm.tsx +++ b/srcs/nginx/src/components/organisms/RegisterForm.tsx @@ -112,8 +112,7 @@ async function signupAction(prevState: SignupState | null, formData: FormData) { return nextState; } } - -export const RegisterForm = () => { +export const RegisterForm = ({ onToggleForm }: { onToggleForm?: () => void }) => { const { t } = useTranslation(); const [state, formAction, isPending] = useActionState(signupAction, null); const navigate = useNavigate(); @@ -121,7 +120,8 @@ export const RegisterForm = () => { useEffect(() => { if (user && isLoggedIn) { - navigate(`/profile/${user.username}`); + // navigate(`/profile/${user.username}`); + navigate(`/welcome`); } }, [user, isLoggedIn]); @@ -129,7 +129,8 @@ export const RegisterForm = () => { if (state?.success && state.fields?.username) { const username = state.fields?.username; login({ username: username, avatarUrl: null }); - navigate(`/profile/${username}`); + // navigate(`/profile/${username}`); + navigate(`/welcome`); } }, [state?.success, state?.fields?.username, navigate]); @@ -167,11 +168,9 @@ export const RegisterForm = () => {
{t('auth.hasAccount')}{' '} - - - {t('auth.login')} - - +
); diff --git a/srcs/nginx/src/hooks/AxiosInterceptor.tsx b/srcs/nginx/src/hooks/AxiosInterceptor.tsx index ccc327c2..d719261c 100644 --- a/srcs/nginx/src/hooks/AxiosInterceptor.tsx +++ b/srcs/nginx/src/hooks/AxiosInterceptor.tsx @@ -12,7 +12,7 @@ export const AxiosInterceptor = ({ children }: { children: React.ReactNode }) => (response) => response, (error) => { if (error.statusCode === HTTP_STATUS.UNAUTHORIZED) { - navigate('/login'); + navigate('/welcome'); } return Promise.reject(error); }, diff --git a/srcs/nginx/src/locales/en/common.json b/srcs/nginx/src/locales/en/common.json index e5f2d079..359b9857 100644 --- a/srcs/nginx/src/locales/en/common.json +++ b/srcs/nginx/src/locales/en/common.json @@ -66,5 +66,10 @@ "copyright": "© 2026 . All rights reserved.", "privacyPolicy": "Privacy Policy", "termsOfService": "Terms of Service" + }, + "game": { + "playWithAI": "Play with AI", + "playWithFriends": "Play with Friends", + "tournament": "Tournament" } } diff --git a/srcs/nginx/src/locales/fr/common.json b/srcs/nginx/src/locales/fr/common.json index c2f69834..94be04e3 100644 --- a/srcs/nginx/src/locales/fr/common.json +++ b/srcs/nginx/src/locales/fr/common.json @@ -66,5 +66,10 @@ "copyright": "© 2026 Tous droits réservés.", "privacyPolicy": "Politique de confidentialité", "termsOfService": "Conditions d'utilisation" + }, + "game": { + "playWithAI": "Joue avec un ROBOT (no friends?)", + "playWithFriends": "Joue avec ton copaing", + "tournament": "Defi tes potes en tournois" } } diff --git a/srcs/nginx/src/locales/tf/common.json b/srcs/nginx/src/locales/tf/common.json index ff94361f..c019d41f 100644 --- a/srcs/nginx/src/locales/tf/common.json +++ b/srcs/nginx/src/locales/tf/common.json @@ -66,5 +66,10 @@ "copyright": "© 2026 – C'est à nous.", "privacyPolicy": "La loi du milieu (on balance rien, t'es en sécurité)", "termsOfService": "Les règles du jeu (lis ça, sinon t’es un rigolo)" + }, + "game": { + "playWithAI": "No friends? Joue avec un ROBOT", + "playWithFriends": "Joue avec ton copaing", + "tournament": "Defi tes potes en tournois" } } diff --git a/srcs/nginx/src/pages/AnimationPage.tsx b/srcs/nginx/src/pages/AnimationPage.tsx index 552749dc..e1af8bbc 100644 --- a/srcs/nginx/src/pages/AnimationPage.tsx +++ b/srcs/nginx/src/pages/AnimationPage.tsx @@ -20,7 +20,7 @@ export const AnimationPage = ({ className = '' }: AnimationPageProps) => { useEffect(() => { if (animDone) { - navigate(`/login`); + navigate(`/welcome`); } }, [animDone, user]); diff --git a/srcs/nginx/src/pages/WelcomePage.tsx b/srcs/nginx/src/pages/WelcomePage.tsx new file mode 100644 index 00000000..c521afcc --- /dev/null +++ b/srcs/nginx/src/pages/WelcomePage.tsx @@ -0,0 +1,91 @@ +import { NavBar } from '../components/molecules/NavBar'; // Adjust path based on your folder structure +import Halo from '../components/molecules/Halo'; +import { Link } from 'react-router-dom'; +import Background from '../components/atoms/Background'; +import { useTranslation } from 'react-i18next'; +import { RegisterForm } from '../components/organisms/RegisterForm'; +import { LoginForm } from '../components/organisms/LoginForm'; +import { useState } from 'react'; +import Circle from '../components/atoms/Circle'; +import { CircleButton } from '../components/molecules/CircleButton'; +import { useAuth } from '../providers/AuthProvider'; + +const colors = { + start: '#00ff9f', + end: '#0088ff', +}; + +interface LoginRegisterPageProps { + isRegister: boolean; +} +export const WelcomePage = () => { + const { t } = useTranslation(); + const [isRegister, setIsRegister] = useState(false); + const { user, isLoggedIn } = useAuth(); + + const ai = t('game.playWithAI'); + const tournament = t('game.tournament'); + const friends = t('game.playWithFriends'); + return ( +
+ + + {/* Not logged in - show login/register */} + {!isLoggedIn && ( + setIsRegister(!isRegister)} + className="top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" + /> + )} + {/* Logged in - show 3 game options */} + {isLoggedIn && ( +
+
+ + {ai} + + + + {friends} + + + + {tournament} + +
+
+ )} +
+
+ ); +}; +// export const WelcomePage = () => { +// const { t } = useTranslation(); +// const [isRegister, setIsRegister] = useState(false); +// const title = isRegister ? t('auth.signup') : t('auth.login'); +// return ( +//
+// +// +// setIsRegister(!isRegister)} +// className="top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" +// /> +// +//
+// ); +// };