Nexjs Acme Dashboard ‐ Matdweb - Matdweb/nextjs-acme-dashboard GitHub Wiki

📌 Nexjs Acme Dashboard

📝 Project Overview

What is it?
A banking dashboard that manages revenues, balances, invoices and more.

What problem does it solve?
This dashboard app helps users have a secure, intuitive and optimized experience while managin their money.

Tech Stack

  • Frontend: Next.js, React, TailwindCSS, TypeScript, zod.
  • Backend: TypeScript, Next.js API Routes.
  • Database: PostgreSQL
  • Authentication: NextAuth.js
  • Deployment: Vercel

📂 Project Structure

├── nextjs-acme-dashboard/
    |   .eslintrc.json
    |   .gitignore
    |   auth.config.ts
    |   auth.ts
    |   favicon.ico
    |   middleware.ts
    |   next.config.ts
    |   opengraph-image.png
    |   package-lock.json
    |   package.json
    |   postcss.config.js
    |   README.md
    |   tailwind.config.ts
    |   tsconfig.json
    |   
    ├── app/
    |   |   layout.tsx
    |   |   page.tsx
    |   |   
    |   ├── dashboard/
    |   |   |   layout.tsx
    |   |   |   
    |   |   ├── (overview)/
    |   |   |       loading.tsx
    |   |   |       page.tsx
    |   |   |       
    |   |   ├── customers/
    |   |   |       page.tsx
    |   |   |       
    |   |   ├── invoices/
    |   |       |   error.tsx
    |   |       |   page.tsx
    |   |       |   
    |   |       ├── create/
    |   |       |       page.tsx
    |   |       |       
    |   |       ├── [id]/
    |   |           ├── edit/
    |   |                   not-found.tsx
    |   |                   page.tsx
    |   |                   
    |   ├── lib/
    |   |       actions.ts
    |   |       data.ts
    |   |       definitions.ts
    |   |       placeholder-data.ts
    |   |       utils.ts
    |   |       
    |   ├── login/
    |   |       page.tsx
    |   |       
    |   ├── query/
    |   |       route.ts
    |   |       
    |   ├── ui/
    |       |   acme-logo.tsx
    |       |   button.tsx
    |       |   fonts.ts
    |       |   global.css
    |       |   login-form.tsx
    |       |   search.tsx
    |       |   skeletons.tsx
    |       |   
    |       ├── customers/
    |       |       table.tsx
    |       |       
    |       ├── dashboard/
    |       |       cards.tsx
    |       |       latest-invoices.tsx
    |       |       nav-links.tsx
    |       |       revenue-chart.tsx
    |       |       sidenav.tsx
    |       |       
    |       ├── invoices/
    |               breadcrumbs.tsx
    |               buttons.tsx
    |               create-form.tsx
    |               edit-form.tsx
    |               pagination.tsx
    |               status.tsx
    |               table.tsx
    |               
    ├── public/                          # staic hero section images 
        ├── customers/                   # static profile images

🔑 Authentication Flow

User data is passed with a useActionState() on a Form submit event as formData. Then, this data is passed to a server action stored in lib/actions.ts where the same data is again passed to signIn() NextAuth function. This function is costumized and in this case, it checks data types with zod and queries the data base to see if the user exists; if it does, then it returns the user and therefor stores it, otherwise it returns null.

image

Route protection

The middleware will always be enabled for the routes that fullfill this regex match: '/((?!api|_next/static|_next/image|.*\\.png$).*)'. And the same one checks if the user is authenticated and if the route starts with '/dashboard', otherwise it will redirect to Login.

image


🚀 Server Queries

This module provides database query functions for handling revenue, invoices, customers, and dashboard data in a Next.js application using @vercel/postgres.

📌 Features

  • Revenue Queries: Fetch total revenue data.
  • Invoice Queries: Retrieve latest invoices, filter invoices, and fetch by ID.
  • Customer Queries: Fetch all customers and filter by name/email.
  • Dashboard Stats: Fetch invoice count, customer count, and payment statuses.

📂 Available Queries

🔹 fetchRevenue()

Retrieves total revenue records with a simulated delay for demo purposes.

🔹 fetchLatestInvoices()

Fetches the 5 most recent invoices, including customer details.

🔹 fetchCardData()

