Product Dashboard & Cart
A product catalogue and shopping cart on ASP.NET Core MVC and MySQL, with two front ends — Razor with jQuery, and React with TypeScript — reading the same API.
What it is
A full-stack technical assessment, built alone in August 2025. It is a restaurant-menu style catalogue (“Golden Fork”) with paginated browsing, search, category filtering, a product detail view and a guest shopping cart.
The problem
The brief asked for a responsive product dashboard on an MVC structure, using jQuery for interaction: list with pagination, real-time search, category filtering, a cart with quantities and totals, and reusable client-side code. I added a second, React-based front end to test whether the same backend could serve both styles of UI cleanly.
How it fits together
-
01
MySQL
Products, categories and cart items. Schema owned by EF Core migrations; seeded with SQL on start-up.
-
02
EF Core
Pomelo MySQL provider with connection retry, behind a ProductService that owns filtering, ordering and paging.
-
03
Controllers
MVC controllers return Razor partials for the server-rendered UI; API controllers return JSON, documented with Swagger.
-
04
Razor + jQuery
Primary UI. Partial views swapped in over AJAX, so filtering and paging never reload the page.
-
05
React + TS
Alternative SPA on Vite, using TanStack Query and Axios against the same /api endpoints.
My role
Sole author — schema, migrations and seed data, service layer, MVC and API controllers, both front ends, and the written technical documentation with ERD.
Decisions that mattered
- One backend, two front ends. Rather than duplicating logic for the React view, filtering and paging live in one service used by both the MVC controllers (returning partial views) and the API controllers (returning JSON). Each UI is a thin consumer of the same rules.
- Paging that does not skip rows. Seeded products shared creation timestamps, so ordering by date alone was not deterministic — items could repeat or vanish between pages. Ordering by CreatedDate and then by Id gives every row a stable position, which is what OFFSET-style paging needs.
- A cart without accounts. The brief had no authentication, so the cart is held in server-side session state and serialised as JSON. Guests get a working cart across requests without a login flow that nobody asked for.
- Reusable client code, not page scripts. Client behaviour is split into small classes — an AJAX helper with request timeouts via AbortController, a modal helper and a cart manager — plus debounce and throttle utilities for search and scroll.
The running application
What is not finished
The Razor UI is complete against the brief. The React UI fetches and filters products but its cart page was not finished within the assessment window — the documentation says so too.
Built with
- C#
- ASP.NET Core MVC (.NET 9)
- Entity Framework Core
- MySQL
- Razor
- jQuery
- Bootstrap
- Swagger
- React
- TypeScript
- Vite
- TanStack Query
- Axios
- Tailwind CSS