Step 9 Upload your photos

Purpose (Product)

  • Enable landlords to upload and organize property photos by room, creating a comprehensive visual representation of their listing.

  • Supports two workflows: manual photo upload with room categorization, or booking professional photography services.

  • Minimum 5 photos required unless photography service is booked, ensuring adequate visual content for guest decision-making.

UX Flow (What the user sees)

1

No photos yet

Large upload area with drag-and-drop support, plus option to book professional photography service.

2

Photos exist

Room-based organization with sidebar (desktop) or tabs (mobile) for room selection, plus upload area for each room.

3

First-time upload

Multi-step dialog for bulk photo selection, then room categorization workflow.

4

Room management

Add/delete rooms with confirmation, reassign photos between rooms.

5

Photography service

Toggle booking with confirmation dialog; when booked, bypasses photo requirement.

Photography CTA Flow

![[Photo CTA 1.png]]

![[Photo CTA 2.png]]

![[Photo CTA Modal.png]]

Bulk Uploads Flow

![[Photo Step - 1.png]]

![[Photo Step - 2.png]] ![[Placeholder.png]] ![[Photos Step - 3.png]]

![[Photos Step - 4.1.png]]

![[Photos Step - 4.png]]

System Flow (How it works)

APIs Called

  • POST /api/properties/{propertyId}/property-rooms

    • Payload: { name: string, type: string, order: number }

    • Response: Created room with ID

    • Errors: 400, 401/403, 404, 500

  • DELETE /api/properties/{propertyId}/property-rooms/{roomId}

    • Purpose: Remove room and associated images

    • Errors: 400, 401/403, 404, 500

  • POST /api/properties/{propertyId}/cart

    • Payload: { serviceId: string, quantity: 1 } (photography service)

    • Response: Updated cart

    • Errors: 400, 401/403, 404, 500

  • DELETE /api/properties/{propertyId}/cart

    • Payload: { serviceId: string } (remove photography service)

    • Response: Updated cart

  • PATCH /api/properties/{propertyId}

    • Payload: { images: Array<{propertyId, propertyRoomId, smallUrl, mediumUrl, thumbnailUrl, sortOrder, caption}> }

    • Response: Updated property

    • Errors: 400, 401/403, 404, 500

  • PATCH /api/users/{userId}

    • Payload: { onboardingStep: number } (current + 1)

    • Response: Updated user

Integrations

  • Firebase Storage: File upload with progress tracking via uploadFileToFirebase

  • Photography Service: Integration with service marketplace for professional photography booking

  • Firebase Auth: User context management

QA Checklist

  • Visual

    • Upload area renders correctly for both empty and populated states

    • Room sidebar/tabs show proper selection states

    • Upload progress modal displays correctly

  • Behavior

    • Drag-and-drop and click upload work

    • Room creation/deletion with confirmation

    • Photo categorization workflow completes successfully

    • Photography service booking toggles correctly

  • Data

    • Verify properties.images array contains correct room associations

    • Verify properties.propertyRooms reflects created/deleted rooms

    • Verify users.onboardingStep increments once

  • Negative

    • < 5 photos without photography service shows validation error

    • Upload failures prevent step advancement

    • Network errors handled gracefully