Skip to content

Developement-Practice/ragas-ai-assignment

Repository files navigation

CarePlane — B2B Healthcare Operations Console

A production-grade frontend for a B2B healthcare SaaS, built for the Ragas AI frontend assignment. Demonstrates auth, multi-page architecture, a patient-management module with grid/list views, an analytics dashboard, and service-worker-driven notifications.

Live demo: https://careplane-ragas-demo.netlify.app
Repo: https://github.com/Developement-Practice/ragas-ai-assignment
PR: #1


Demo credentials

The login screen offers three paths:

Method Status How to use
Continue as demo user ✅ Always works (no Firebase round-trip) One click on the login screen
Email / password ✅ Live Demo credentials shared in the PR description / submission form
Continue with Google ✅ Live Any Google account

All three are wired against Firebase project redux-http-7f91b. The demo user is held in localStorage, so signing out fully clears state.

Demo email/password credentials are intentionally kept out of the README and live only in the PR description / submission form to avoid them being indexed by code search.


Stack

Layer Choice Why
Framework Next.js 16 (App Router) + React 19 File-based routing, RSC, dynamic imports for chart code-splitting
Language TypeScript (strict) End-to-end type safety from RTK Query → views
State Redux Toolkit + RTK Query Scalable for multi-module SaaS; built-in caching, dedup, refetch
Styling Tailwind CSS v4 + shadcn/ui (Base UI primitives) Accessible primitives, consistent design tokens, dark mode built in
Forms React Hook Form + Zod Type-inferred validation, minimal re-renders
Charts Recharts Composable, themeable, dynamically imported on the analytics route
Auth Firebase Authentication Email/password + Google OAuth
Mock API MSW (Mock Service Worker) Realistic REST simulation without standing up a backend
Notifications Service Worker + Notifications API Local push notifications, no FCM dependency
Toasts sonner Lightweight, accessible
Deploy Netlify (@netlify/plugin-nextjs) Auto-deploy on push, preview deploys per PR

Features

