Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2290220
chore(gitignore): add package-lock.json to ignore list
psyitama Aug 23, 2025
c79eb1f
chore: add React Email packages (@react-email/components, @react-emai…
psyitama Aug 24, 2025
2d3b662
chore(db): add migration for initial tables
psyitama Aug 24, 2025
5f1709b
fix(admin/login): remove JWT key check if not present
psyitama Aug 24, 2025
6000ecd
chore: ignore bun.lockb
psyitama Aug 24, 2025
aea010a
chore(package.json): add prisma key to run seed.ts
psyitama Aug 24, 2025
eec3779
feat(storefront/products): add search functionality
psyitama Aug 24, 2025
406efef
feat(storefront/products): add price filter functionality
psyitama Aug 24, 2025
4b2c6c5
chore(storefront): fix component UIs
psyitama Aug 24, 2025
d78b817
feat(storefront/products): add selecting categories functionality
psyitama Aug 24, 2025
d0daac5
feat(storefront/products): add selecting brand functionality
psyitama Aug 24, 2025
8421d1c
chore(storefront/products): reoder filters
psyitama Aug 24, 2025
7c83626
feat(storefront/products): update sorting to add title (A-Z), (Z-A) o…
psyitama Aug 24, 2025
db4a1a9
chore(storefront/products): make all filter inputs one line in LG
psyitama Aug 24, 2025
f387bbf
fix(chore/producs): fix filter button get overriden by others
psyitama Aug 24, 2025
35842fb
fix(storefront/products): fix some witdth issues
psyitama Aug 24, 2025
ec4de60
chore(admin/package.json): add react-day-picker
psyitama Aug 25, 2025
a85cf63
fix(admin/components): fix some outdated UIs
psyitama Aug 25, 2025
e9f426d
feat(admin/ui): add reusable Calendar component
psyitama Aug 25, 2025
495acca
feat(admin/reports/ui): add filter options component
psyitama Aug 25, 2025
4ba9cf7
feat(admin/reports/ui): add chart component
psyitama Aug 25, 2025
6e5c289
feat(admin/reports/ui): add table component
psyitama Aug 25, 2025
d377851
feat(admin/reports): add page and nav
psyitama Aug 25, 2025
46ed29b
chore: move some codes inside main function, remove console.log
psyitama Aug 25, 2025
c254ada
feat(admin/reports): add reports viewing via date picker functionality
psyitama Aug 25, 2025
d9d9062
feat(admin/reports): add reports filter through brand functionality
psyitama Aug 25, 2025
fa85c0c
feat(admin/reports): add reports filter through category/es functiona…
psyitama Aug 25, 2025
d193fb7
chore(admin/middleware): add admin path in config
psyitama Aug 25, 2025
f73fa20
chore(migration): add crossSellProducts and crossSellOff in Product t…
psyitama Aug 25, 2025
80afb05
chore(storefront/prisma): add seed file and script
psyitama Aug 25, 2025
8f03bc6
feat(storefront/product-details): add related products you may like view
psyitama Aug 25, 2025
1e8f7d9
feat(storefront/cart): add related products you may like view
psyitama Aug 25, 2025
c673cc4
fix(storefront/cart): wrong item was being removed from cart
psyitama Aug 25, 2025
01e0f2c
Update README.md
psyitama Aug 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 75 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ You can [read more about environment variables here](https://nextjs.org/docs/bas
Clone the repository.

```bash
git clone https://github.com/sesto-dev/next-prisma-tailwind-ecommerce
git clone https://github.com/psyitama/next-prisma-tailwind-ecommerce.git
```

Navigate to each folder in the `apps` folder and and set the variables.
Expand All @@ -75,7 +75,24 @@ Bring your database to life with pushing the database schema.
bun run db:push
```

```sh
Run the projects

Storefront

```bash
cd apps/storefront
```

```bash
bun run dev
```
Admin

```bash
cd apps/admin
```

```bash
bun run dev
```

Expand All @@ -91,12 +108,59 @@ This project exposes a package.json script for accessing prisma via `bun run db:

Make changes to your database by modifying `prisma/schema.prisma`.

## 🛸 How to Deploy the Project

Follow the deployment guides for [Vercel](https://create.t3.gg/en/deployment/vercel), [Netlify](https://create.t3.gg/en/deployment/netlify) and [Docker](https://create.t3.gg/en/deployment/docker) for more information.

## 📄 License

This project is MIT-licensed and is free to use and modify for your own projects. Check the [LICENSE](./LICENSE) file for details.

Created by [Amirhossein Mohammadi](https://github.com/sesto-dev).
## 1️⃣ Rebuild product filters on the storefront page
- Created `ProductSearchInput` with an `onChange` listener to search for products. Applied a debounce feature to prevent concurrent requests while the user has not finalized the keyword.
- Created `PriceInputFields` to filter the minimum and maximum price of the product list. Also created a corresponding button titled "Apply" to trigger the filtering.
- Noticed that the current `Categories` and `Brand` combo boxes are not fully functional. To fix this, I rewrote the UI component using the `Shadcn` documentation as reference.
- Added filter options to the `SortBy` filter to handle sorting of product titles in ascending and descending order.
- Updated the Prisma query to handle `search`, `minPrice`, `maxPrice`, `sort`, `isAvailable`, `brand`, and `category` search parameters.
- Ensured that the product data updates dynamically based on all selected filter options, without reloading the page.
- Commented out `AvailableToggle` as it was not included in part 1 of the assessment.

## 2️⃣ Build an admin reports page with charts or tables
- Tried checking the login and encountered a bug where the `JWT_SECRET_KEY` was being checked on the login page, which is the `UserAuthForm` component rendered on the client (CSR). Removed that line of code and retried logging in, which redirected me to the OTP verification.
- Checked the OTP verification and found out I needed to set up an SMTP account in Google. Used an App Password to fill `MAIL_SMTP_SERVICE`, `MAIL_SMTP_PASS`, and `MAIL_SMTP_USER`. After that, I created a row in the Owner table using my personal email address to receive the OTP code.
- Created a Reports Page by adding `admin/reports` folders in the `(dashboard)/(routes)` path.
- After creating the ReportsPage, I added the link `main-nav /admin/report`.
- Added `'/admin/:path*'` in the `middleware.ts` config to prevent unauthorized access for users without administrator capabilities.
- Also noticed the same issue in the Storefront where the `Categories` and `Brand` combo boxes are not fully functional. To fix it, I rewrote `command.tsx` using the updated version from `Shadcn`.
- **Reports Overview - Orders: Line Chart**
- Display the order count grouped by date for visualization that the admin can use in reports.
- Prisma: To fetch the needed data, I used the `Order` table, grouping by `createdAt` while counting the IDs.
- Displaying: Looped through the results and formatted the date as `'yyyy-MM-dd'` for the chart.
- **Reports Overview - Top Selling Products: Table**
- Display products with the highest sales first, or by order count. Products with no sales are not listed.
- Prisma: To fetch the needed data, I used the `Product` table including the `Order` table and counted the order IDs for the Sales number.
- Displaying: Looped through the results and formatted them according to the table’s requirements.
- Made sure that any changes in the `DateRangePicker`, `Brand`, and `Category` combo box filter options dynamically update the Report Overview Products and Order data without reloading the page.

## 3️⃣ Extend the Product model for cross-sell recommendations
- **3.1: Update Prisma DB Model to Support Cross-Sell Products**

- Updated the Prisma migration to handle cross-related products by adding the necessary fields to the Product table.

```prisma
crossSellProducts Product[] @relation("CrossSellRelation")
crossSellOf Product[] @relation("CrossSellRelation")
```
- Run the updated migration using the following command:
```bash
npx prisma migrate dev --name add_cross_sell_products
```
- Populated records by creating a `seed.ts` file and adding the script in `package.json`. This script seeds the database by linking existing products to their related cross-sell products using Prisma’s connect relation.
```package.json
"prisma": {
"seed": "tsx prisma/seed.ts"
}
```
- Started the populating of `crossSellProducts` by running this command.
```bash
npx prisma db seed
```
- **3.2: Enhance Frontend for Cross-Sell Products and Improved Cart
Feedback**
- I usually noticed on well-known e-commerce websites that related or cross-sell products are displayed at the bottom of the page.
- Implemented a toast notification after successfully adding a product to the cart using the `react-hot-toast` package.
- Created a `RelatedProducts` component to display the cross-related products of the selected product.
- Updated the Prisma query and used the `RelatedProducts` component to display the cross-related products below the Product Details and Cart page.
- While testing the adding/removing of quantity on the Cart page, I encountered and fixed a bug where, regardless of which product’s quantity was changed (first, second, or third), the last product in the list was always removed.
5 changes: 4 additions & 1 deletion apps/admin/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
/.next
/node_modules
/node_modules

package-lock.json
bun.lockb
Binary file removed apps/admin/bun.lockb
Binary file not shown.
12 changes: 10 additions & 2 deletions apps/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"@radix-ui/react-switch": "^1.1.1",
"@radix-ui/react-tabs": "^1.1.1",
"@radix-ui/react-toast": "^1.2.2",
"@react-email/components": "^0.5.1",
"@react-email/render": "^1.2.1",
"@tanstack/react-table": "^8.20.5",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
Expand All @@ -51,16 +53,19 @@
"next-themes": "^0.3.0",
"nodemailer": "^6.9.15",
"react": "18.3.1",
"react-day-picker": "^9.9.0",
"react-dom": "18.3.1",
"react-hook-form": "^7.53.0",
"react-hot-toast": "^2.4.1",
"recharts": "^2.13.0",
"ts-node": "^10.9.2",
"tsx": "^4.20.5",
"zod": "^3.23.8",
"zustand": "^4.5.5"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/node": "22.7.5",
"@types/node": "^24.3.0",
"@types/react": "18.3.11",
"@types/react-dom": "18.3.1",
"autoprefixer": "10.4.20",
Expand All @@ -73,6 +78,9 @@
"tailwind-merge": "^2.5.3",
"tailwindcss": "3.4.13",
"tailwindcss-animate": "^1.0.7",
"typescript": "5.6.3"
"typescript": "^5.9.2"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
}
}
Loading