website refactor

This commit is contained in:
2026-01-14 10:51:05 +01:00
parent 4522d41aef
commit 0d89ad027e
291 changed files with 6887 additions and 3685 deletions

View File

@@ -7,7 +7,7 @@
'use client';
import { useState } from 'react';
import { ForgotPasswordViewData } from '@/lib/builders/view-data/ForgotPasswordViewDataBuilder';
import { ForgotPasswordViewData } from '@/lib/builders/view-data/types/ForgotPasswordViewData';
import { ForgotPasswordTemplate } from '@/templates/auth/ForgotPasswordTemplate';
import { ForgotPasswordMutation } from '@/lib/mutations/auth/ForgotPasswordMutation';
import { ForgotPasswordViewModelBuilder } from '@/lib/builders/view-models/ForgotPasswordViewModelBuilder';
@@ -73,7 +73,7 @@ export function ForgotPasswordClient({ viewData }: ForgotPasswordClientProps) {
setShowSuccess: (show) => {
if (!show) {
// Reset to initial state
setViewModel(prev => ForgotPasswordViewModelBuilder.build(viewData));
setViewModel(() => ForgotPasswordViewModelBuilder.build(viewData));
}
},
}}

View File

@@ -8,6 +8,7 @@
import { ForgotPasswordPageQuery } from '@/lib/page-queries/auth/ForgotPasswordPageQuery';
import { ForgotPasswordClient } from './ForgotPasswordClient';
import { AuthError } from '@/components/ui/AuthError';
export default async function ForgotPasswordPage({
searchParams,
@@ -19,12 +20,7 @@ export default async function ForgotPasswordPage({
const queryResult = await ForgotPasswordPageQuery.execute(params);
if (queryResult.isErr()) {
// Handle query error
return (
<div className="min-h-screen bg-deep-graphite flex items-center justify-center">
<div className="text-red-400">Failed to load forgot password page</div>
</div>
);
return <AuthError action="forgot password" />;
}
const viewData = queryResult.unwrap();

View File

@@ -1,6 +1,7 @@
import { headers } from 'next/headers';
import { redirect } from 'next/navigation';
import { createRouteGuard } from '@/lib/auth/createRouteGuard';
import { AuthContainer } from '@/components/ui/AuthContainer';
interface AuthLayoutProps {
children: React.ReactNode;
@@ -11,7 +12,7 @@ interface AuthLayoutProps {
*
* Provides authentication route protection for all auth routes.
* Uses RouteGuard to enforce access control server-side.
*
*
* Behavior:
* - Unauthenticated users can access auth pages (login, signup, etc.)
* - Authenticated users are redirected away from auth pages
@@ -26,9 +27,5 @@ export default async function AuthLayout({ children }: AuthLayoutProps) {
redirect(result.to);
}
return (
<div className="min-h-screen bg-deep-graphite flex items-center justify-center p-4">
{children}
</div>
);
return <AuthContainer>{children}</AuthContainer>;
}

View File

@@ -11,12 +11,13 @@ import { useState, useEffect, useMemo } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useAuth } from '@/lib/auth/AuthContext';
import { LoginFlowController, LoginState } from '@/lib/auth/LoginFlowController';
import { LoginViewData } from '@/lib/builders/view-data/LoginViewDataBuilder';
import { LoginViewData } from '@/lib/builders/view-data/types/LoginViewData';
import { LoginTemplate } from '@/templates/auth/LoginTemplate';
import { LoginMutation } from '@/lib/mutations/auth/LoginMutation';
import { validateLoginForm, type LoginFormValues } from '@/lib/utils/validation';
import { LoginViewModelBuilder } from '@/lib/builders/view-models/LoginViewModelBuilder';
import { LoginViewModel } from '@/lib/view-models/auth/LoginViewModel';
import { AuthLoading } from '@/components/ui/AuthLoading';
interface LoginClientProps {
viewData: LoginViewData;
@@ -179,30 +180,12 @@ export function LoginClient({ viewData }: LoginClientProps) {
}));
};
// Dismiss error details
const dismissErrorDetails = () => {
setViewModel(prev => {
const newFormState = {
...prev.formState,
submitError: undefined,
};
return prev.withFormState(newFormState).withUIState({
...prev.uiState,
showErrorDetails: false,
});
});
};
// Get current state from controller
const state = controller.getState();
// If user is authenticated with permissions, show loading
if (state === LoginState.AUTHENTICATED_WITH_PERMISSIONS) {
return (
<main className="min-h-screen bg-deep-graphite flex items-center justify-center">
<div className="w-8 h-8 border-2 border-primary-blue border-t-transparent rounded-full animate-spin" />
</main>
);
return <AuthLoading />;
}
// If user has insufficient permissions, show permission error

View File

@@ -8,6 +8,7 @@
import { LoginPageQuery } from '@/lib/page-queries/auth/LoginPageQuery';
import { LoginClient } from './LoginClient';
import { AuthError } from '@/components/ui/AuthError';
export default async function LoginPage({
searchParams,
@@ -19,12 +20,7 @@ export default async function LoginPage({
const queryResult = await LoginPageQuery.execute(params);
if (queryResult.isErr()) {
// Handle query error
return (
<div className="min-h-screen bg-deep-graphite flex items-center justify-center">
<div className="text-red-400">Failed to load login page</div>
</div>
);
return <AuthError action="login" />;
}
const viewData = queryResult.unwrap();

View File

@@ -8,11 +8,12 @@
import { useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { ResetPasswordViewData } from '@/lib/builders/view-data/ResetPasswordViewDataBuilder';
import { ResetPasswordViewData } from '@/lib/builders/view-data/types/ResetPasswordViewData';
import { ResetPasswordTemplate } from '@/templates/auth/ResetPasswordTemplate';
import { ResetPasswordMutation } from '@/lib/mutations/auth/ResetPasswordMutation';
import { ResetPasswordViewModelBuilder } from '@/lib/builders/view-models/ResetPasswordViewModelBuilder';
import { ResetPasswordViewModel } from '@/lib/view-models/auth/ResetPasswordViewModel';
import { routes } from '@/lib/routing/RouteConfig';
interface ResetPasswordClientProps {
viewData: ResetPasswordViewData;
@@ -70,7 +71,7 @@ export function ResetPasswordClient({ viewData }: ResetPasswordClientProps) {
// Redirect to login after a delay
setTimeout(() => {
router.push('/auth/login');
router.push(routes.auth.login);
}, 3000);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Failed to reset password';
@@ -120,7 +121,7 @@ export function ResetPasswordClient({ viewData }: ResetPasswordClientProps) {
setShowSuccess: (show) => {
if (!show) {
// Reset to initial state
setViewModel(prev => ResetPasswordViewModelBuilder.build(viewData));
setViewModel(() => ResetPasswordViewModelBuilder.build(viewData));
}
},
setShowPassword: togglePassword,

View File

@@ -8,6 +8,7 @@
import { ResetPasswordPageQuery } from '@/lib/page-queries/auth/ResetPasswordPageQuery';
import { ResetPasswordClient } from './ResetPasswordClient';
import { AuthError } from '@/components/ui/AuthError';
export default async function ResetPasswordPage({
searchParams,
@@ -19,12 +20,7 @@ export default async function ResetPasswordPage({
const queryResult = await ResetPasswordPageQuery.execute(params);
if (queryResult.isErr()) {
// Handle query error
return (
<div className="min-h-screen bg-deep-graphite flex items-center justify-center">
<div className="text-red-400">Failed to load reset password page</div>
</div>
);
return <AuthError action="reset password" />;
}
const viewData = queryResult.unwrap();

View File

@@ -9,7 +9,7 @@
import { useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useAuth } from '@/lib/auth/AuthContext';
import { SignupViewData } from '@/lib/builders/view-data/SignupViewDataBuilder';
import { SignupViewData } from '@/lib/builders/view-data/types/SignupViewData';
import { SignupTemplate } from '@/templates/auth/SignupTemplate';
import { SignupMutation } from '@/lib/mutations/auth/SignupMutation';
import { SignupViewModelBuilder } from '@/lib/builders/view-models/SignupViewModelBuilder';

View File

@@ -8,6 +8,7 @@
import { SignupPageQuery } from '@/lib/page-queries/auth/SignupPageQuery';
import { SignupClient } from './SignupClient';
import { AuthError } from '@/components/ui/AuthError';
export default async function SignupPage({
searchParams,
@@ -19,12 +20,7 @@ export default async function SignupPage({
const queryResult = await SignupPageQuery.execute(params);
if (queryResult.isErr()) {
// Handle query error
return (
<div className="min-h-screen bg-deep-graphite flex items-center justify-center">
<div className="text-red-400">Failed to load signup page</div>
</div>
);
return <AuthError action="signup" />;
}
const viewData = queryResult.unwrap();