Files
Momento/architectural-grid/src/components/AuthPage.tsx
Antigravity e2672cd2c2
Some checks failed
CI / Lint, Test & Build (push) Failing after 1m19s
CI / Deploy production (on server) (push) Has been skipped
feat(notes): liens internes, onglet Réseau, living blocks et consentement IA
Rend les liens entre notes visibles et persistants (sync NoteLink au save, auto-save, graphe réseau rafraîchi), ajoute living blocks, Memory Echo, recherche globale, consentement IA explicite et consolide les prototypes design en architectural-grid.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 14:27:29 +00:00

201 lines
10 KiB
TypeScript

import React, { useState } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { Mail, Lock, User, ArrowRight, Github, Globe, Sparkles } from 'lucide-react';
interface AuthPageProps {
onAuthComplete: () => void;
onBack: () => void;
initialMode?: 'login' | 'register';
}
export const AuthPage: React.FC<AuthPageProps> = ({ onAuthComplete, onBack, initialMode = 'login' }) => {
const [mode, setMode] = useState<'login' | 'register'>(initialMode);
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
// Simulate auth
setTimeout(() => {
setIsLoading(false);
onAuthComplete();
}, 1500);
};
return (
<div className="min-h-screen bg-[#FDFCFB] dark:bg-[#0D0D0D] flex flex-col relative overflow-hidden font-sans">
{/* Background Orbs */}
<div className="absolute top-[-10%] right-[-10%] w-[50%] h-[50%] bg-accent/5 blur-[120px] rounded-full" />
<div className="absolute bottom-[-10%] left-[-10%] w-[50%] h-[50%] bg-ochre/5 blur-[120px] rounded-full" />
{/* Header */}
<header className="p-8 flex justify-between items-center relative z-10">
<button
onClick={onBack}
className="flex items-center gap-2 text-concrete hover:text-ink transition-colors group"
>
<div className="w-8 h-8 rounded-full border border-border flex items-center justify-center group-hover:border-accent transition-colors">
<Globe size={14} className="group-hover:rotate-12 transition-transform" />
</div>
<span className="text-[10px] font-bold uppercase tracking-widest">Retour</span>
</button>
<div className="flex items-center gap-2">
<div className="w-8 h-8 bg-ink text-white rounded-xl flex items-center justify-center shadow-lg">
<span className="font-serif font-bold text-xl">M</span>
</div>
<span className="font-serif text-xl font-medium tracking-tight text-ink">Momento</span>
</div>
<div className="w-24" /> {/* Spacer */}
</header>
{/* Main Content */}
<main className="flex-1 flex items-center justify-center p-6 relative z-10">
<div className="w-full max-w-md">
<AnimatePresence mode="wait">
<motion.div
key={mode}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.4, ease: [0.22, 1, 0.36, 1] }}
className="bg-white dark:bg-paper/50 border border-border p-10 rounded-[48px] shadow-2xl relative"
>
<div className="space-y-8">
<div className="text-center space-y-2">
<h1 className="text-3xl font-serif font-bold text-ink">
{mode === 'login' ? 'Bon retour parmi nous' : 'Créer votre espace'}
</h1>
<p className="text-concrete text-sm font-light">
{mode === 'login'
? 'Entrez vos identifiants pour accéder à vos notes.'
: 'Rejoignez la nouvelle ère de la prise de notes intelligente.'}
</p>
</div>
<form onSubmit={handleSubmit} className="space-y-4">
{mode === 'register' && (
<div className="space-y-1.5">
<label className="text-[10px] uppercase tracking-widest font-bold text-concrete px-4">Nom complet</label>
<div className="relative group">
<div className="absolute left-4 top-1/2 -translate-y-1/2 text-concrete group-focus-within:text-accent transition-colors">
<User size={16} />
</div>
<input
type="text"
placeholder="Jean Dupont"
className="w-full bg-slate-50 dark:bg-white/5 border border-border rounded-2xl py-4 pl-12 pr-4 text-sm outline-none focus:border-accent focus:ring-4 ring-accent/5 transition-all"
/>
</div>
</div>
)}
<div className="space-y-1.5">
<label className="text-[10px] uppercase tracking-widest font-bold text-concrete px-4">Email</label>
<div className="relative group">
<div className="absolute left-4 top-1/2 -translate-y-1/2 text-concrete group-focus-within:text-accent transition-colors">
<Mail size={16} />
</div>
<input
type="email"
placeholder="jean@exemple.com"
className="w-full bg-slate-50 dark:bg-white/5 border border-border rounded-2xl py-4 pl-12 pr-4 text-sm outline-none focus:border-accent focus:ring-4 ring-accent/5 transition-all"
required
/>
</div>
</div>
<div className="space-y-1.5">
<div className="flex justify-between items-center px-4">
<label className="text-[10px] uppercase tracking-widest font-bold text-concrete">Mot de passe</label>
{mode === 'login' && (
<button type="button" className="text-[10px] text-accent font-bold uppercase tracking-widest hover:underline">Oublié ?</button>
)}
</div>
<div className="relative group">
<div className="absolute left-4 top-1/2 -translate-y-1/2 text-concrete group-focus-within:text-accent transition-colors">
<Lock size={16} />
</div>
<input
type="password"
placeholder="••••••••"
className="w-full bg-slate-50 dark:bg-white/5 border border-border rounded-2xl py-4 pl-12 pr-4 text-sm outline-none focus:border-accent focus:ring-4 ring-accent/5 transition-all"
required
/>
</div>
</div>
<button
type="submit"
disabled={isLoading}
className="w-full bg-ink text-white py-4 rounded-2xl font-bold uppercase tracking-[0.2em] text-[10px] flex items-center justify-center gap-3 transition-all hover:shadow-xl hover:shadow-ink/20 active:scale-95 disabled:opacity-50 mt-4 overflow-hidden relative"
>
{isLoading ? (
<motion.div
animate={{ rotate: 360 }}
transition={{ repeat: Infinity, duration: 1, ease: 'linear' }}
>
<Sparkles size={16} />
</motion.div>
) : (
<>
{mode === 'login' ? 'Se connecter' : 'Créer mon compte'}
<ArrowRight size={14} />
</>
)}
</button>
</form>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-border" />
</div>
<div className="relative flex justify-center text-[10px] uppercase tracking-widest font-bold">
<span className="bg-white dark:bg-dark-paper px-4 text-concrete">Ou continuer avec</span>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<button className="flex items-center justify-center gap-3 py-3 border border-border rounded-xl hover:bg-slate-50 dark:hover:bg-white/5 transition-all group">
<div className="w-4 h-4 bg-white rounded-full flex items-center justify-center">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" fill="#4285F4"/>
<path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/>
<path d="M5.84 14.1c-.22-.66-.35-1.36-.35-2.1s.13-1.44.35-2.1V7.06H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.94l3.66-2.84z" fill="#FBBC05"/>
<path d="M12 5.38c1.62 0 3.06.56 4.21 1.66l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.06l3.66 2.84c.87-2.6 3.3-4.52 6.16-4.52z" fill="#EA4335"/>
</svg>
</div>
<span className="text-[10px] font-bold uppercase tracking-widest text-ink">Google</span>
</button>
<button className="flex items-center justify-center gap-3 py-3 border border-border rounded-xl hover:bg-slate-50 dark:hover:bg-white/5 transition-all group">
<Github size={16} className="text-ink" />
<span className="text-[10px] font-bold uppercase tracking-widest text-ink">GitHub</span>
</button>
</div>
<div className="text-center pt-4">
<p className="text-xs text-concrete">
{mode === 'login' ? "Vous n'avez pas de compte ?" : "Vous avez déjà un compte ?"}
{' '}
<button
onClick={() => setMode(mode === 'login' ? 'register' : 'login')}
className="text-accent font-bold hover:underline"
>
{mode === 'login' ? "S'inscrire" : "Se connecter"}
</button>
</p>
</div>
</div>
</motion.div>
</AnimatePresence>
<p className="text-center mt-8 text-[9px] text-concrete font-bold uppercase tracking-[0.3em] opacity-40">
© 2024 Momento Labs Privacy Terms
</p>
</div>
</main>
</div>
);
};