refactor: centralize route management with comprehensive Routes enum

This commit is contained in:
javayhu 2025-03-01 14:16:26 +08:00
parent 7ab78c95dc
commit 31575c599d
14 changed files with 104 additions and 44 deletions

View File

@ -1,12 +1,12 @@
import { ErrorCard } from "@/components/auth/error-card";
import { siteConfig } from "@/config/site";
import { constructMetadata } from "@/lib/metadata";
import { AUTH_ROUTE_ERROR } from "@/routes";
import { Routes } from "@/routes";
export const metadata = constructMetadata({
title: "Auth Error",
description: "Auth Error",
canonicalUrl: `${siteConfig.url}${AUTH_ROUTE_ERROR}`,
canonicalUrl: `${siteConfig.url}${Routes.AuthError}`,
});
const AuthErrorPage = () => {

View File

@ -1,12 +1,12 @@
import { ForgotPasswordForm } from "@/components/auth/forgot-password-form";
import { siteConfig } from "@/config/site";
import { constructMetadata } from "@/lib/metadata";
import { AUTH_ROUTE_FORGOT_PASSWORD } from "@/routes";
import { Routes } from "@/routes";
export const metadata = constructMetadata({
title: "Forgot Password",
description: "Forgot your password? Reset it.",
canonicalUrl: `${siteConfig.url}${AUTH_ROUTE_FORGOT_PASSWORD}`,
canonicalUrl: `${siteConfig.url}${Routes.ForgotPassword}`,
});
const ForgotPasswordPage = () => {

View File

@ -1,12 +1,12 @@
import { LoginForm } from "@/components/auth/login-form";
import { siteConfig } from "@/config/site";
import { constructMetadata } from "@/lib/metadata";
import { AUTH_ROUTE_LOGIN } from "@/routes";
import { Routes } from "@/routes";
export const metadata = constructMetadata({
title: "Login",
description: "Login to your account",
canonicalUrl: `${siteConfig.url}${AUTH_ROUTE_LOGIN}`,
canonicalUrl: `${siteConfig.url}${Routes.Login}`,
});
const LoginPage = () => {

View File

@ -1,12 +1,12 @@
import { RegisterForm } from "@/components/auth/register-form";
import { siteConfig } from "@/config/site";
import { constructMetadata } from "@/lib/metadata";
import { AUTH_ROUTE_REGISTER } from "@/routes";
import { Routes } from "@/routes";
export const metadata = constructMetadata({
title: "Register",
description: "Create an account to get started",
canonicalUrl: `${siteConfig.url}${AUTH_ROUTE_REGISTER}`,
canonicalUrl: `${siteConfig.url}${Routes.Register}`,
});
const RegisterPage = () => {

View File

@ -1,12 +1,12 @@
import { AuthCard } from "@/components/auth/auth-card";
import { AUTH_ROUTE_LOGIN } from "@/routes";
import { Routes } from "@/routes";
import { TriangleAlertIcon } from "lucide-react";
export const ErrorCard = () => {
return (
<AuthCard
headerLabel="Something went wrong!"
bottomButtonHref={`${AUTH_ROUTE_LOGIN}`}
bottomButtonHref={`${Routes.Login}`}
bottomButtonLabel="Back to login"
className="border-none"
>

View File

@ -37,7 +37,7 @@ export const ForgotPasswordForm = () => {
const onSubmit = async (values: z.infer<typeof ForgotPasswordSchema>) => {
const { data, error } = await authClient.forgetPassword({
email: values.email,
redirectTo: `${AUTH_ROUTE_RESET_PASSWORD}`,
redirectTo: `${Routes.ResetPassword}`,
}, {
onRequest: (ctx) => {
// console.log("forgotPassword, request:", ctx.url);
@ -64,7 +64,7 @@ export const ForgotPasswordForm = () => {
<AuthCard
headerLabel="Froget password?"
bottomButtonLabel="Back to login"
bottomButtonHref={`${AUTH_ROUTE_LOGIN}`}
bottomButtonHref={`${Routes.Login}`}
className="border-none"
>
<Form {...form}>

View File

@ -9,7 +9,7 @@ import {
} from "@/components/ui/dialog";
import { LoginForm } from "@/components/auth/login-form";
import { useMediaQuery } from "@/hooks/use-media-query";
import { AUTH_ROUTE_LOGIN, authRoutes } from "@/routes";
import { Routes, authRoutes } from "@/routes";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
@ -31,7 +31,7 @@ export const LoginWrapper = ({
const { isTablet, isDesktop } = useMediaQuery();
const handleLogin = () => {
router.push(`${AUTH_ROUTE_LOGIN}`);
router.push(`${Routes.Login}`);
};
// Close the modal on route change
@ -41,7 +41,8 @@ export const LoginWrapper = ({
// 1. don't open the modal if the user is already in the auth pages
// 2. keep isTablet or isDesktop open, if user resizes the window
const isAuthRoute = authRoutes.includes(pathname);
// 3. TODO: pathname as Routes ???
const isAuthRoute = authRoutes.includes(pathname as Routes);
if (mode === "modal" && !isAuthRoute && (isTablet || isDesktop)) {
return (
<Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>

View File

@ -17,7 +17,7 @@ import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { LoginSchema } from "@/lib/schemas";
import { cn } from "@/lib/utils";
import { AUTH_ROUTE_FORGOT_PASSWORD, AUTH_ROUTE_REGISTER, DEFAULT_LOGIN_REDIRECT } from "@/routes";
import { Routes } from "@/routes";
import { zodResolver } from "@hookform/resolvers/zod";
import { useSearchParams } from "next/navigation";
import { useState } from "react";
@ -48,7 +48,7 @@ export const LoginForm = ({ className }: { className?: string }) => {
const { data, error } = await authClient.signIn.email({
email: values.email,
password: values.password,
callbackURL: callbackUrl || DEFAULT_LOGIN_REDIRECT,
callbackURL: callbackUrl || Routes.DefaultLoginRedirect,
}, {
onRequest: (ctx) => {
// console.log("login, request:", ctx.url);
@ -76,7 +76,7 @@ export const LoginForm = ({ className }: { className?: string }) => {
<AuthCard
headerLabel="Welcome back"
bottomButtonLabel="Don't have an account? Sign up"
bottomButtonHref={`${AUTH_ROUTE_REGISTER}`}
bottomButtonHref={`${Routes.Register}`}
showSocialLoginButton
className={cn("border-none", className)}
>
@ -115,7 +115,7 @@ export const LoginForm = ({ className }: { className?: string }) => {
className="px-0 font-normal text-muted-foreground"
>
<a
href={`${AUTH_ROUTE_FORGOT_PASSWORD}`}
href={`${Routes.ForgotPassword}`}
className="text-xs hover:underline hover:underline-offset-4 hover:text-primary"
>
Forgot password?

View File

@ -16,7 +16,7 @@ import {
import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { RegisterSchema } from "@/lib/schemas";
import { AUTH_ROUTE_LOGIN, DEFAULT_LOGIN_REDIRECT } from "@/routes";
import { Routes } from "@/routes";
import { zodResolver } from "@hookform/resolvers/zod";
import { useSearchParams } from "next/navigation";
import { useState } from "react";
@ -49,7 +49,7 @@ export const RegisterForm = () => {
email: values.email,
password: values.password,
name: values.name,
callbackURL: callbackUrl || DEFAULT_LOGIN_REDIRECT,
callbackURL: callbackUrl || Routes.DefaultLoginRedirect,
}, {
onRequest: (ctx) => {
console.log("register, request:", ctx.url);
@ -78,7 +78,7 @@ export const RegisterForm = () => {
<AuthCard
headerLabel="Create an account"
bottomButtonLabel="Already have an account? Sign in"
bottomButtonHref={`${AUTH_ROUTE_LOGIN}`}
bottomButtonHref={`${Routes.Login}`}
showSocialLoginButton
className="border-none"
>

View File

@ -16,7 +16,7 @@ import {
import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { ResetPasswordSchema } from "@/lib/schemas";
import { AUTH_ROUTE_LOGIN } from "@/routes";
import { Routes } from "@/routes";
import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";
@ -62,7 +62,7 @@ export const ResetPasswordForm = () => {
onSuccess: (ctx) => {
// console.log("resetPassword, success:", ctx.data);
// setSuccess("Password reset successfully");
router.push(`${AUTH_ROUTE_LOGIN}`);
router.push(`${Routes.Login}`);
},
onError: (ctx) => {
console.log("resetPassword, error:", ctx.error);
@ -75,7 +75,7 @@ export const ResetPasswordForm = () => {
<AuthCard
headerLabel="Reset password"
bottomButtonLabel="Back to login"
bottomButtonHref={`${AUTH_ROUTE_LOGIN}`}
bottomButtonHref={`${Routes.Login}`}
className="border-none"
>
<Form {...form}>

View File

@ -7,7 +7,7 @@ import { useState } from "react";
import { GitHubIcon } from "@/components/icons/github";
import { GoogleIcon } from "@/components/icons/google";
import { authClient } from "@/lib/auth-client";
import { AUTH_ROUTE_ERROR, DEFAULT_LOGIN_REDIRECT } from "@/routes";
import { Routes } from "@/routes";
/**
* social login buttons
@ -28,11 +28,11 @@ export const SocialLoginButton = () => {
* a url to redirect after the user authenticates with the provider
* @default "/"
*/
callbackURL: callbackUrl || DEFAULT_LOGIN_REDIRECT,
callbackURL: callbackUrl || Routes.DefaultLoginRedirect,
/**
* a url to redirect if an error occurs during the sign in process
*/
errorCallbackURL: `${AUTH_ROUTE_ERROR}`,
errorCallbackURL: Routes.AuthError,
/**
* a url to redirect if the user is newly registered
*/

View File

@ -10,7 +10,7 @@ import type * as React from "react";
import Container from "@/components/container";
import { Logo } from "@/components/logo";
import BuiltWithButton from "@/components/shared/built-with-button";
import { ThemeSwitcherHorizontal } from "@/components/layout/mode-toggle-horizontal";
import { ThemeSwitcherHorizontal } from "@/components/layout/theme-switcher-horizontal";
export function Footer({ className }: React.HTMLAttributes<HTMLElement>) {
const { theme } = useTheme();

View File

@ -9,12 +9,13 @@ import {
LayoutIcon,
PlayIcon
} from 'lucide-react';
import { Routes } from '@/constants/routes';
import { Routes } from '@/routes';
import { FacebookIcon } from '@/components/icons/facebook';
import { InstagramIcon } from '@/components/icons/instagram';
import { LinkedInIcon } from '@/components/icons/linkedin';
import { TikTokIcon } from '@/components/icons/tiktok';
import { XTwitterIcon } from '@/components/icons/x';
export const MENU_LINKS = [
{
title: 'Features',

View File

@ -1,3 +1,69 @@
/**
* The routes for the application
*/
export enum Routes {
Root = '/',
Contact = '/contact',
Roadmap = 'https://achromatic.canny.io',
Docs = '/docs',
Pricing = '/pricing',
Blog = '/blog',
Story = '/story',
Careers = '/careers',
TermsOfUse = '/terms-of-use',
PrivacyPolicy = '/privacy-policy',
CookiePolicy = '/cookie-policy',
Login = '/auth/login',
Register = '/auth/register',
AuthError = '/auth/error',
ForgotPassword = '/auth/forgot-password',
ResetPassword = '/auth/reset-password',
Auth = '/auth',
Logout = '/auth/logout',
Totp = '/auth/totp',
RecoveryCode = '/auth/recovery-code',
ChangeEmail = '/auth/change-email',
ChangeEmailRequest = '/auth/change-email/request',
ChangeEmailInvalid = '/auth/change-email/invalid',
ChangeEmailExpired = '/auth/change-email/expired',
// ForgotPassword = '/auth/forgot-password',
ForgotPasswordSuccess = '/auth/forgot-password/success',
// ResetPassword = '/auth/reset-password',
ResetPasswordRequest = '/auth/reset-password/request',
ResetPasswordExpired = '/auth/reset-password/expired',
ResetPasswordSuccess = '/auth/reset-password/success',
VerifyEmail = '/auth/verify-email',
VerifyEmailRequest = '/auth/verify-email/request',
VerifyEmailExpired = '/auth/verify-email/expired',
VerifyEmailSuccess = '/auth/verify-email/success',
Dashboard = '/dashboard',
Home = '/dashboard/home',
Contacts = '/dashboard/contacts',
Settings = '/dashboard/settings',
Account = '/dashboard/settings/account',
Profile = '/dashboard/settings/account/profile',
Security = '/dashboard/settings/account/security',
Notifications = '/dashboard/settings/account/notifications',
Organization = '/dashboard/settings/organization',
OrganizationInformation = '/dashboard/settings/organization/information',
Members = '/dashboard/settings/organization/members',
Billing = '/dashboard/settings/organization/billing',
Developers = '/dashboard/settings/organization/developers',
Invitations = '/invitations',
InvitationRequest = '/invitations/request',
InvitationAlreadyAccepted = '/invitations/already-accepted',
InvitationRevoked = '/invitations/revoked',
InvitationLogOutToAccept = '/invitations/log-out-to-accept',
Onboarding = '/onboarding',
DefaultLoginRedirect = '/dashboard',
}
/**
* An array of routes that are accessible to the public
* These routes do not require authentication
@ -27,22 +93,14 @@ export const publicRoutes = [
];
/**
* An array of routes that are used for authentication
* These routes will redirect logged in users to /dashboard
* @type {string[]}
* The routes for the authentication pages
*/
export const AUTH_ROUTE_LOGIN = "/auth/login";
export const AUTH_ROUTE_REGISTER = "/auth/register";
export const AUTH_ROUTE_ERROR = "/auth/error";
export const AUTH_ROUTE_FORGOT_PASSWORD = "/auth/forgot-password";
export const AUTH_ROUTE_RESET_PASSWORD = "/auth/reset-password";
export const authRoutes = [
AUTH_ROUTE_LOGIN,
AUTH_ROUTE_REGISTER,
AUTH_ROUTE_ERROR,
AUTH_ROUTE_FORGOT_PASSWORD,
AUTH_ROUTE_RESET_PASSWORD,
Routes.Login,
Routes.Register,
Routes.AuthError,
Routes.ForgotPassword,
Routes.ResetPassword,
];
/**