Case Study · UI/UX Design + Full-Stack Development

Carowna
Vehicle Rental
Platform

Pan-India car & bike rental, designed and built end-to-end by Kodrex.

Industry
Vehicle Rental & Mobility
Services
UI/UX Design + Full-Stack Dev
Platform
Next.js + Supabase
Coverage
Pan India · 50+ Cities

Carowna is an enterprise-grade vehicle rental marketplace connecting customers with cars and bikes across India. The platform serves three distinct user roles, Customer, Vendor, and Admin, each with a purpose-built dashboard, secured by role-based access control, and powered by real-time data through Supabase. Every layer was designed and engineered in-house by the Kodrex team with a sharp focus on billing transparency, trust-building UX, and seamless mobile-first experience.

<3min
Search to confirmed booking
<35ms
Vehicle inventory load time
3
Customer · Vendor · Admin
01 - Challenge

A Fragmented Market
Needed a Clear Platform

Opacity was the industry norm

India's vehicle rental market was dominated by platforms that obscured pricing, buried terms in fine print, and left customers confused about what they owed and when. Vendors had no real-time visibility into their fleet. Admins had no centralised control.

  • No transparent, day-wise billing model customers could actually trust
  • Vendor fleet management done manually via spreadsheets and phone calls
  • Driver hire fees were opaque, true cost discovered too late in the flow
  • Security deposit handling was inconsistent and unexplained
  • No unified admin layer for approvals, KYC verification, and oversight

Build trust through radical transparency

Carowna needed more than a booking form. The brief called for a multi-sided platform with clearly separated role experiences, a billing model users could understand at a glance, and a backend that vendors and admins could rely on daily.

  • Surface every cost before the customer confirms
  • Build a vendor portal for fleet management and earnings tracking
  • Create an admin layer for KYC approvals and platform oversight
  • Integrate Razorpay with webhook-driven booking state transitions
  • Deliver a mobile-first experience that felt premium and fast

02 - Approach

Research, Decisions,
Deliberate Design

Before a single component was built, the product was mapped, user by user, flow by flow.

Research

Understanding three distinct users

We mapped the core journeys for each role: a customer searching by city and date, a vendor listing and managing their fleet, and an admin approving vehicles and monitoring the platform. The billing model, 24-hour day-wise cycles, ₹500 advance payment, driver fee upfront, security deposit at pickup, required its own dedicated logic layer. We audited how competitors handled transparency failures and designed Carowna to explicitly address each one.

Planning

Architecture before aesthetics

The data model came first, a fully normalised PostgreSQL schema with Supabase Row Level Security policies enforcing role-based data access. Vendor A can never access Vendor B's fleet or booking data. The booking state machine was explicitly modelled before any code was written: PENDING → REQUESTED → UPCOMING → ONGOING → COMPLETED. Every state transition is triggered by a Razorpay webhook, never by client-side code.

Design Decisions

Every screen earned its place

The booking confirmation screen was the most critical design problem: how do you show a customer exactly what they owe now (₹500 advance + driver fee), what they owe at pickup (rental balance + security deposit), and what happens if they return late, without overwhelming them? The solution was a payment split card with two clearly labelled sections and a plain-language billing walkthrough covering both scenarios.


From Search to Confirmed
in Under 3 Minutes

1
Search Fleet

Filter by city, dates, vehicle type, fuel type, and driver preference

2
Select Vehicle

View specs, daily pricing, and driver availability on the detail page

3
Confirm Booking

Review the full cost summary, upload documents, and agree to terms

4
Pay ₹500 Advance

Razorpay checkout. Webhook transitions the booking to CONFIRMED

5
Pickup & Drive

Balance + security deposit collected at pickup. Return by 23:59


03 - Development

The Stack Behind
the Experience

Every technology chosen for a specific reason. No bloat, no compromise on performance or security.

Next.js 15

App Router, Server Actions, and hybrid rendering. Static cache for inventory, dynamic for live booking state.

Supabase + PostgreSQL

Fully normalised schema, Row Level Security policies enforced per role, real-time triggers for profile sync.

Razorpay

Advance payment collection and refund processing. Webhook-driven booking state transitions, no client-side trust.

shadcn/ui + Tailwind

OKLCH design tokens for a consistent, accessible dark mode. Custom component extensions for booking-specific UI.

TypeScript

Strict mode, zero implicit-any. Zod validation schemas for all form inputs and API payloads.

JWT Middleware

Edge JWT decoding eliminates auth API round-trips. Role resolution in under 50ms, flicker-free page renders.

pnpm Workspace

Monorepo-ready workspace configuration for scalable multi-package management.

