From 028487d708c3e2969e2e077ee157cceaf68c722d Mon Sep 17 00:00:00 2001 From: Leon Morival Date: Sun, 12 Apr 2026 11:55:43 +0200 Subject: [PATCH] feat: components --- src/app/login/page.tsx | 63 +++++++++---------- src/app/page.tsx | 103 +++++++++++++++++-------------- src/app/register/page.tsx | 97 ++++++++++++++--------------- src/components/common/Button.tsx | 29 +++++++++ src/components/common/Card.tsx | 26 ++++++++ src/components/common/Input.tsx | 35 +++++++++++ src/types/auth.ts | 2 +- 7 files changed, 226 insertions(+), 129 deletions(-) create mode 100644 src/components/common/Button.tsx create mode 100644 src/components/common/Card.tsx create mode 100644 src/components/common/Input.tsx diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 2925085..911ae11 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -4,6 +4,9 @@ import { useState } from 'react' import { useLogin } from '@/hooks/queries/auth' import { useRouter } from 'next/navigation' import Link from 'next/link' +import Button from '@/components/common/Button' +import Input from '@/components/common/Input' +import Card from '@/components/common/Card' export default function LoginPage() { const [email, setEmail] = useState('') @@ -21,58 +24,56 @@ export default function LoginPage() { } return ( -
+
-
-

- Connectez-vous à votre compte +
+

+ Connectez-vous

-
-
-
- + +
+ setEmail(e.target.value)} /> -
-
- setPassword(e.target.value)} />
-
- {login.isError && ( -
- {(login.error as any).message} -
- )} + {login.isError && ( +

+ {(login.error as any).message} +

+ )} -
- + + + +
+ + Pas encore de compte ? S'inscrire +
- -
- - Pas encore de compte ? S'inscrire - -
+
) diff --git a/src/app/page.tsx b/src/app/page.tsx index 9b26d43..71eda0e 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,69 +2,78 @@ import { useUser, useLogout } from '@/hooks/queries/auth' import Link from 'next/link' +import Button from '@/components/common/Button' +import Card from '@/components/common/Card' +import { useEffect, useState } from 'react' export default function Home() { + const [mounted, setMounted] = useState(false) const { data: user, isLoading } = useUser() const logout = useLogout() - if (isLoading) { + useEffect(() => { + setMounted(true) + }, []) + + if (!mounted || isLoading) { return ( -
-

Chargement...

+
+

Chargement...

) } return ( -
-
-

+
+
+

Bienvenue sur Next Starter

- {user ? ( -
-
- {user.avatar_url && ( - {user.name} - )} -

Bonjour, {user.name} !

-

{user.email}

-
- - -
- ) : ( -
-

- Connectez-vous pour accéder à toutes les fonctionnalités. -

-
- + {user ? ( +
+
+ {user.avatarUrl && ( + {user.name} + )} +

Bonjour, {user.name} !

+

{user.email}

+
+ +
-
- )} + ) : ( +
+

+ Connectez-vous pour accéder à toutes les fonctionnalités. +

+
+ + + + + + +
+
+ )} +
) diff --git a/src/app/register/page.tsx b/src/app/register/page.tsx index f53260f..d9cbe87 100644 --- a/src/app/register/page.tsx +++ b/src/app/register/page.tsx @@ -4,6 +4,9 @@ import { useState } from 'react' import { useRegister } from '@/hooks/queries/auth' import { useRouter } from 'next/navigation' import Link from 'next/link' +import Button from '@/components/common/Button' +import Input from '@/components/common/Input' +import Card from '@/components/common/Card' export default function RegisterPage() { const [formData, setFormData] = useState({ @@ -26,88 +29,82 @@ export default function RegisterPage() { } return ( -
+
-
-

+
+

Créez votre compte

-
-
-
- + +
+ setFormData({ ...formData, name: e.target.value })} /> -
-
- setFormData({ ...formData, email: e.target.value })} /> -
-
- setFormData({ ...formData, password: e.target.value })} /> -
-
- setFormData({ ...formData, password_confirmation: e.target.value })} /> + +
+ + setFormData({ ...formData, avatar: e.target.files?.[0] || null })} + /> +
-
-
- - setFormData({ ...formData, avatar: e.target.files?.[0] || null })} - /> -
+ {register.isError && ( +

+ {(register.error as any).message} +

+ )} - {register.isError && ( -
- {(register.error as any).message} -
- )} - -
- + + + +
+ + Déjà un compte ? Se connecter +
- -
- - Déjà un compte ? Se connecter - -
+
) diff --git a/src/components/common/Button.tsx b/src/components/common/Button.tsx new file mode 100644 index 0000000..7b91ae6 --- /dev/null +++ b/src/components/common/Button.tsx @@ -0,0 +1,29 @@ +import React from 'react'; + +interface ButtonProps extends React.ButtonHTMLAttributes { + variant?: 'primary' | 'secondary'; + children: React.ReactNode; +} + +export default function Button({ + variant = 'primary', + children, + className = '', + ...props +}: ButtonProps) { + const baseClasses = "px-4 py-2 transition-all cursor-pointer rounded-md text-sm font-medium disabled:opacity-50 disabled:cursor-not-allowed"; + + const variants = { + primary: "bg-black text-white hover:bg-black/90 dark:bg-white dark:text-black dark:hover:bg-white/90 shadow-sm", + secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200 dark:bg-neutral-800 dark:text-white dark:hover:bg-neutral-700 border border-transparent shadow-sm" + }; + + return ( + + ); +} diff --git a/src/components/common/Card.tsx b/src/components/common/Card.tsx new file mode 100644 index 0000000..043d8ea --- /dev/null +++ b/src/components/common/Card.tsx @@ -0,0 +1,26 @@ +import React from 'react'; + +interface CardProps { + children: React.ReactNode; + className?: string; + title?: string; +} + +export default function Card({ + children, + className = '', + title +}: CardProps) { + return ( +
+ {title && ( +

+ {title} +

+ )} +
+ {children} +
+
+ ); +} diff --git a/src/components/common/Input.tsx b/src/components/common/Input.tsx new file mode 100644 index 0000000..15c6622 --- /dev/null +++ b/src/components/common/Input.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +interface InputProps extends React.InputHTMLAttributes { + label?: string; + error?: string; +} + +export default function Input({ + label, + error, + className = '', + ...props +}: InputProps) { + const baseClasses = "block w-full px-4 py-2 text-sm border rounded-md transition-colors duration-200 outline-none focus:ring-2 focus:ring-black/5 dark:focus:ring-white/10"; + const stateClasses = error + ? "border-red-500 text-red-900 placeholder-red-300" + : "border-gray-200 focus:border-black dark:border-neutral-800 dark:focus:border-white bg-transparent"; + + return ( +
+ {label && ( + + )} + + {error && ( +

{error}

+ )} +
+ ); +} diff --git a/src/types/auth.ts b/src/types/auth.ts index db1383f..3db16c9 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -2,7 +2,7 @@ export interface User { id: string; name: string; email: string; - avatar_url: string | null; + avatarUrl: string | null; created_at: string; updated_at: string; }