Getting Started with React, Prisma and NextJs
While not a web developer by trade, I like to periodically try out new frameworks and technologies, plus the trend toward multi-platform applications (e.g. Electron-based) that use web technologies under the hood is hard to ignore.
This article documents my journey with React + Prisma + NextJs.
Project Overview
The goal of this project is a tool for project estimation and quotes for large, multi-discipline, multi-team projects. Most places I've worked have used elaborate Excel spreadsheets and feel there might be a low-cost roll-our-own middle-ground, so this project is intended to demonstrate the concept. On a side note, there are various open-source tools available for software estimation, construction estimate and project management, but doesn't exactly cover hardware / software projects nicely.
Source: https://github.com/ericjameszimmerman/estimatey
Getting started and basic authentication
Largely, I followed along with a basic tutorial for creating the project, building and running it.
I created a tag and release here with the source contained within this section:
https://github.com/ericjameszimmerman/estimatey/releases/tag/v0.1.0
Key Commands
Largely I'm documenting these since I'm likely to forget when switching to other topics.
Build and Run
npm run dev
This builds and runs on localhost:3000, similar to other reactive frameworks.
Prisma Database Migration
npx prisma migrate dev
This connects to the database and modifies the tables according to the current updated models. If it is unable to create a migration file it will let you know. For early development, you can simply purge old tables or data if needed.
Prisma Studio Database Editor
npx prisma studio
Prisma provides a little database editor similar to old MySQL connector or similar tools you may have used in the past.
Milestone 1 - Basic Authentication
The present UI is essentially the same as the tutorial
The "Sign in" page uses the default UI from next-auth. We'll look at adapting that later, but good enough for now.
To test that it did indeed work, I added debug code within the api
GET request
If the credentials were invalid, it shows the following:
Milestone 2: Demo CRUD and Rough UI design
This iteration adds functionality to create a project record to the database and view it.
The majority of the following screens are static content that was pillaged from examples but meant to get a feel for the desired functionality.
Takeaways:
It took me a little while to get used to, but for api and page structure, I appreciate the react / nextjs approach with folders representing wildcards or ids (e.g.
app/api/projects/[id]/route.ts
contains the GET request content specific to a specific project id. Similarly,app/projects/[projectid]/page.tsx
defines the view displayed when viewing a specific project andapp/projects/create/page.tsx
defines the project creation view.These frameworks allow freedom to organize files and folders mostly how you please; the trade-off is that it can be difficult to go from a super simple example into something larger and will need to scale.
The
shadcn/ui
examples are pretty nice. I've been using it as a starting point and adapting it to my application.
Demo UI
Here is the super basic form for creating a project.
The following is the UI for the project page. Except for the project name and description, the content is all fake, but imagine that aggregation and a heatmap of the project estimate contents might make up the overview section.
The tab bar is functional and the following shows a data grid, which is likely useful for the top-level list of estimate line items. It is intended that the top-level items may be simple static estimates for some, while others are comprised of another collection of elements, in a hierarchical nature. The item may also be set as a specific type, allowing a software line item to perhaps use points while other categories use different estimation approaches.
Side-note on implementation: it took me a little while to figure out how to fit the data grid into the remaining parent space but scroll. The keys were:
change the div containing the tabs from
h-full
toh-[calc(100vh-74px)]
to account for header space.change the top div within
data-table.tsx
# From <div className="space-y-4"> # to <div className="flex flex-col h-full">
change the div within
src/registry/new-york/ui/table.tsx
from the examples# From <div className="relative w-full max-h-[400px] overflow-y-scroll"> # to <div className="relative w-full table-container h-[calc(100vh-250px)]">
The following was added to globals.css
.table-container { border-radius: 20px; padding: 0 10px 10px 10px; overflow: scroll; } .table-header { position: sticky; top: 0px; margin: 0 0 0 0; }
To force the header row to stick to the top, changed the TableHeader
within src/registry/new-york/ui/table.tsx
:
# From
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
# to
<thead ref={ref} className={cn("[&_tr]:border-b table-header", className)} {...props} />
References
The following are references that I used when first learning.
Build a Complete SaaS Platform with Next.js 13, React, Prisma, tRPC, Tailwind | Full Course 2023
- This was a really good tutorial. I liked his approach and styling.
Set up Next-Auth with Next.js and Prisma with this ultimate guide!
- For my purpose, I didn't want to use OAuth or other credential providers out of the box. Next-auth seemed a little more straight forward for the basic credentials.