TanStack Query

Client-side data fetching with cache invalidation aligned to server-side revalidation tags.

Three Portals.
Hundreds of Features.

Role Feature Description
Customer Booking Flow Multi-step booking with vehicle selection, date picker, driver toggle, document upload, full cost summary with payment split, and Razorpay checkout. Every charge visible before confirmation.
Customer Vehicle Browse Infinite-scroll vehicle listing with sidebar filters (type, fuel, price, driver availability) and a sticky filter bar. Sorted and paginated server-side.
Vendor Fleet Management Vendors list vehicles with image galleries, RC documents, insurance docs, pricing, and specs. Per-vehicle approval workflow, vehicles go live only after Admin review.
Vendor Driver Management Vendors register and manage their driver pool with licence uploads, daily rates, availability toggling, and performance metrics.
Admin Platform Dashboard Platform-wide oversight, revenue charts, booking stats, pending KYC approvals, user management, vendor management, and full vehicle approval workflow.
Platform Receipts & Policies Auto-generated booking receipts with transaction IDs, payment split, and security deposit disclosure. Inline Privacy Policy, T&C, and Refund Policy built into the app.

Four Hard Problems,
Elegant Solutions

01

Cross-Table OR Queries in PostgREST

Supabase's PostgREST layer does not support logical OR across columns from different joined tables. A simple booking search by customer name OR vehicle name would fail with a PGRST100 error.

Fix: A multi-step parallel query strategy, fetch matching IDs from the vehicles and users tables separately, intersect with the vendor's fleet for tenant isolation, and construct a valid nested OR filter only when matches exist.

02

Multi-Tenant Cache Isolation

Early implementations used static cache keys, which meant Vendor A's fleet results were being served to Vendor B from the Next.js cache.

Fix: Serialise all scope parameters, vendorId, page number, and active filter state, directly into the cache key, guaranteeing per-tenant isolation with automatic invalidation on data mutation.

03

Flicker-Free Authentication

Authenticated pages suffered 1-3 second redirect flickers. Client-side auth checks queried Supabase on every page load before deciding whether to redirect, creating a visible blank flash.

Fix: Decode the session JWT cookie directly in Next.js Middleware at the edge. Role resolution now happens in under 50ms, before the page begins rendering, zero flicker.

04

Uncontrolled Input Clear Bug

Resetting search parameters via URL correctly cleared the query string, but uncontrolled input fields retained their previous values, the text boxes wouldn't visually clear because React never re-mounted the component.

Fix: A reactive key prop tied to the search value forces React to destroy and recreate the input node on every reset, zero state management overhead.


04 - Results

Performance That
Speaks for Itself

From sub-35ms inventory loads to a booking flow customers complete in under three minutes.

<35ms
Inventory Load
Cached via Next.js server cache
<50ms
Auth Resolution
JWT edge decoding, zero round-trip
3
Role Dashboards
Customer · Vendor · Admin - fully isolated
0
Hidden Charges
Every cost surfaced before confirmation
100%
TypeScript Coverage
Strict mode, zero implicit-any
5
Booking States
Webhook-driven, never client-trusted
50+
Cities Supported
Pan-India with geolocation support
5–7 days
Refund Processing
Razorpay-powered, policy-compliant

Three Portals,
One Platform

Customer

CUSTOMER PORTAL

  • Browse vehicles by city, dates, and filters
  • Choose self-drive or hire a driver
  • View the full cost breakdown before booking
  • Pay ₹500 advance via Razorpay
  • Upload KYC documents inline during booking
  • Access booking history and auto-generated receipts
  • Read T&C, Privacy Policy, and Refund Policy in-app
Vendor

VENDOR PORTAL

  • Dashboard with revenue and booking analytics
  • List vehicles with images, RC and insurance docs
  • Toggle vehicle availability in real-time
  • Add and manage a driver pool
  • View per-booking payment settlement details
  • Track fleet performance metrics
  • Await admin vehicle approval before listings go live
Admin

ADMIN PORTAL

  • Platform-wide revenue and booking statistics
  • Vehicle KYC and document approval workflow
  • Full user and vendor management
  • Driver oversight across all vendor accounts
  • Booking management and manual status updates
  • CMS for platform content
  • Full audit trail on all approval actions

The team didn't just build what we asked for. They designed the billing transparency we couldn't articulate ourselves. Customers now know exactly what they're paying before they tap confirm. That trust has changed everything.

Carowna Founder

Have a project
in mind?

Whether you need a website, an online store, a web application, or a custom solution, we'll help you find the right approach and build it from the ground up.