changed auth design

This commit is contained in:
Rajpreet0 2026-08-03 19:37:10 +02:00
parent 9ef2acb5bd
commit 96e9fe9679
11 changed files with 206 additions and 79 deletions

View file

@ -9,7 +9,6 @@
"forgotPassword": "Passwort vergessen?",
"submit": "Anmelden",
"loginWithGoogle": "Login mit Google",
"loginWithFacebook": "Login mit Facebook",
"noAccount": "Ich habe noch keinen Account",
"signUp": "Registrieren"
}

View file

@ -123,3 +123,56 @@
@apply bg-background text-foreground;
}
}
@keyframes auth-gradient-shift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
@keyframes auth-blob-float {
0%,
100% {
transform: translate(0, 0) scale(1);
}
33% {
transform: translate(4%, 6%) scale(1.08);
}
66% {
transform: translate(-3%, -4%) scale(0.96);
}
}
.auth-animated-gradient {
background: linear-gradient(
120deg,
oklch(0.97 0 0) 0%,
oklch(0.9 0.05 240) 25%,
oklch(0.93 0.07 85) 50%,
oklch(0.9 0.04 260) 75%,
oklch(0.97 0 0) 100%
);
background-size: 300% 300%;
animation: auth-gradient-shift 18s ease-in-out infinite;
}
.auth-gradient-blob {
animation: auth-blob-float 16s ease-in-out infinite;
}
.auth-gradient-blob-delay {
animation-delay: -8s;
}
@media (prefers-reduced-motion: reduce) {
.auth-animated-gradient,
.auth-gradient-blob {
animation: none;
}
}

View file

@ -16,7 +16,7 @@ const AuthButton: React.FC<AuthButtonProps> = ({ Icon, label, onClick }) => {
onClick();
}
}}
className="flex gap-2 py-2 px-3 items-center justify-center rounded-xl border-1 border-blue text-blue w-full sm:w-fit cursor-pointer hover:scale-105 transition-all"
className="flex gap-2 py-2 px-3 items-center justify-center rounded-xl border border-blue/60 bg-white/40 backdrop-blur-md shadow-sm text-blue w-full sm:w-fit cursor-pointer hover:scale-105 hover:bg-white/60 transition-all"
>
<Icon size={20} />
<p className="ml-2 mt-1">{label}</p>

View file