Required by assignment

  • Authentication — Firebase Email/Password + Google sign-in, session persistence (IndexedDB), validated form, friendly error mapping, demo-mode fallback so reviewers don't need Firebase to evaluate.
  • Pages/login, /dashboard, /analytics, /patients, /patients/[id], /settings/notifications.
  • Patient module — searchable, filterable patient roster with grid ↔ list toggle (persisted to localStorage via Redux), pagination, click-through detail page with Overview / Visits / Labs / Notes tabs. Skeleton loaders, empty states, error states.
  • Service-worker notifications — own SW at /sw.js (scoped narrowly to coexist with MSW's worker), three demo triggers: appointment reminder · critical-patient alert · lab results ready. Permission-gated, persisted preferences, in-app history dropdown synced with system notifications.
  • State management — Redux Toolkit with three slices (auth, patientsView, notifications) and two RTK Query APIs (patientsApi, analyticsApi).

Stretch / bonus

  • Reusable component design + clean folder structure — feature-based foldering, shared UI primitives, shared KpiCard, ChartCard, EmptyState, PageHeader, StatusPill.
  • Dark modenext-themes, system-aware, toggle in topbar, theme-aware chart palettes.
  • Accessibility baseline — semantic landmarks, skip-to-content link, aria-labels on icon buttons, aria-current on active nav, aria-live on pagination, full keyboard navigation, focus-visible rings.
  • Performance — dynamic import() of Recharts on analytics route, RTK Query response caching, debounced search input, next/font self-hosted Inter, server-rendered shell with client-side data fetching.

Folder structure

src/
  app/                            # Next.js App Router
    (auth)/login/                 # Public login route
    (app)/                        # Auth-gated app shell
      dashboard/
      patients/        [id]/
      analytics/
      settings/notifications/
    layout.tsx, providers.tsx     # Root + Redux/Theme/MSW/Auth bootstrap
  features/
    auth/                         # Firebase init, slice, listener, AuthGate
    patients/                     # RTK Query API, view slice, components
    analytics/                    # RTK Query API, chart components
    notifications/                # Slice, SW registration, scheduler
  components/
    ui/                           # shadcn/ui primitives (Base UI under the hood)
    shared/                       # AppShell, Sidebar, TopBar, KpiCard, …
  store/                          # configureStore + typed hooks
  mocks/                          # MSW handlers + 56 seeded patients
  lib/                            # cn, date/format, status helpers
  types/                          # Domain types
public/
  sw.js                           # CarePlane notification worker (scope: /sw-scope/)
  mockServiceWorker.js            # MSW worker (scope: /)

Local development

Prereqs

  • Node 20+ (tested on 22)
  • npm 10+

Setup

git clone <repo-url>
cd ragas-ai-assignment
npm install
cp .env.example .env.local      # then fill in Firebase keys (see FIREBASE_SETUP.md)
npm run dev                     # http://localhost:3000

The app boots in demo mode automatically if Firebase env vars are missing — click "Continue as demo user" on the login page.

Useful scripts

npm run dev        # next dev (Turbopack)
npm run build      # next build
npm run start      # next start (after build)
npm run lint       # eslint
npm run typecheck  # tsc --noEmit
npm run format     # prettier --write

Firebase setup

See FIREBASE_SETUP.md for a 5-minute walkthrough (project creation → enabling providers → wiring env vars → authorized domains for the live deploy).


Deployment (Netlify)

  1. Push this repo to GitHub.
  2. Netlify → Add new site → Import from Git → select repo. Defaults from netlify.toml are honoured (build: npm run build, publish: .next, plugin: @netlify/plugin-nextjs).
  3. Site settings → Environment variables: add the six NEXT_PUBLIC_FIREBASE_* keys plus NEXT_PUBLIC_ENABLE_MSW=true. Trigger a redeploy.
  4. Firebase console → Authentication → Settings → Authorized domains: add your *.netlify.app domain so Google OAuth works.

Architectural notes

Why Mock Service Worker for the data layer?

The assignment asks for a UI demonstration, not a backend. MSW intercepts real fetch calls inside the browser, so the codebase looks and behaves exactly like a real API client — RTK Query, error handling, loading states, pagination, all real. Swapping to a live backend is a one-line baseUrl change.

Why two service workers?

MSW's mockServiceWorker.js has to register at root scope / to intercept all requests. Our notification SW is registered at scope /sw-scope/ (a never-navigated path) so it doesn't override MSW. Notification APIs (showNotification, notificationclick) are scope-independent, so this works cleanly.

Why Redux + RTK Query over Zustand or Context?

Three separate concerns — auth state, view preferences, notification history — each with their own update patterns and consumers. Redux DevTools time-travel debugging matters for healthcare workflows. RTK Query gives caching, dedup, and refetch semantics for free, which would be reinvented in Zustand.

Why Base UI under shadcn instead of Radix?

Newer shadcn (base-nova preset) ships Base UI primitives — same ergonomics as Radix but with better TypeScript inference and smaller bundle. The pattern-difference for consumers is render={<Component />} instead of asChild.

Why a feature-based folder structure?

Each domain (auth, patients, analytics, notifications) keeps its slice, API, and components colocated. This scales: a new module slots in beside the existing ones without surgery on shared files. components/shared/ holds primitives that are genuinely cross-cutting.


Verification checklist

  • npm install && npm run dev → loads at localhost:3000, redirects to /login
  • Click "Continue as demo user" → lands on /dashboard
  • Sign in with email/password (after Firebase setup) and Google
  • /patients → toggle grid ↔ list, search, filter by status / department, click into a patient
  • /patients/[id] → tabs (Overview / Visits / Labs / Notes) all render
  • /analytics → 4 charts render and adapt to dark mode
  • /settings/notifications → enable permission, trigger each of the three demos, verify OS notification appears
  • Click a system notification → tab focuses and navigates
  • Notification bell shows history with unread count
  • Theme toggle: Light / Dark / System
  • Mobile: hamburger menu opens, all pages responsive
  • Keyboard-only nav from login through every page
  • npm run build && npm run lint && npm run typecheck all clean

License

MIT © 2026 Kaustav Ghosh

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors