-
Notifications
You must be signed in to change notification settings - Fork 1
Sales Management Dashboard ‐ Documentation
The application is a sales management dashboard built with Next.js 15 using the App Router.
The app relies on a PostgreSQL database, hosted on Vercel, using Kysely as the ORM for database management and queries. NextAuth.js handles user authentication, shadcn/ui provides the component library, and Tailwind CSS is used for styling. The project is deployed on Vercel.
The following routes are included:
-
/sign-in
: User sign-in page. -
/sign-up
: User sign-up page. -
/dashboard
: Displays total sales summaries, top sellers, and a chart showing monthly sales from the previous year. -
/dashboard/invoices
: Shows a table with all invoices, optimized for over 1,000 entries. -
/dashboard/sellers
: Lists all sellers in a table view. -
/seed
: Resets the database by recreating table structures and seeding new test data.
The main folders in the project structure are:
-
Root Folder:
-
__tests__
: Unit tests. -
cypress
: E2E tests. -
public
: Public assets. -
src
: Application logic and source code.
-
-
Inside
src
Folder:-
src/app
: Defines the routing structure, and layouts. -
src/components
: All application components. -
src/components/ui
: For UI components. -
src/hooks
: Custom hooks. -
src/lib
: Server actions, database access functions, and utilities. -
src/schemas
: Zod schemas for validation. -
src/types
: Type definitions.
-
This project primarily uses SSR for all components, limiting client components to essential cases. Server actions are used for server data access from client components, a recommended practice in recent Next.js versions with App Router, as it enables direct access to server data without setting up specific API routes (though it functions similarly under the hood).
For authentication, the project uses NextAuth.js v5 configured with the Credentials provider. The configuration is set up across two separate files for clarity and modularity, following NextAuth's recommendations:
-
/src/auth.config.ts
defines the basic configuration, including a middleware to protect routes. -
/src/auth.ts
imports this configuration and defines the Credentials provider setup, as well as utility functions for sign-in and sign-out logic. This file includes the sign-in logic. -
signInAction
andsignUpAction
server actions are defined in/src/lib/auth-actions.ts
and are used in components for authentication handling.
I chose shadcn/ui as a UI components library over building components from scratch because it closely aligns with a professional setup—using components that are both highly accessible and well-tested. Shadcn/ui provides components through a CLI that adds the source code right into the project. This setup gives me complete control to customize the components however I need, both in terms of functionality and design.
Using shadcn/ui has also sped up the development of this project, letting me focus on other key details and be more productive overall.
Lastly, it’s worth noting that in Tailwind CSS 3, Just-In-Time (JIT) mode is enabled by default.
The database schema includes the following tables:
-
User Table: Stores user
id
,name
,email
, andpassword
. -
Seller Table: Stores seller
id
,name
,email
, andavatar
. -
Invoice Table: Stores invoice
id
,status
,amount
,paymentMethod
,sellerId
, andcreatedAt
.
A theme-toggle component (theme-toggle.tsx
) is accessible from all pages, allowing users to switch between light, dark, or system themes. This functionality is managed by a theme-provider.tsx
component using the next-themes library, which handles the theme state.
The custom hook useScrollPagination
(located in src/hooks/useScrollPagination.tsx
) manages fetching additional data as the user scrolls through a list, such as in a table. This hook leverages the Intersection Observer API to detect scrolling activity and automatically load more data as needed. It’s used in the invoices-table.tsx
and sellers-table.tsx
components, which can be seen in action on the /dashboard/invoices
and /dashboard/sellers
routes.
The useScrollPagination
hook is designed for efficient data fetching when scrolling:
-
Parameters:
-
fetchDataAction
: The async function for fetching data. -
initialData
: Initial dataset. -
limit
: Number of records to fetch at a time. -
refToObserve
: Reference to the DOM element triggering additional data loading.
-
-
State Management:
-
data
: Holds all fetched data. -
offset
: Tracks the current offset. -
hasMoreData
: Tracks if there’s more data to fetch.
-
-
Intersection Observer:
- Observes
refToObserve
. When it intersects,handleIntersection
is triggered to load more data.
- Observes
To optimize the application, the following strategies are applied:
- SSR: Used on almost all components, except where client components are strictly necessary.
-
Prefetching:
Link
components from Next.js are used, which support prefetching to reduce loading times. More info: Next.js Link Documentation. - Lighthouse Testing: The application scores 99 for performance, accessibility, best practices, and SEO in Google Lighthouse, specifically on mobile.
Production Testing was completed using the deployed version at: a-safe-technical-test-roan.vercel.app
Due to Cypress not yet supporting component tests in Next.js 14 or higher (see warning), I have opted to use Jest for component tests and Cypress for end-to-end (E2E) tests.
-
Jest is used for component testing, with tests stored in the
__tests__
folder at the project root. -
Cypress is used for E2E testing, located in the
cypress
folder.
-
To run the tests, use the following commands:
Unit tests:
pnpm run test
E2E tests:
pnpm run build && pnpm run start // In a new terminal, open Cypress: pnpm run cypress:open
-
Ensure Node.js (version 18.18 or above) and pnpm are installed on your system.
- If not installed, download Node.js from nodejs.org and install pnpm globally using:
npm install -g pnpm
- If not installed, download Node.js from nodejs.org and install pnpm globally using:
-
Clone the repository:
git clone https://github.com/MarioMS90/sales-management-dashboard
-
Install project dependencies:
pnpm install
-
Create a project and a PostgreSQL database on Vercel:
Add the necessary keys to a .env.local file in the root of the project to set up the environment variables.
-
Initialize the database structure and seed data:
Visit http://localhost:3000/seed to create the database tables and populate them with sample data.
-
Start the local development server:
pnpm run dev
Default user for login:
-
Email:
[email protected]
-
Password:
123456
-
Email:
-
To run the tests, use the following commands:
Unit tests:
pnpm run test
E2E tests:
pnpm run build && pnpm run start // In a new terminal, open Cypress: pnpm run cypress:open