@ -11,6 +11,9 @@ interface AuthSidebarComponentProps {
step?: number;
totalSteps?: number;
onStepChange?: (step: number) => void;
className?: string;
/** Short label shown on mobile only, e.g. "Login", "Registrieren" */
pageLabel?: string;
}
const AuthSidebarComponent: React.FC<AuthSidebarComponentProps> = ({
@ -21,38 +24,56 @@ const AuthSidebarComponent: React.FC<AuthSidebarComponentProps> = ({
step = 1,
totalSteps = 2,
onStepChange,
className = "rounded-2xl",
pageLabel,
}) => {
return (
<Card className="bg-blue border-0 w-full h-full p-6 lg:p-8 xl:p-12 flex flex-col justify-between">
<CardHeader className="p-0 pb-4">
<CardTitle>
<Image
src={Logo}
width={150}
height={150}
alt="Logo"
className="w-auto h-auto max-w-[120px] lg:max-w-[150px]"
/>
</CardTitle>
</CardHeader>
<CardContent className="text-yellow flex flex-col gap-4 lg:gap-6 xl:gap-8 flex-1 p-0">
<h1 className="text-2xl lg:text-3xl xl:text-[40px] max-w-full font-bold mt-2 lg:mt-4 xl:mt-8">
{title}
</h1>
{description && <p className="text-sm lg:text-base">{description}</p>}
{isSteps && (
<MultiStepProzess step={step} totalSteps={totalSteps} onStepChange={onStepChange} />
<div className={`relative w-full h-auto lg:h-full overflow-hidden ${className}`}>
{/* Animated Gradient Background */}
<div className="absolute inset-0 -z-10 bg-blue auth-animated-gradient opacity-90">
<div className="absolute -top-1/3 -left-1/4 w-[80%] h-[80%] rounded-full bg-[oklch(0.6_0.1_240/_0.45)] blur-3xl auth-gradient-blob" />
<div className="absolute -bottom-1/3 -right-1/4 w-[80%] h-[80%] rounded-full bg-[oklch(0.85_0.15_85/_0.35)] blur-3xl auth-gradient-blob auth-gradient-blob-delay" />
</div>
<Card
className={`relative border border-white/15 bg-blue/60 backdrop-blur-2xl shadow-2xl w-full h-auto lg:h-full p-6 lg:p-8 xl:p-12 flex flex-col justify-center lg:justify-between ${className}`}
>
<CardHeader className="p-0 pb-4 hidden lg:grid">
<CardTitle>
<Image
src={Logo}
width={150}
height={150}
alt="Logo"
className="w-auto h-auto max-w-[120px] lg:max-w-[150px]"
/>
</CardTitle>
</CardHeader>
{/* Mobile-only: short page label (e.g. "Login") */}
{pageLabel && (
<p className="lg:hidden text-center text-2xl font-bold text-yellow">{pageLabel}</p>
)}
</CardContent>
<CardFooter className="pointer-events-auto p-0 pt-4 mt-auto">
<p className="text-yellow text-sm lg:text-base break-words">
Bei Fragen:{" "}
<a href={`mailto:${footer}`} className="hover:underline">
{footer}
</a>
</p>
</CardFooter>
</Card>
<CardContent className="hidden lg:flex text-yellow flex-col gap-4 lg:gap-6 xl:gap-8 flex-1 p-0">
<h1 className="text-2xl lg:text-3xl xl:text-[40px] max-w-full font-bold lg:mt-4 xl:mt-8">
{title}
</h1>
{description && <p className="text-sm lg:text-base">{description}</p>}
{isSteps && (
<MultiStepProzess step={step} totalSteps={totalSteps} onStepChange={onStepChange} />
)}
</CardContent>
<CardFooter className="pointer-events-auto p-0 pt-4 mt-auto hidden lg:flex">
<p className="text-yellow text-sm lg:text-base break-words">
Bei Fragen:{" "}
<a href={`mailto:${footer}`} className="hover:underline">
{footer}
</a>
</p>
</CardFooter>
</Card>
</div>
);
};

View file

@ -62,21 +62,23 @@ const CompleteProfileView = () => {
};
return (
<div className="flex min-h-screen">
<div className="flex flex-col lg:flex-row min-h-screen">
{/* Sidebar */}
<div className="hidden lg:block lg:w-[40%]">
<div className="hidden lg:block fixed left-0 top-0 h-screen w-[40%] p-2 z-10">
<div className="w-full lg:w-[40%]">
<div className="lg:fixed lg:left-0 lg:top-0 lg:h-screen w-full lg:w-[40%] lg:p-2 z-10">
<AuthSidebarComponent
title="Fast geschafft"
description="Nur noch ein paar Angaben, damit wir dir alle Funktionen anbieten können."
footer="info@kumasy.de"
pageLabel="Profil vervollständigen"
className="rounded-none rounded-b-3xl lg:rounded-2xl"
/>
</div>
</div>
{/* Formular */}
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center min-h-screen px-4">
<div className="w-full max-w-lg flex flex-col gap-4 z-20">
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center lg:min-h-screen px-4 py-8">
<div className="w-full max-w-lg flex flex-col gap-4 relative z-20">
<h1 className="text-2xl font-extrabold text-blue mb-8 mt-8">Profil vervollständigen</h1>
<form onSubmit={handleSubmit} className="space-y-5">
@ -114,7 +116,11 @@ const CompleteProfileView = () => {
error={errors.gender}
/>
<Button type="submit" disabled={loading} className="w-full mt-6">
<Button
type="submit"
disabled={loading}
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
>
{loading ? <Spinner /> : "Speichern"}
</Button>
</form>

View file

@ -206,10 +206,10 @@ const EmployeeOnboardingView = () => {
}
return (
<div className="flex min-h-screen">
<div className="flex flex-col lg:flex-row min-h-screen">
{/* Sidebar with onboarding steps */}
<div className="hidden lg:block lg:w-[40%]">
<div className="hidden lg:block fixed left-0 top-0 h-screen w-[40%] p-2 z-10">
<div className="w-full lg:w-[40%]">
<div className="lg:fixed lg:left-0 lg:top-0 lg:h-screen w-full lg:w-[40%] lg:p-2 z-10">
<AuthSidebarComponent
title="Werde Teil unseres Teams"
footer="info@kumasy.de"
@ -217,13 +217,15 @@ const EmployeeOnboardingView = () => {
step={step}
totalSteps={2}
onStepChange={setStep}
pageLabel="Onboarding"
className="rounded-none rounded-b-3xl lg:rounded-2xl"
/>
</div>
</div>
{/* Main onboarding form */}
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center min-h-screen px-4">
<div className="w-full max-w-lg flex flex-col gap-4 z-20">
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center lg:min-h-screen px-4 py-8">
<div className="w-full max-w-lg flex flex-col gap-4 relative z-20">
<h1 className="text-2xl font-extrabold text-blue mb-2 mt-8">Herzlich Willkommen!</h1>
<p className="text-gray-500 mb-6">{employeeEmail}</p>
@ -276,7 +278,10 @@ const EmployeeOnboardingView = () => {
onChange={(e) => setPasswordConfirm(e.target.value)}
error={errors.passwordConfirm}
/>
<Button className="w-full mt-6" type="submit">
<Button
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
type="submit"
>
Weiter
</Button>
</form>
@ -311,7 +316,11 @@ const EmployeeOnboardingView = () => {
onChange={(e) => setQualification(e.target.value)}
error={errors.qualification}
/>
<Button type="submit" disabled={loading} className="w-full mt-6">
<Button
type="submit"
disabled={loading}
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
>
{loading ? <Spinner /> : "Account erstellen"}
</Button>
</form>

View file

@ -51,21 +51,23 @@ const ForgotPasswordView = () => {
};
return (
<div className="flex min-h-screen">
<div className="flex flex-col lg:flex-row min-h-screen">
{/* Sidebar */}
<div className="hidden lg:block lg:w-[40%]">
<div className="hidden lg:block fixed left-0 top-0 h-screen w-[40%] p-2 z-10">
<div className="w-full lg:w-[40%]">
<div className="lg:fixed lg:left-0 lg:top-0 lg:h-screen w-full lg:w-[40%] lg:p-2 z-10">
<AuthSidebarComponent
title="Passwort zurücksetzen"
description="Keine Sorge, wir helfen Ihnen dabei, wieder Zugang zu Ihrem Konto zu erhalten."
footer="info@kumasy.de"
pageLabel="Passwort vergessen"
className="rounded-none rounded-b-3xl lg:rounded-2xl"
/>
</div>
</div>
{/* Forgot Password Formular */}
<div className="w-full lg:w-5/6 lg:ml-auto flex justify-center items-center min-h-screen px-4">
<div className="w-full max-w-lg flex flex-col gap-4 z-20">
<div className="w-full lg:w-5/6 lg:ml-auto flex justify-center items-center lg:min-h-screen px-4 py-8">
<div className="w-full max-w-lg flex flex-col gap-4 relative z-20">
<h1 className="text-2xl font-extrabold text-blue mb-8">Passwort vergessen?</h1>
<p className="text-sm text-gray-600 mb-4">
@ -85,7 +87,11 @@ const ForgotPasswordView = () => {
error={emailError}
/>
<Button type="submit" disabled={loading} className="w-full mt-6">
<Button
type="submit"
disabled={loading}
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
>
{loading ? <Spinner /> : "Link zum Zurücksetzen senden"}
</Button>
</form>

View file

@ -37,20 +37,22 @@ const LoginView = () => {
};
return (
<div className="flex min-h-screen">
<div className="flex flex-col lg:flex-row min-h-screen">
{/* Sidebar */}
<div className="hidden lg:block lg:w-[40%]">
<div className="hidden lg:block fixed left-0 top-0 h-screen w-[40%] p-2 z-10">
<div className="w-full lg:w-[40%]">
<div className="lg:fixed lg:left-0 lg:top-0 lg:h-screen w-full lg:w-[40%] lg:p-2 z-10">
<AuthSidebarComponent
title={t("sidebarTitle")}
description={t("sidebarDescription")}
footer="info@kumasy.de"
pageLabel="Login"
className="rounded-none rounded-b-3xl lg:rounded-2xl"
/>
</div>
</div>
{/* Login-Formular */}
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center min-h-screen px-4">
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center lg:min-h-screen px-4 py-8">
<div className="w-full max-w-lg flex flex-col gap-4 relative z-20">
<div className="flex justify-end">
<LocaleSwitcher />
@ -84,7 +86,7 @@ const LoginView = () => {
id="remembering"
checked={remember}
onCheckedChange={(val: boolean) => setRemember(val)}
className="shadow-none h-5 w-5 bg-white border-blue cursor-pointer"
className="shadow-none h-5 w-5 bg-white/40 backdrop-blur-md border-blue cursor-pointer"
/>
<Label htmlFor="remembering" className="cursor-pointer">
{t("rememberMe")}
@ -98,7 +100,11 @@ const LoginView = () => {
</p>
</div>
<Button type="submit" disabled={loading} className="w-full mt-6">
<Button
type="submit"
disabled={loading}
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
>
{loading ? <Spinner /> : t("submit")}
</Button>
</form>
@ -108,7 +114,6 @@ const LoginView = () => {
{/* Social Login Buttons */}
<div className="flex flex-col sm:flex-row gap-4 mt-4">
<AuthButton Icon={FaGoogle} label={t("loginWithGoogle")} onClick={loginWithGoogle} />
<AuthButton Icon={FaFacebook} label={t("loginWithFacebook")} />
</div>
<div className="flex flex-col sm:flex-row gap-2 items-center mt-16 text-sm">

View file

@ -134,10 +134,10 @@ const RegisterAdmin = () => {
};
return (
<div className="flex min-h-screen">
<div className="flex flex-col lg:flex-row min-h-screen">
{/* Sidebar with step indicator */}
<div className="hidden lg:block lg:w-[40%]">
<div className="hidden lg:block fixed left-0 top-0 h-screen w-[40%] p-2 z-10">
<div className="w-full lg:w-[40%]">
<div className="lg:fixed lg:left-0 lg:top-0 lg:h-screen w-full lg:w-[40%] lg:p-2 z-10">
<AuthSidebarComponent
title="Werde zur besten Version deiner selbst"
footer="info@kumasy.de"
@ -145,13 +145,15 @@ const RegisterAdmin = () => {
step={step}
totalSteps={3}
onStepChange={setStep}
pageLabel="Registrieren"
className="rounded-none rounded-b-3xl lg:rounded-2xl"
/>
</div>
</div>
{/* Main form */}
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center min-h-screen px-4">
<div className="w-full max-w-lg flex flex-col gap-4 z-20">
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center lg:min-h-screen px-4 py-8">
<div className="w-full max-w-lg flex flex-col gap-4 relative z-20">
<h1 className="text-2xl font-extrabold text-blue mb-8 mt-8 ">Sign up for free</h1>
{/* Step 1: Personal + login data */}
@ -202,7 +204,11 @@ const RegisterAdmin = () => {
error={errors.passwordConfirm}
/>
<Button className="w-full mt-6" type="submit" disabled={loading}>
<Button
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
type="submit"
disabled={loading}
>
{loading ? <Spinner /> : "Weiter"}
</Button>
</form>
@ -229,7 +235,11 @@ const RegisterAdmin = () => {
placeError={errors.place}
/>
<Button className="w-full mt-6" type="submit" disabled={loading}>
<Button
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
type="submit"
disabled={loading}
>
{loading ? <Spinner /> : "Weiter"}
</Button>
</form>
@ -282,7 +292,11 @@ const RegisterAdmin = () => {
error={errors.companyNumber}
/>
<Button className="w-full mt-6" type="submit" disabled={loading}>
<Button
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
type="submit"
disabled={loading}
>
{loading ? <Spinner /> : "Anmelden"}
</Button>
</form>

View file

@ -96,10 +96,10 @@ const RegisterUserView = () => {
};
return (
<div className="flex min-h-screen">
<div className="flex flex-col lg:flex-row min-h-screen">
{/* Sidebar with step indicator */}
<div className="hidden lg:block lg:w-[40%]">
<div className="hidden lg:block fixed left-0 top-0 h-screen w-[40%] p-2 z-10">
<div className="w-full lg:w-[40%]">
<div className="lg:fixed lg:left-0 lg:top-0 lg:h-screen w-full lg:w-[40%] lg:p-2 z-10">
<AuthSidebarComponent
title="Werde zur besten Version deiner selbst"
footer="info@kumasy.de"
@ -107,13 +107,15 @@ const RegisterUserView = () => {
step={step}
totalSteps={2}
onStepChange={setStep}
pageLabel="Registrieren"
className="rounded-none rounded-b-3xl lg:rounded-2xl"
/>
</div>
</div>
{/* Main registration form */}
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center min-h-screen px-4">
<div className="w-full max-w-lg flex flex-col gap-4 z-20">
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center lg:min-h-screen px-4 py-8">
<div className="w-full max-w-lg flex flex-col gap-4 relative z-20">
<h1 className="text-2xl font-extrabold text-blue mb-8 mt-8 ">Sign up for free</h1>
{/* Step 1: Basic account data */}
@ -157,7 +159,10 @@ const RegisterUserView = () => {
error={errors.passwordConfirm}
/>
<Button className="w-full mt-6" type="submit">
<Button
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
type="submit"
>
{loading ? <Spinner /> : "Weiter"}
</Button>
</form>
@ -202,7 +207,11 @@ const RegisterUserView = () => {
error={errors.gender}
/>
<Button type="submit" disabled={loading} className="w-full mt-6">
<Button
type="submit"
disabled={loading}
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
>
{loading ? <Spinner /> : "Anmelden"}
</Button>
</form>
@ -213,7 +222,6 @@ const RegisterUserView = () => {
{/* Social login options */}
<div className="flex flex-col sm:flex-row gap-4 mt-4">
<AuthButton Icon={FaGoogle} label="Login mit Google" onClick={loginWithGoogle} />
<AuthButton Icon={FaFacebook} label="Login mit Facebook" />
</div>
<div className="flex flex-col sm:flex-row gap-2 items-center mt-8 text-sm">

View file

@ -86,21 +86,23 @@ const ResetPasswordView = () => {
};
return (
<div className="flex min-h-screen">
<div className="flex flex-col lg:flex-row min-h-screen">
{/* Sidebar */}
<div className="hidden lg:block lg:w-[40%]">
<div className="hidden lg:block fixed left-0 top-0 h-screen w-[40%] p-2 z-10">
<div className="w-full lg:w-[40%]">
<div className="lg:fixed lg:left-0 lg:top-0 lg:h-screen w-full lg:w-[40%] lg:p-2 z-10">
<AuthSidebarComponent
title="Neues Passwort setzen"
description="Wählen Sie ein sicheres Passwort für Ihr Konto."
footer="info@kumasy.de"
pageLabel="Passwort zurücksetzen"
className="rounded-none rounded-b-3xl lg:rounded-2xl"
/>
</div>
</div>
{/* Reset Password Formular */}
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center min-h-screen px-4">
<div className="w-full max-w-lg flex flex-col gap-4 z-20">
<div className="w-full lg:w-[60%] lg:ml-auto flex justify-center items-center lg:min-h-screen px-4 py-8">
<div className="w-full max-w-lg flex flex-col gap-4 relative z-20">
<h1 className="text-2xl font-extrabold text-blue mb-8">Passwort zurücksetzen</h1>
<p className="text-sm text-gray-600 mb-4">
@ -129,7 +131,11 @@ const ResetPasswordView = () => {
error={confirmPasswordError}
/>
<Button type="submit" disabled={loading} className="w-full mt-6">
<Button
type="submit"
disabled={loading}
className="w-full mt-6 bg-blue/80 backdrop-blur-md border border-white/20"
>
{loading ? <Spinner /> : "Passwort zurücksetzen"}
</Button>
</form>