Our great sponsors
-
zenstack
Typescript toolkit on top of Prisma ORM, offering flexible and declarative Access Control Policy(Authorization/Permission) for RBAC/ABAC/PBAC/ReBAC with auto-generated type-safe APIs and frontend hooks.
-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
-
Prisma
Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB
-
InfluxDB
Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.
-
daisyui
๐ผ ๐ผ ๐ผ ๐ผ ๐ผ โThe most popular, free and open-source Tailwind CSS component library
Congratulations on finishing this long journey! ZenStack is an open-source project in its infant stage. If you think it's useful, let's raise it together. Let us know your thought on Twitter, Discord, GitHub, or whatever you like.
https://zenstack-nextjs-todo-demo.vercel.app (source)
npx create-next-app todo --use-npm -e https://github.com/zenstackhq/nextjs-auth-postgres-template
This part is what an ORM provides. Internally, it would be converted into the Prisma schema. Now it is fully compatible with Prisma schema. So to get the complete list of what you can use, please take a reference with the Prisma schema document.
We choose to daisyUI component with TailWindCSS utility. We will create a Navigation bar for it. As it's pure front-end Layout work, we will not dive into the detail in this tutorial.
If you don't have a Postgres database, the simple way to get one is to get a docker instance or a free one from Supabase.
import Image from "next/image"; import { List, User } from "@zenstackhq/runtime/types"; import { customAlphabet } from "nanoid"; import { LockClosedIcon, TrashIcon } from "@heroicons/react/24/outline"; import Avatar from "./Avatar"; import Link from "next/link"; import { useRouter } from "next/router"; import { useList } from "@zenstackhq/runtime/hooks"; import TimeInfo from "./TimeInfo"; type Props = { value: List & { owner: User }; deleted?: (value: List) => void; }; export default function TodoList({ value, deleted }: Props) { const router = useRouter(); const { del } = useList(); const deleteList = async () => { if (confirm("Are you sure to delete this list?")) { try { await del(value.id); } catch (error: any) { if (error.status == 403) { alert("You are not allowed to do so"); } } if (deleted) { deleted(value); } } }; return ( className="card w-80 bg-base-100 shadow-xl cursor-pointer hover:bg-gray-50"> src={`https://picsum.photos/300/200?r=${value.id}`} width={320} height={200} alt="Cover" /> className="card-body"> href={`${router.asPath}/${value.id}`}> className="card-title line-clamp-1">{value.title || "Missing Title"} className="card-actions flex w-full justify-between"> value={value} /> className="flex space-x-2"> user={value.owner} size={18} /> {value.private && ( className="tooltip" data-tip="Private"> className="w-4 h-4 text-gray-500" /> )} className="w-4 h-4 text-gray-500 cursor-pointer" onClick={() => { deleteList(); }} /> ); }
Almost every modern application has authentication now, which the access policy is based on as the auth() function you have seen. To simplify the task, ZenStack has integrated with the open source authentication library NextAuth, which we will use in this demo.
We choose to daisyUI component with TailWindCSS utility. We will create a Navigation bar for it. As it's pure front-end Layout work, we will not dive into the detail in this tutorial.
We also replace the default login page with a custom one implemented using Chakra UI components. Again, you can look at how to do that from the official NextAuth document.