From 4ea155cf3306199c80a5c424db784b1c560c83a4 Mon Sep 17 00:00:00 2001 From: cte Date: Sun, 11 May 2025 22:56:45 -0700 Subject: [PATCH] More cleanup --- .vscode/settings.json | 60 ++----- src/actions/locale.ts | 9 + src/app/(auth)/dashboard/layout.tsx | 2 +- .../[[...organization-profile]]/page.tsx | 2 +- src/app/(auth)/dashboard/page.tsx | 4 +- .../user-profile/[[...user-profile]]/page.tsx | 2 +- src/app/(unauth)/page.tsx | 8 +- src/app/robots.ts | 2 +- src/app/sitemap.ts | 2 +- src/components/ActiveLink.tsx | 14 +- src/components/Background.stories.tsx | 28 --- src/components/Background.tsx | 10 -- src/components/DemoBadge.tsx | 10 -- src/components/LocaleSwitcher.tsx | 28 +-- src/components/ToggleMenuButton.tsx | 14 +- src/components/dashboard/DashboardHeader.tsx | 96 ++++++++++ .../dashboard/DashboardSection.tsx | 0 .../dashboard/MessageState.tsx | 0 .../dashboard/TitleBar.tsx | 0 .../landing/CenteredFooter.test.tsx | 0 src/components/landing/CenteredFooter.tsx | 34 ++++ src/components/landing/CenteredHero.tsx | 25 +++ .../landing/CenteredMenu.tsx | 4 +- .../landing/FeatureCard.tsx | 0 .../landing/Section.tsx | 2 +- src/{ => components}/templates/Features.tsx | 14 +- src/components/templates/Footer.tsx | 53 ++++++ src/components/templates/Hero.tsx | 23 +++ src/components/templates/Logo.tsx | 7 + src/{ => components}/templates/Navbar.tsx | 4 +- src/{libs/DB.ts => db/index.ts} | 4 +- src/{models/Schema.ts => db/schema.ts} | 0 src/features/dashboard/DashboardHeader.tsx | 111 ------------ src/features/landing/CenteredFooter.tsx | 52 ------ src/features/landing/CenteredHero.tsx | 22 --- src/hooks/UseMenu.test.ts | 2 +- src/i18n/locales/en.json | 75 ++++++++ src/i18n/locales/fr.json | 75 ++++++++ src/i18n/request.ts | 14 +- src/lib/constants.ts | 3 + src/{utils/Helpers.ts => lib/getBaseUrl.ts} | 8 - src/{libs => lib/server}/Env.ts | 0 src/{libs => lib/server}/Logger.ts | 0 src/locales/en.json | 166 ------------------ src/locales/fr.json | 166 ------------------ src/templates/Footer.tsx | 110 ------------ src/templates/Hero.tsx | 52 ------ src/templates/Logo.tsx | 21 --- src/types/Auth.ts | 4 +- src/types/Subscription.ts | 34 +--- src/types/global.d.ts | 2 +- src/types/locale.ts | 11 ++ src/utils/AppConfig.ts | 11 -- 53 files changed, 487 insertions(+), 913 deletions(-) create mode 100644 src/actions/locale.ts delete mode 100644 src/components/Background.stories.tsx delete mode 100644 src/components/Background.tsx delete mode 100644 src/components/DemoBadge.tsx create mode 100644 src/components/dashboard/DashboardHeader.tsx rename src/{features => components}/dashboard/DashboardSection.tsx (100%) rename src/{features => components}/dashboard/MessageState.tsx (100%) rename src/{features => components}/dashboard/TitleBar.tsx (100%) rename src/{features => components}/landing/CenteredFooter.test.tsx (100%) create mode 100644 src/components/landing/CenteredFooter.tsx create mode 100644 src/components/landing/CenteredHero.tsx rename src/{features => components}/landing/CenteredMenu.tsx (94%) rename src/{features => components}/landing/FeatureCard.tsx (100%) rename src/{features => components}/landing/Section.tsx (96%) rename src/{ => components}/templates/Features.tsx (95%) create mode 100644 src/components/templates/Footer.tsx create mode 100644 src/components/templates/Hero.tsx create mode 100644 src/components/templates/Logo.tsx rename src/{ => components}/templates/Navbar.tsx (87%) rename src/{libs/DB.ts => db/index.ts} (94%) rename src/{models/Schema.ts => db/schema.ts} (100%) delete mode 100644 src/features/dashboard/DashboardHeader.tsx delete mode 100644 src/features/landing/CenteredFooter.tsx delete mode 100644 src/features/landing/CenteredHero.tsx create mode 100644 src/i18n/locales/en.json create mode 100644 src/i18n/locales/fr.json create mode 100644 src/lib/constants.ts rename src/{utils/Helpers.ts => lib/getBaseUrl.ts} (68%) rename src/{libs => lib/server}/Env.ts (100%) rename src/{libs => lib/server}/Logger.ts (100%) delete mode 100644 src/locales/en.json delete mode 100644 src/locales/fr.json delete mode 100644 src/templates/Footer.tsx delete mode 100644 src/templates/Hero.tsx delete mode 100644 src/templates/Logo.tsx create mode 100644 src/types/locale.ts delete mode 100644 src/utils/AppConfig.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 12bd7febf5..f0e1d3117f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,57 +1,17 @@ { "editor.tabSize": 2, "editor.detectIndentation": false, - "search.exclude": { - "package-lock.json": true - }, - - // TypeScript - "typescript.tsdk": "node_modules/typescript/lib", // Use the workspace version of TypeScript - "typescript.enablePromptUseWorkspaceTsdk": true, // For security reasons it's require that users opt into using the workspace version of typescript - "typescript.preferences.autoImportFileExcludePatterns": [ - // useRouter should be imported from `next/navigation` instead of `next/router` - "next/router.d.ts", - "next/dist/client/router.d.ts", - // give priority for Link to next/link instead of lucide-react - "lucide-react" - ], - "typescript.preferences.preferTypeOnlyAutoImports": true, - - // Vitest - "testing.automaticallyOpenTestResults": "neverOpen", // Don't open the test results automatically - - "prettier.enable": true, "editor.formatOnSave": false, - // Auto fix with ESLint on save - // "editor.codeActionsOnSave": [ - // "source.addMissingImports", - // "source.fixAll.eslint" - // ], + "search.exclude": { + "pnpm-lock.yaml": true + }, - // Enable eslint for all supported languages - "eslint.format.enable": false, - "eslint.validate": [ - "javascript", - "javascriptreact", - "typescript", - "typescriptreact", - "vue", - "html", - "markdown", - "json", - "jsonc", - "yaml", - "toml", - "xml", - "gql", - "graphql", - "astro", - "css", - "less", - "scss", - "pcss", - "postcss", - "github-actions-workflow" - ] + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true, + "typescript.preferences.preferTypeOnlyAutoImports": true, + + "testing.automaticallyOpenTestResults": "neverOpen", + + "prettier.enable": true } diff --git a/src/actions/locale.ts b/src/actions/locale.ts new file mode 100644 index 0000000000..30d3ddd38e --- /dev/null +++ b/src/actions/locale.ts @@ -0,0 +1,9 @@ +'use server'; + +import type { Locale } from '@/types/locale'; +import { cookies } from 'next/headers'; + +export const setLocale = async (locale: Locale) => { + const store = await cookies(); + store.set('locale', locale); +}; diff --git a/src/app/(auth)/dashboard/layout.tsx b/src/app/(auth)/dashboard/layout.tsx index f99d35622d..848af4f664 100644 --- a/src/app/(auth)/dashboard/layout.tsx +++ b/src/app/(auth)/dashboard/layout.tsx @@ -1,7 +1,7 @@ import { useTranslations } from 'next-intl'; import { getLocale, getTranslations } from 'next-intl/server'; -import { DashboardHeader } from '@/features/dashboard/DashboardHeader'; +import { DashboardHeader } from '@/components/dashboard/DashboardHeader'; export async function generateMetadata() { const locale = await getLocale(); diff --git a/src/app/(auth)/dashboard/organization-profile/[[...organization-profile]]/page.tsx b/src/app/(auth)/dashboard/organization-profile/[[...organization-profile]]/page.tsx index c299da19cd..a6a582c118 100644 --- a/src/app/(auth)/dashboard/organization-profile/[[...organization-profile]]/page.tsx +++ b/src/app/(auth)/dashboard/organization-profile/[[...organization-profile]]/page.tsx @@ -1,7 +1,7 @@ import { OrganizationProfile } from '@clerk/nextjs'; import { useTranslations } from 'next-intl'; -import { TitleBar } from '@/features/dashboard/TitleBar'; +import { TitleBar } from '@/components/dashboard/TitleBar'; const OrganizationProfilePage = () => { const t = useTranslations('OrganizationProfile'); diff --git a/src/app/(auth)/dashboard/page.tsx b/src/app/(auth)/dashboard/page.tsx index ce695d2816..003ab79f0e 100644 --- a/src/app/(auth)/dashboard/page.tsx +++ b/src/app/(auth)/dashboard/page.tsx @@ -1,7 +1,7 @@ import { useTranslations } from 'next-intl'; -import { MessageState } from '@/features/dashboard/MessageState'; -import { TitleBar } from '@/features/dashboard/TitleBar'; +import { MessageState } from '@/components/dashboard/MessageState'; +import { TitleBar } from '@/components/dashboard/TitleBar'; const DashboardIndexPage = () => { const t = useTranslations('DashboardIndex'); diff --git a/src/app/(auth)/dashboard/user-profile/[[...user-profile]]/page.tsx b/src/app/(auth)/dashboard/user-profile/[[...user-profile]]/page.tsx index 143b1350b4..981c618f43 100644 --- a/src/app/(auth)/dashboard/user-profile/[[...user-profile]]/page.tsx +++ b/src/app/(auth)/dashboard/user-profile/[[...user-profile]]/page.tsx @@ -1,7 +1,7 @@ import { UserProfile } from '@clerk/nextjs'; import { useTranslations } from 'next-intl'; -import { TitleBar } from '@/features/dashboard/TitleBar'; +import { TitleBar } from '@/components/dashboard/TitleBar'; const UserProfilePage = () => { const t = useTranslations('UserProfile'); diff --git a/src/app/(unauth)/page.tsx b/src/app/(unauth)/page.tsx index 5b5a82d1eb..71c5fdb064 100644 --- a/src/app/(unauth)/page.tsx +++ b/src/app/(unauth)/page.tsx @@ -1,9 +1,9 @@ import { getLocale, getTranslations, setRequestLocale } from 'next-intl/server'; -import { Features } from '@/templates/Features'; -import { Footer } from '@/templates/Footer'; -import { Hero } from '@/templates/Hero'; -import { Navbar } from '@/templates/Navbar'; +import { Features } from '@/components/templates/Features'; +import { Footer } from '@/components/templates/Footer'; +import { Hero } from '@/components/templates/Hero'; +import { Navbar } from '@/components/templates/Navbar'; export async function generateMetadata() { const locale = await getLocale(); diff --git a/src/app/robots.ts b/src/app/robots.ts index a19cd8670a..c1807a9ddc 100644 --- a/src/app/robots.ts +++ b/src/app/robots.ts @@ -1,6 +1,6 @@ import type { MetadataRoute } from 'next'; -import { getBaseUrl } from '@/utils/Helpers'; +import { getBaseUrl } from '@/lib/getBaseUrl'; export default function robots(): MetadataRoute.Robots { return { diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index 31d1f0084a..2b48226917 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -1,6 +1,6 @@ import type { MetadataRoute } from 'next'; -import { getBaseUrl } from '@/utils/Helpers'; +import { getBaseUrl } from '@/lib/getBaseUrl'; export default function sitemap(): MetadataRoute.Sitemap { return [ diff --git a/src/components/ActiveLink.tsx b/src/components/ActiveLink.tsx index 126a2016f8..3f9aaab682 100644 --- a/src/components/ActiveLink.tsx +++ b/src/components/ActiveLink.tsx @@ -3,24 +3,26 @@ import Link from 'next/link'; import { usePathname } from 'next/navigation'; -import { cn } from '@/utils/Helpers'; +import { cn } from '@/lib/utils'; -export const ActiveLink = (props: { +type ActiveLinkProps = { href: string; children: React.ReactNode; -}) => { +}; + +export const ActiveLink = ({ href, children }: ActiveLinkProps) => { const pathname = usePathname(); return ( - {props.children} + {children} ); }; diff --git a/src/components/Background.stories.tsx b/src/components/Background.stories.tsx deleted file mode 100644 index 8fb6888ae1..0000000000 --- a/src/components/Background.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { Background } from './Background'; - -const meta = { - title: 'Components/Background', - component: Background, - parameters: { - layout: 'fullscreen', - }, - tags: ['autodocs'], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const DefaultBackgroundWithChildren = { - args: { - children:
Children node
, - }, -} satisfies Story; - -export const RedBackgroundWithChildren = { - args: { - className: 'bg-red-500', - children:
Children node
, - }, -} satisfies Story; diff --git a/src/components/Background.tsx b/src/components/Background.tsx deleted file mode 100644 index 0a14233b04..0000000000 --- a/src/components/Background.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { cn } from '@/utils/Helpers'; - -export const Background = (props: { - children: React.ReactNode; - className?: string; -}) => ( -
- {props.children} -
-); diff --git a/src/components/DemoBadge.tsx b/src/components/DemoBadge.tsx deleted file mode 100644 index c33f891e86..0000000000 --- a/src/components/DemoBadge.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export const DemoBadge = () => ( -
- -
- Demo of - {' SaaS Boilerplate'} -
-
-
-); diff --git a/src/components/LocaleSwitcher.tsx b/src/components/LocaleSwitcher.tsx index 37beada1d4..3abc7afb02 100644 --- a/src/components/LocaleSwitcher.tsx +++ b/src/components/LocaleSwitcher.tsx @@ -1,8 +1,11 @@ 'use client'; -import { usePathname, useRouter } from 'next/navigation'; +import { useCallback } from 'react'; +import { useRouter } from 'next/navigation'; import { useLocale } from 'next-intl'; +import { Locales, isLocale } from '@/types/locale'; +import { setLocale } from '@/actions/locale'; import { Button } from '@/components/ui/button'; import { DropdownMenu, @@ -11,17 +14,20 @@ import { DropdownMenuRadioItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; -import { AppConfig } from '@/utils/AppConfig'; export const LocaleSwitcher = () => { const router = useRouter(); - const pathname = usePathname(); const locale = useLocale(); - const handleChange = () => { - router.push(pathname); - router.refresh(); - }; + const onLocaleChange = useCallback( + (value: string) => { + if (isLocale(value)) { + setLocale(value); + router.refresh(); + } + }, + [router], + ); return ( @@ -47,10 +53,10 @@ export const LocaleSwitcher = () => { - - {AppConfig.locales.map((elt) => ( - - {elt.name} + + {Object.entries(Locales).map(([id, name]) => ( + + {name} ))} diff --git a/src/components/ToggleMenuButton.tsx b/src/components/ToggleMenuButton.tsx index a5b0c20503..7f2c2976a4 100644 --- a/src/components/ToggleMenuButton.tsx +++ b/src/components/ToggleMenuButton.tsx @@ -2,16 +2,12 @@ import { type ForwardedRef, forwardRef } from 'react'; import { Button } from '@/components/ui/button'; -/** - * A toggle button to show/hide component in small screen. - * @component - * @params props - Component props. - * @params props.onClick - Function to run when the button is clicked. - */ +type ToggleMenuButtonProps = { + onClick?: () => void; +}; + const ToggleMenuButtonInternal = ( - props: { - onClick?: () => void; - }, + props: ToggleMenuButtonProps, ref?: ForwardedRef, ) => (