Build a Finance SaaS Platform -1 ( Initial )

Create New NEXTJS Project

1
npx create-next-app@latest finance-demo

Install shadcn-ui

1
npx shadcn-ui@latest init

Install Button

Follow instruction of shadcn doc

1
npx shadcn-ui@latest add button

Register Clerk

Register Clerk and install clerk

1
npm install @clerk/nextjs

follow instruction of Clerk to setup

Setup .env.local

1
2
3
4
5
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=...
CLERK_SECRET_KEY=...

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

Change home page

change page.tsx to app/(dashboard):

1
2
3
4
5
6
7
8
export default function Home() {
return (
<p>
this is an authenticated route
</p>
);
}

Change Layout:

change app/layout.tsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import type { Metadata } from "next";
import "./globals.css";
import { ClerkProvider } from "@clerk/nextjs";

export const metadata: Metadata = {
title: "Finance Demo",
description: "Finance Dashboard",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<ClerkProvider>
<html lang="en">
<body>{children}</body>
</html>
</ClerkProvider>
);
}

Add sign in page:

Add app/(auth)/sign-in/[[...sign-in]]/page.tsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import Image from "next/image";
import { Loader2 } from "lucide-react";
import { SignIn, ClerkLoaded,ClerkLoading } from "@clerk/nextjs";

export default function Page() {
return(
<div className="min-h-screen grid grid-cols-1 lg:grid-cols-2">
<div className="h-full lg:flex flex-col items-center justify-center px-4">
<div className="text-center space-y-4 pt-16">
<h1 className="font-bold text-3xl text-[#2E2A47]">
Welcome Back!
</h1>
<p className="text-base text-[#7E8CA0]">
Log in or Create account to get back to your dashboad!
</p>
</div>
<div className="flex items-center justify-center mt-8">
<ClerkLoaded>
<SignIn path="/sign-in" />
</ClerkLoaded>
<ClerkLoading>
<Loader2 className="animate-spin text-muted-foreground" />
</ClerkLoading>
</div>
</div>
<div className="h-full bg-blue-600 hidden lg:flex items-center justify-center">
<Image src="/vim-logo.svg" height={100} width={100} alt="Logo" />
</div>
</div>
)
}

Add sign up page

Add app/(auth)/sign-up/[[...sign-up]]/page.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import Image from "next/image";
import { Loader2 } from "lucide-react";
import { SignUp, ClerkLoaded,ClerkLoading } from "@clerk/nextjs";

export default function Page() {
return(
<div className="min-h-screen grid grid-cols-1 lg:grid-cols-2">
<div className="h-full lg:flex flex-col items-center justify-center px-4">
<div className="text-center space-y-4 pt-16">
<h1 className="font-bold text-3xl text-[#2E2A47]">
Welcome Back!
</h1>
<p className="text-base text-[#7E8CA0]">
Log in or Create account to get back to your dashboad!
</p>
</div>
<div className="flex items-center justify-center mt-8">
<ClerkLoaded>
<SignUp path="/sign-up" />
</ClerkLoaded>
<ClerkLoading>
<Loader2 className="animate-spin text-muted-foreground" />
</ClerkLoading>
</div>
</div>
<div className="h-full bg-blue-600 hidden lg:flex items-center justify-center">
<Image src="/vim-logo.svg" height={100} width={100} alt="Logo" />
</div>
</div>
)
}

请我喝杯咖啡吧~

支付宝
微信