Aggregates invoice count, customer count, and payment status summaries.

🔹 fetchFilteredInvoices(query, currentPage)

Fetches invoices matching a search query, paginated with 6 items per page.

🔹 fetchInvoicesPages(query)

Determines the total number of pages for paginated invoice results.

🔹 fetchInvoiceById(id)

Retrieves a single invoice by its ID, converting amounts to dollars.

🔹 fetchCustomers()

Fetches all customers, ordered alphabetically.

🔹 fetchFilteredCustomers(query)

Fetches customers matching a search query, including total invoices and payment details.


⚡ Server Actions

This module defines server-side actions for handling invoices and authentication in a Next.js application using @vercel/postgres.

📌 Features

  • Invoice Management: Create, update, and delete invoices.
  • Form Validation: Uses zod for schema validation.
  • Authentication: Handles user sign-in with error handling.
  • Cache Revalidation: Ensures up-to-date invoice data after modifications.

📂 Available Actions

🔹 createInvoice(prevStatus, formData)

  • Validates form data using zod.
  • Inserts a new invoice into the database.
  • Redirects to /dashboard/invoices.

🔹 updateInvoice(id, prevStatus, formData)

  • Validates and updates an existing invoice.
  • Handles error messages and logs database issues.
  • Revalidates and redirects after an update.

🔹 deleteInvoice(id)

  • Deletes an invoice by ID from the database.
  • Triggers cache revalidation to reflect changes.

🔹 authenticate(prevState, formData)

  • Uses signIn from next-auth to authenticate users.

🛢 Database Schema

This document defines the TypeScript types representing the database schema.
These types describe the shape of the data and the expected data types for each field.

export type User = {
  id: string;
  name: string;
  email: string;
  password: string;
};
export type Customer = {
  id: string;
  name: string;
  email: string;
  image_url: string;
};
export type Invoice = {
  id: string;
  customer_id: string;
  amount: number;
  date: string;
  status: 'pending' | 'paid';
};
export type Revenue = {
  month: string;
  revenue: number;
};
export type LatestInvoice = {
  id: string;
  name: string;
  image_url: string;
  email: string;
  amount: string;
};
export type LatestInvoiceRaw = Omit<LatestInvoice, 'amount'> & {
  amount: number;
};
export type InvoicesTable = {
  id: string;
  customer_id: string;
  name: string;
  email: string;
  image_url: string;
  date: string;
  amount: number;
  status: 'pending' | 'paid';
};
export type CustomersTableType = {
  id: string;
  name: string;
  email: string;
  image_url: string;
  total_invoices: number;
  total_pending: number;
  total_paid: number;
};
export type FormattedCustomersTable = {
  id: string;
  name: string;
  email: string;
  image_url: string;
  total_invoices: number;
  total_pending: string;
  total_paid: string;
};
export type CustomerField = {
  id: string;
  name: string;
};
export type InvoiceForm = {
  id: string;
  customer_id: string;
  amount: number;
  status: 'pending' | 'paid';
};

⚛️ State Management & UI Flow

This projects works with a client and server flow. API calls, when performed, are done in the background with a auitomatic POST action thanks to server actions, learn more here server actions and mutations | Next.js Docs

/dashboard

image

image

image

image

/Invoices

image


🛠 Business Rules


🚀 How to Run the Project

Prerequisites

  • Install Node.js and npm.
  • Set up a PostgreSQL database.
  • Run npm run dev in the project

Installation

git clone https://github.com/your-username/your-project.git
npm install

Environment Variables

Create a .env file in the root directory:

DATABASE_URL=postgres://your_url
DATABASE_URL_UNPOOLED=postgresql://your_unpooled_db_url

#data provided by vercel for neo-postgres
PGHOST=
PGHOST_UNPOOLED=
PGUSER=
PGDATABASE=
PGPASSWORD=
POSTGRES_URL=
POSTGRES_URL_NON_POOLING=
POSTGRES_USER=
POSTGRES_HOST=
POSTGRES_PASSWORD=
POSTGRES_DATABASE=
POSTGRES_URL_NO_SSL=
POSTGRES_PRISMA_URL=

AUTH_SECRET=your_64_bits_string

Running the Project

npm run dev  # Start development server

✅ TODO

  • Customers
  • Documentation additions

📜 License

MIT