Skip to content

Commit

Permalink
Merge pull request #44 from ixartz/refactor-component
Browse files Browse the repository at this point in the history
Refactor-component
  • Loading branch information
ixartz authored Oct 17, 2024
2 parents 75525ed + a0eeda1 commit 3af6a05
Show file tree
Hide file tree
Showing 24 changed files with 1,488 additions and 1,361 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ You can easily configure Next.js SaaS Boilerplate by searching the entire projec

You have full access to the source code for further customization. The provided code is just an example to help you start your project. The sky's the limit 🚀.

In the source code, you will also find `PRO` comments that indicate the code that is only available in the PRO version. You can easily remove or replace this code with your own implementation.

### Change database schema

To modify the database schema in the project, you can update the schema file located at `./src/models/Schema.ts`. This file defines the structure of your database tables using the Drizzle ORM library.
Expand Down
2,647 changes: 1,385 additions & 1,262 deletions package-lock.json

Large diffs are not rendered by default.

80 changes: 41 additions & 39 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,87 +26,89 @@
"prepare": "husky"
},
"dependencies": {
"@clerk/localizations": "^3.1.2",
"@clerk/nextjs": "^5.7.1",
"@electric-sql/pglite": "^0.2.10",
"@clerk/localizations": "^3.2.1",
"@clerk/nextjs": "^5.7.3",
"@clerk/themes": "^2.1.36",
"@electric-sql/pglite": "^0.2.12",
"@hookform/resolvers": "^3.9.0",
"@logtail/pino": "^0.5.0",
"@logtail/pino": "^0.5.2",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
"@sentry/nextjs": "^8.33.1",
"@spotlightjs/spotlight": "^2.4.2",
"@sentry/nextjs": "^8.34.0",
"@spotlightjs/spotlight": "^2.5.0",
"@t3-oss/env-nextjs": "^0.11.1",
"@tanstack/react-table": "^8.20.5",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"drizzle-orm": "^0.33.0",
"lucide-react": "^0.447.0",
"next": "^14.2.14",
"next-intl": "^3.20.0",
"drizzle-orm": "^0.35.1",
"lucide-react": "^0.453.0",
"next": "^14.2.15",
"next-intl": "^3.21.1",
"next-themes": "^0.3.0",
"pg": "^8.13.0",
"pino": "^9.4.0",
"pino-pretty": "^11.2.2",
"pino": "^9.5.0",
"pino-pretty": "^11.3.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.0",
"sharp": "^0.33.5",
"stripe": "^16.12.0",
"tailwind-merge": "^2.5.3",
"tailwind-merge": "^2.5.4",
"zod": "^3.23.8"
},
"devDependencies": {
"@antfu/eslint-config": "^2.27.3",
"@clerk/testing": "^1.3.9",
"@clerk/testing": "^1.3.11",
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@commitlint/cz-commitlint": "^19.5.0",
"@eslint-react/eslint-plugin": "^1.14.3",
"@eslint-react/eslint-plugin": "^1.15.0",
"@faker-js/faker": "^9.0.3",
"@next/bundle-analyzer": "^14.2.14",
"@next/eslint-plugin-next": "^14.2.14",
"@percy/cli": "1.29.4",
"@next/bundle-analyzer": "^14.2.15",
"@next/eslint-plugin-next": "^14.2.15",
"@percy/cli": "1.30.1",
"@percy/playwright": "^1.0.6",
"@playwright/test": "^1.47.2",
"@playwright/test": "^1.48.1",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@storybook/addon-essentials": "^8.3.4",
"@storybook/addon-interactions": "^8.3.4",
"@storybook/addon-links": "^8.3.4",
"@storybook/addon-onboarding": "^8.3.4",
"@storybook/blocks": "^8.3.4",
"@storybook/nextjs": "^8.3.4",
"@storybook/react": "^8.3.4",
"@storybook/test": "^8.3.4",
"@storybook/addon-essentials": "^8.3.5",
"@storybook/addon-interactions": "^8.3.5",
"@storybook/addon-links": "^8.3.5",
"@storybook/addon-onboarding": "^8.3.5",
"@storybook/blocks": "^8.3.5",
"@storybook/nextjs": "^8.3.5",
"@storybook/react": "^8.3.5",
"@storybook/test": "^8.3.5",
"@storybook/test-runner": "^0.19.1",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/jest-dom": "^6.6.1",
"@testing-library/react": "^16.0.1",
"@testing-library/user-event": "^14.5.2",
"@types/node": "^22.7.4",
"@types/node": "^22.7.6",
"@types/pg": "^8.11.10",
"@types/react": "^18.3.11",
"@vitejs/plugin-react": "^4.3.2",
"@vitest/coverage-v8": "^2.1.2",
"@vitest/expect": "^2.1.2",
"@vitest/coverage-v8": "^2.1.3",
"@vitest/expect": "^2.1.3",
"autoprefixer": "^10.4.20",
"checkly": "^4.9.0",
"commitizen": "^4.3.1",
"cross-env": "^7.0.3",
"cssnano": "^7.0.6",
"dotenv-cli": "^7.4.2",
"drizzle-kit": "^0.24.2",
"drizzle-kit": "^0.26.2",
"eslint": "^8.57.1",
"eslint-plugin-format": "^0.1.2",
"eslint-plugin-jest-dom": "^5.4.0",
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-playwright": "^1.6.2",
"eslint-plugin-playwright": "^1.7.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.12",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-tailwindcss": "^3.17.4",
"eslint-plugin-tailwindcss": "^3.17.5",
"eslint-plugin-testing-library": "^6.3.0",
"http-server": "^14.1.1",
"husky": "^9.1.6",
Expand All @@ -118,13 +120,13 @@
"rimraf": "^6.0.1",
"semantic-release": "^24.1.2",
"start-server-and-test": "^2.0.8",
"storybook": "^8.3.4",
"tailwindcss": "^3.4.13",
"storybook": "^8.3.5",
"tailwindcss": "^3.4.14",
"tailwindcss-animate": "^1.0.7",
"tsx": "^4.19.1",
"typescript": "^5.6.2",
"typescript": "^5.6.3",
"vite-tsconfig-paths": "^5.0.1",
"vitest": "^2.1.2",
"vitest": "^2.1.3",
"vitest-fail-on-console": "^0.7.1"
},
"config": {
Expand Down
Binary file modified public/assets/images/clerk-logo-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/images/clerk-logo-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/app/[locale]/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import { enUS, frFR } from '@clerk/localizations';
import { ClerkProvider } from '@clerk/nextjs';

Expand Down Expand Up @@ -26,6 +28,7 @@ export default function AuthLayout(props: {

return (
<ClerkProvider
// PRO: Dark mode support for Clerk
localization={clerkLocale}
signInUrl={signInUrl}
signUpUrl={signUpUrl}
Expand Down
10 changes: 8 additions & 2 deletions src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,15 @@ export default function RootLayout(props: {
// Using internationalization in Client Components
const messages = useMessages();

// The `suppressHydrationWarning` in <html> is used to prevent hydration errors caused by `next-themes`.
// Solution provided by the package itself: https://github.com/pacocoursey/next-themes?tab=readme-ov-file#with-app

// The `suppressHydrationWarning` attribute in <body> is used to prevent hydration errors caused by Sentry Overlay,
// which dynamically adds a `style` attribute to the body tag.
return (
<html lang={props.params.locale}>
<body className="bg-background text-foreground antialiased">
<html lang={props.params.locale} suppressHydrationWarning>
<body className="bg-background text-foreground antialiased" suppressHydrationWarning>
{/* PRO: Dark mode support for Shadcn UI */}
<NextIntlClientProvider
locale={props.params.locale}
messages={messages}
Expand Down
2 changes: 1 addition & 1 deletion src/components/LocaleSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const LocaleSwitcher = () => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button className="p-2 focus-visible:ring-offset-0" variant="ghost" aria-label="lang-switcher">
<Button className="p-2 focus-visible:ring-offset-0" variant="ghost" size="icon" aria-label="lang-switcher">
<svg
xmlns="http://www.w3.org/2000/svg"
className="size-6 stroke-current stroke-2"
Expand Down
8 changes: 3 additions & 5 deletions src/components/ToggleMenuButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ import { type ForwardedRef, forwardRef } from 'react';

import { Button } from '@/components/ui/button';

type IToggleMenuButtonProps = {
onClick?: () => void;
};

/**
* 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.
*/
const ToggleMenuButtonInternal = (
props: IToggleMenuButtonProps,
props: {
onClick?: () => void;
},
ref?: ForwardedRef<HTMLButtonElement>,
) => (
<Button
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/data-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function DataTable<TData, TValue>({
data-state={row.getIsSelected() && 'selected'}
>
{row.getVisibleCells().map(cell => (
<TableCell key={cell.id}>
<TableCell key={cell.id} className="whitespace-nowrap">
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
Expand Down
4 changes: 2 additions & 2 deletions src/features/billing/PricingCard.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useTranslations } from 'next-intl';
import React from 'react';

import type { BillingInterval, PlanId } from '@/types/Subscription';
import type { BillingInterval } from '@/types/Subscription';

export const PricingCard = (props: {
planId: PlanId;
planId: string;
price: number;
interval: BillingInterval;
button: React.ReactNode;
Expand Down
5 changes: 2 additions & 3 deletions src/features/billing/PricingInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ import { useTranslations } from 'next-intl';

import { PricingCard } from '@/features/billing/PricingCard';
import { PricingFeature } from '@/features/billing/PricingFeature';
import type { PlanId } from '@/types/Subscription';
import { PricingPlanList } from '@/utils/AppConfig';

export const PricingInformation = (props: {
buttonList: Record<PlanId, React.ReactNode>;
buttonList: Record<string, React.ReactNode>;
}) => {
const t = useTranslations('PricingPlan');

return (
<div className="grid grid-cols-1 gap-x-6 gap-y-8 md:grid-cols-3">
{PricingPlanList.map(plan => (
{Object.values(PricingPlanList).map(plan => (
<PricingCard
key={plan.id}
planId={plan.id}
Expand Down
8 changes: 5 additions & 3 deletions src/features/dashboard/DashboardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const DashboardHeader = (props: {
</Link>

<svg
className="ml-1 size-8 stroke-muted-foreground max-sm:hidden"
className="size-8 stroke-muted-foreground max-sm:hidden"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
Expand All @@ -54,7 +54,7 @@ export const DashboardHeader = (props: {
skipInvitationScreen
appearance={{
elements: {
organizationSwitcherTrigger: 'max-w-52',
organizationSwitcherTrigger: 'max-w-28 sm:max-w-52',
},
}}
/>
Expand All @@ -71,7 +71,7 @@ export const DashboardHeader = (props: {
</div>

<div>
<ul className="flex items-center gap-x-1 [&_li:not(:last-child):hover]:opacity-100 [&_li:not(:last-child)]:opacity-60">
<ul className="flex items-center gap-x-1.5 [&_li:not(:last-child):hover]:opacity-100 [&_li:not(:last-child)]:opacity-60">
<li>
<div className="lg:hidden">
<DropdownMenu>
Expand All @@ -89,6 +89,8 @@ export const DashboardHeader = (props: {
</div>
</li>

{/* PRO: Dark mode toggle button */}

<li>
<LocaleSwitcher />
</li>
Expand Down
5 changes: 2 additions & 3 deletions src/features/landing/CenteredFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Link from 'next/link';
import { useTranslations } from 'next-intl';
import React from 'react';

Expand Down Expand Up @@ -28,12 +27,12 @@ export const CenteredFooter = (props: {
{`© Copyright ${new Date().getFullYear()} ${props.name}. `}
{t.rich('designed_by', {
author: () => (
<Link
<a
className="text-blue-500 hover:text-blue-600"
href="https://creativedesignsguru.com"
>
Creative Designs Guru
</Link>
</a>
),
})}
{/*
Expand Down
18 changes: 2 additions & 16 deletions src/features/landing/CenteredHero.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
import { badgeVariants } from '@/components/ui/badgeVariants';

export const CenteredHero = (props: {
banner: {
href: string;
text: React.ReactNode;
};
banner: React.ReactNode;
title: React.ReactNode;
description: string;
buttons: React.ReactNode;
}) => (
<>
<div className="text-center">
<a
className={badgeVariants()}
href={props.banner.href}
target="_blank"
rel="noopener"
>
{props.banner.text}
</a>
</div>
<div className="text-center">{props.banner}</div>

<div className="mt-3 text-center text-5xl font-bold tracking-tight">
{props.title}
Expand Down
2 changes: 1 addition & 1 deletion src/features/landing/CenteredMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const CenteredMenu = (props: {
navClass,
)}
>
<ul className="flex flex-row items-center gap-x-4 text-lg font-medium [&_li:not(:last-child):hover]:opacity-100 [&_li:not(:last-child)]:opacity-60">
<ul className="flex flex-row items-center gap-x-1.5 text-lg font-medium [&_li:not(:last-child):hover]:opacity-100 [&_li:not(:last-child)]:opacity-60">
{props.rightMenu}
</ul>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/features/landing/FeatureCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const FeatureCard = (props: {
children: React.ReactNode;
}) => (
<div className="rounded-xl border border-border bg-card p-5">
<div className="size-12 rounded-lg bg-gradient-to-br from-indigo-400 via-purple-400 to-pink-400 p-2 [&_svg]:stroke-primary-foreground [&_svg]:stroke-2">
<div className="size-12 rounded-lg bg-gradient-to-br from-indigo-400 via-purple-400 to-pink-400 p-2 [&_svg]:stroke-white [&_svg]:stroke-2">
{props.icon}
</div>

Expand Down
3 changes: 2 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@
"edit": "Edit",
"delete": "Delete",
"title_header": "Title",
"message_header": "Message"
"message_header": "Message",
"created_at_header": "Created at"
},
"AddTodo": {
"title_bar": "Add Todo",
Expand Down
5 changes: 3 additions & 2 deletions src/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
"title_bar": "Tableau de bord",
"title_bar_description": "Bienvenue sur votre tableau de bord",
"message_state_title": "C'est parti",
"message_state_description": "Vous pouvez personnaliser cette page en modifiant le fichier dans <code>src/app/[locale]/(auth)/dashboard/page.tsx</code>",
"message_state_description": "Vous pouvez personnaliser cette page en modifiant le fichier dans <code>dashboard/page.tsx</code>",
"message_state_button": "Besoin d'une intégration Stripe ? Découvrez Next.js Boilerplate Pro"
},
"UserProfile": {
Expand Down Expand Up @@ -142,7 +142,8 @@
"edit": "Modifier",
"delete": "Supprimer",
"title_header": "Titre",
"message_header": "Message"
"message_header": "Message",
"created_at_header": "Créé le"
},
"AddTodo": {
"title_bar": "Ajouter une todo",
Expand Down
Loading

0 comments on commit 3af6a05

Please sign in to comment.