The gorgeous frontend interface of the ServiceHub local-service-booking marketplace.
Because finding a trustworthy plumber shouldn't be harder than fixing the pipe yourself! 🛠️
Why read documentation when you can just click things? Test drive the platform!
- 🌍 Live Website: Click Here to be Amazed
- 💻 Frontend Repo: ServiceHub-client
- 🗄️ Backend Repo: ServiceHub-server
🔑 Magic Keys (Demo Customer)
Email:-customer@gmail.com
Password:-Customer@123
We didn't just build a CRUD app; we built an experience. Here are the core modules that make ServiceHub shine:
🎭 Triple-Role Architecture (Guest, Customer, Provider, Admin)
The platform intelligently adapts its UI based on who is logged in. Providers get powerful service management and scheduling tools, customers get streamlined booking and history tracking, and admins get an eagle-eye view of the entire platform's cash flow and user activity.
⚡ Real-Time Booking Engine
Nobody likes mashing F5. When a customer requests a booking, the provider gets a real-time notification. When the provider accepts, the customer's dashboard updates instantly. It feels alive.
💳 Seamless Stripe Integration
Frictionless payment flows. We handle Stripe Elements natively so users never feel like they are leaving the platform when they hand over their hard-earned cash.
🌓 True Dynamic Theming
Not just "invert the colors." We built a robust, Material-3-inspired custom DaisyUI theme that perfectly balances contrast, primary (Indigo), secondary (Amber), and tertiary (Emerald) hues across both Light and Dark modes.
Building this wasn't all sunshine and rainbows. Here are the complex issues we encountered and how we engineered our way out of them:
🛑 The Problem: State Synchronization Chaos With multiple users interacting simultaneously, how do we ensure a user doesn't double-book a time slot or view stale data?
✅ The Solution: The React Query + Pusher Wombo-Combo We strictly separated "Client State" from "Server State". We use Zustand strictly for UI state (is a modal open? what theme is active?). For data, we use React Query. We wired Pusher JS WebSockets directly into React Query's cache. When a Pusher event arrives (e.g.,
booking-updated), we don't manually mutate state—we simply invalidate the specific React Query key, forcing a lightning-fast background refetch that updates the UI seamlessly without a full page reload.
🛑 The Problem: Form Re-render Hell Forms with multiple image uploads, nested complex validation, and rich text were causing the app to crawl during keystrokes.
✅ The Solution: Uncontrolled Zod Forms We bypassed standard React controlled inputs by utilizing React Hook Form paired with Zod resolvers. Inputs remain uncontrolled until submission or validation, dropping re-renders by over 80%. We achieved strict type-safety from the schema down to the input props.
| Category | Weapon of Choice | Why we chose it |
|---|---|---|
| Framework | Next.js 16.2 | Because we love App Router and face-melting SSR speed. 🏎️ |
| Language | TypeScript | To catch our typos before production does. 🐛 |
| Styling | Tailwind CSS v4 & DaisyUI | Utility-first flexbox wizardry. 🧙♂️ |
| State / Data | React Query & Zustand | Server state & client state holding hands peacefully. 🤝 |
| Forms / Val. | React Hook Form & Zod | Uncontrolled inputs + flawless validation schemas. 🛡️ |
| Auth | Better Auth | Because rolling your own auth is a certified trap. 🪤 |
| Charts | Recharts | Making data look sexy for the C-Suite (Admins). 📈 |
| Realtime | Pusher JS | "Ping!" - Instant WebSocket magic. 🪄 |
flowchart TD
Browser["Client Browser"] --> Next["Next.js App Router"]
Next -->|"API Requests"| Express["Express Server API"]
Express --> MongoDB[("MongoDB")]
Express --> BetterAuth["Better Auth"]
Express -.-> Pusher["Pusher Realtime"]
Next -.-> Pusher
🗺️ Unroll the map of src/
src/
├── app/ # 🚦 Next.js App Router pages (the real MVPs, grouped by (admin), (auth), etc.)
├── components/ # 🧩 Reusable UI LEGO blocks
├── data/ # 🗃️ Constants, mock data, and static configs
├── hooks/ # 🪝 Custom React hooks keeping logic DRY
├── lib/ # 🛠️ Utility functions, fetch wrappers (the duct tape)
├── store/ # 📦 Zustand state slices
└── types/ # 🏷️ TypeScript definitions ensuring we play by the rules
⚙️ Step-by-Step Installation
-
Clone it (make it yours):
git clone https://github.com/Md-Nur-A-Alam/ServiceHub-client.git cd service-hub-client -
Install the magic dependencies:
npm install
-
Environment Variables (The Secret Sauce): Copy
.env.exampleto.env.localand feed it:Variable Example What is it? MONGODB_URImongodb://localhost:27017/ServiceHubWhere the data sleeps BETTER_AUTH_SECRETyoursecretkeyhereShhh 🤫 SERVER_URLhttp://localhost:8000The backend NEXT_PUBLIC_SERVER_URLhttp://localhost:8000What the browser sees -
Fire it up! (Make sure your backend is running too!)
npm run dev
Boom. You're live at
http://localhost:3000.
Distributed under the ISC License. Because sharing is caring.






