Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
wildky
left a comment
There was a problem hiding this comment.
Inline comments to highlight noteworthy bits of code!
| @@ -0,0 +1,3 @@ | |||
| { | |||
| "extends": ["next/core-web-vitals", "prettier"] | |||
There was a problem hiding this comment.
This small change allows you to use prettier with nextjs pre-configured eslinting
| "singleQuote": true, | ||
| "printWidth": 100, | ||
| "tabWidth": 2, | ||
| "plugins": ["prettier-plugin-organize-imports"] |
There was a problem hiding this comment.
I use this prettier plugin with all of my projects - it keeps files nice and tidy
| "private": true, | ||
| "scripts": { | ||
| "dev": "next dev", | ||
| "build": "prisma generate && prisma migrate deploy && next build", |
There was a problem hiding this comment.
Running prisma generate and prisma migrate deploy keeps the prisma client and database schema up to date.
In a production application with a more complex dev cycle, you may not want to include prisma migrate deploy as part of the build process, but I find it works well when just starting small projects.
| updatedAt DateTime @updatedAt | ||
| authorId String | ||
|
|
||
| @@index([authorId]) |
There was a problem hiding this comment.
Since Clerk is being used to manage our users, we don't need a User table in our database. However, we still want to query items based on their relationship to the user, so we should add an index on the relationship keys to make sure these queries remain performant.
| import { getCurrentAuthUser } from '@/lib/models/user' | ||
| import { revalidatePath } from 'next/cache' | ||
|
|
||
| export const addItemAction = async (formData: FormData): Promise<void> => { |
There was a problem hiding this comment.
We can put all of our server actions here. If we create many of them, we may want to break them down into finer categories (similar to how the /lib/models directory is organized)
| @@ -0,0 +1,9 @@ | |||
| export const pluralize = (count: number, singular: string, plural: string): string => { | |||
There was a problem hiding this comment.
A little utility function for pluralizing a word in UI that I use in all of my projects
| return count === 1 ? singular : plural | ||
| } | ||
|
|
||
| export const formatErrorMessage = (error: unknown) => { |
There was a problem hiding this comment.
A little utility function for rendering error message in the UI so you don't need to write this logic again and again when we are checking errors returned from the server.
| @@ -0,0 +1,16 @@ | |||
| import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' | |||
|
|
|||
| const isProtectedRoute = createRouteMatcher(['/dashboard(.*)']) | |||
There was a problem hiding this comment.
Basically, any route that starts with /dashboard will require user to be authenticated, and if they are not, it will automatically re-route them to the sign in page
| import { Roboto } from 'next/font/google' | ||
|
|
||
| const roboto = Roboto({ | ||
| weight: ['300', '400', '500', '700'], | ||
| subsets: ['latin'], | ||
| display: 'swap', | ||
| }) | ||
|
|
||
| let theme = createTheme({ | ||
| typography: { | ||
| fontFamily: roboto.style.fontFamily, | ||
| }, | ||
| }) |
There was a problem hiding this comment.
Demo using next/font with MUI theme
| components: { | ||
| MuiDialogActions: { | ||
| styleOverrides: { | ||
| root: { | ||
| paddingLeft: theme.spacing(3), | ||
| paddingRight: theme.spacing(3), | ||
| paddingBottom: theme.spacing(3), | ||
| }, | ||
| }, | ||
| }, | ||
| MuiButton: { | ||
| styleOverrides: { | ||
| root: { | ||
| textTransform: 'none', | ||
| fontWeight: 700, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }) |
There was a problem hiding this comment.
A few style overrides to make the design look more elegant
This is a simple NextJS full stack app demo using the app router, illustrating some best practices and integrations with helpful tools, including Prisma, MUI, and Clerk.
Live demo: https://list-app-nine.vercel.app/
This PR reviews the entire code base so I can highlight noteworthy decisions and bits of code across the entire demo application. Enjoy!
Some things covered here:
use clientdirective, etc.)/src/lib/models) separated from things like UI form parsing and cache revalidation (src/app/actions.ts)layout, theming)layout, protected routes, getting authenticated user data and using it for authorization checks, using built in components, etc.)