Inbox Page (Messages & Negotiations)

The InboxPage acts as the central communication hub for Socon-MKT. Because the platform relies on peer-to-peer negotiations rather than a standard checkout cart, this page tracks all active and past conversations between buyers and sellers, displaying real-time statuses like "Negotiating" or "Delivering."

The interface is constrained to a 680px maximum width, providing a focused, chat-app-like experience.


Component Architecture

The inbox is designed for quick scanning and easy filtering of active negotiations.

1. InboxPage (Main Wrapper)

This component fetches the paginated list of all active chat threads and provides a unified view for the user.

  • Local Search Filtering: Features a text input that filters the loaded chats locally (client-side) rather than making new server requests. It safely checks the search query against the seller's business title, username, product title, and the last message preview.
  • Empty & Error States: Renders contextual empty states (e.g., if the user has no chats globally vs. if a specific search query yields no results).
  • Infinite Scroll: Utilizes the standard react-intersection-observer sentinel at the bottom of the list to automatically fetch older chat threads.

2. MessageItem

Renders an individual chat row summarizing the negotiation.

  • Contextual Badges:
  • PriceTag: Conditionally changes styling based on the negotiation status (e.g., gray if currently negotiating, gold otherwise).
  • StatusPill: Dynamically renders color-coded pills based on the order.status ("Negotiating" [Gray], "Agreed" [Teal], "Delivering" [Violet], or "Completed" [Green]).
  • Visual Hierarchy: Highlights unread threads using a tinted background (#FFF8E8), a bolder preview text, and a distinct red dot indicator. It also displays a miniature thumbnail of the product being discussed to provide immediate visual context.

State Management & Real-Time Updates

The Inbox leverages @tanstack/react-query to handle both historical data pagination and near real-time updates.

  • Background Polling: The useFetchAllChats hook implements a refetchInterval: 10000 (10 seconds). This acts as a lightweight polling mechanism, automatically pinging the server in the background to fetch new messages and update the "last message preview" and "unread" statuses without requiring WebSockets.
  • Infinite Scrolling: Uses the c (cursor) parameter from the backend's next pagination link to continuously append older chat threads as the user scrolls down the list.

API Endpoints & Data Structures

The inbox interacts with the backend via a primary fetch endpoint using the globally configured Axios authApi instance.

1. Fetch All Chats (Infinite)

Retrieves the paginated list of chat threads the current user is participating in.

  • Endpoint: GET /chat/all_chats/
  • Query Parameters: c (Cursor string for pagination)
  • Authorization: Required (Bearer Token)
  • Response Structure (ChatListResponse):
    {
      "next": "url_string | null",
      "previous": "url_string | null",
      "results": [
        {
          "chat_id": "string",
          "created_at": "ISO 8601 string",
          "updated_at": "ISO 8601 string",
          "last_message_preview": "string",
          "is_own": false,
          "is_unread": true,
          "order": {
            "id": "string",
            "status": "NEGOTIATING | COMPLETED | AGREED | DELIVERING",
            "created_at": "ISO 8601 string",
            "user": {
              "profile_pic": "string | null"
            },
            "product_obj": {
              "id": "string",
              "title": "string | null",
              "price": "string | null",
              "category": "string | null",
              "unit": "string | null",
              "created_at": "ISO 8601 string",
              "updated_at": "ISO 8601 string",
              "author": {
                "id": "string",
                "username": "string",
                "email": "string",
                "profile": {
                  "profile_id": "string",
                  "profile_pic": "string | null",
                  "seller_profile": {
                    "id": "string",
                    "business_title": "string",
                    "category": ["string"],
                    "is_verified": true,
                    "business_logo": "string | null"
                  }
                }
              },
              "media": [
                {
                  "id": "string",
                  "file": "string_url",
                  "media_type": "image | video",
                  "name": "string",
                  "size": "string",
                  "thumbnail": "string_url | null"
                }
              ]
            }
          }
        }
      ]
    }