Skip to content

Latest commit

 

History

History
114 lines (95 loc) · 2.88 KB

File metadata and controls

114 lines (95 loc) · 2.88 KB

Room Owner Dashboard (React + Firebase)

Architecture (Critical Rule)

UI never calls Firebase directly.

Layering:

  1. UI components/pages (src/app/...)
  2. Custom hooks (business logic) (src/hooks/...)
  3. Service layer (Firebase abstraction) (src/services/...)
  4. Firebase SDK instances (src/lib/firebase.ts)

Examples:

  • UI calls useOwnerRooms().createRoom(...)
  • useOwnerRooms calls roomService + useUpload
  • roomService / storageService talk to Firestore/Storage

Folder Structure (key parts)

src/
  app/
    components/
      common/
        ErrorBoundary.tsx
      dashboard/
        RoomForm.tsx
        RoomList.tsx
        ImageUploader.tsx
    pages/
      dashboard/
        DashboardLayout.tsx
        MyRooms.tsx
        AddRoom.tsx
        EditRoom.tsx
        RoomDetails.tsx
  context/
    AuthContext.tsx
  features/
    rooms/
      roomConstants.ts
      roomPricing.ts
      roomValidation.ts
  hooks/
    useRooms.ts
    useUpload.ts
  services/
    authService.ts
    roomService.ts
    storageService.ts
  types/
    room.ts

Firestore Schema

Collection: rooms

Document: rooms/{roomId}

{
  title: string,
  description: string,
  location: string,
  roomType: "single" | "double" | "triple" | "dorm",
  capacity: number,
  pricing: {
    type: "perStudent" | "perRoom",
    perStudent?: { pricePerStudent: number, totalAtCapacity: number },
    perRoom?: { occupancyPrices: { [occupancy: string]: number } },
    priceMin: number,
    priceMax: number
  },
  facilities: string[],
  images: string[],           // Firebase Storage download URLs
  available: boolean,
  ownerId: string,
  ownerEmail: string,
  ownerName: string,
  createdAt: Timestamp,
  updatedAt: Timestamp
}

Storage:

  • rooms/{roomId}/{timestamp}_{index}_{fileName}

Suggested indexes (if you later move filtering server-side):

  • rooms by createdAt desc
  • rooms by ownerId asc, createdAt desc

State Management (how it works)

  • Auth: AuthProvider listens to onAuthStateChanged and exposes login/register/loginWithGoogle/logout.
  • Rooms:
    • useRooms() is for public listing/search.
    • useOwnerRooms(ownerId) manages owner rooms + mutations.
  • Optimistic UI:
    • deleteRoom removes the card immediately and restores on failure.
    • toggleAvailability flips UI immediately and restores on failure.
    • updateRoom updates fields immediately and restores on failure (images finalize after upload).

Pages (Owner)

  1. Dashboard: room list + actions (/dashboard)
  2. Add/Edit wizard: multi-step form (/dashboard/add-room, /dashboard/rooms/:roomId/edit)
  3. Room details: details + history placeholder (/dashboard/rooms/:roomId)

UX Notes (Owner)

  • Header is fixed and minimal (brand + identity + logout) with no secondary navigation.
  • Primary actions live in page content (e.g. “Add Room” on the dashboard).