Chat & Negotiation Page

The ChatPage is the core transactional interface of Socon-MKT. Because the platform relies on peer-to-peer agreements rather than automated checkout gateways, this page facilitates direct communication between buyers and sellers, tracks deal progress, and provides an off-platform Escrow safety net.

The page uses a maximum width of 1000px and features a responsive split-pane layout: a sticky context sidebar on desktop (collapsing to the top on mobile) and the primary messaging interface.


Component Architecture

The chat interface is divided into contextual metadata and the active message stream.

1. ChatPage (Layout & Context)

This wrapper component manages the layout and fetches the high-level metadata for the current chat session.

  • Product Context Card: Displays the product being negotiated, its price, and a link to view the full listing.
  • Deal Progress Tracker: A visual step-indicator mapped to the backend order.status (NEGOTIATING, AGREED, DELIVERING, COMPLETED).
  • Admin Escrow Integration: A premium UI card that dynamically generates a pre-filled WhatsApp message. It encodes the product name, price, seller, and a direct URL, allowing users to quickly request Socon-MKT admin intervention to hold funds securely.

2. ChatMessages

A dedicated component handling the actual message feed to isolate intensive re-renders from the main layout.

  • Reverse Infinite Scroll: Unlike feeds that scroll down for older content, chats load newest messages at the bottom. The react-intersection-observer sentinel is placed at the top of the container to fetch older pages when the user scrolls up.
  • Auto-Scroll to Bottom: Uses a useRef dummy div at the bottom of the message list. On initial load, it forces the container to scroll down to the most recent message.
  • Read Receipts: Mimics standard chat applications. Outgoing messages display a single gray tick (sent/unread) or a double blue tick (read by the recipient).

State Management & Optimistic UI

To provide a real-time chat experience without the overhead of WebSockets, the application leverages advanced @tanstack/react-query polling and optimistic updates.

  • Background Polling:
  • useFetchChat: Polls the chat metadata (like order status updates) every 10 seconds.
  • useFetchChatMessages: Polls the message array every 5 seconds to instantly pull in new replies.
  • Optimistic Message Sending (useCreateMessages): When a user hits send, the UI does not wait for a server response. The mutation cancels active fetches, snapshots the cache, and injects a mock MessageItem with a temp_ ID and is_own: true into the top of the paginated array. The message appears instantly on screen. If the API call fails, the cache rolls back to the snapshot.
  • Auto-Read Mechanism (useReadMessage): A useEffect hook actively monitors the incoming messages array. If it detects unread messages where is_own is false, it automatically fires a mutation in the background to mark those specific message IDs as read on the server.

API Endpoints & Data Structures

The chat interface relies on four primary endpoints via the authApi Axios instance.

1. Fetch Chat Metadata (Polling)

Retrieves the high-level details of the conversation, including the order status and associated product.

  • Endpoint: GET /chat/all_chats/:chatId/
  • Authorization: Required (Bearer Token)
  • Response Structure (ChatItem):
    {
      "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": { /* Author Object */ },
          "media": [ /* Media Array */ ]
        }
      }
    }
    

2. Fetch Chat Messages (Infinite & Polling)

Retrieves the paginated list of messages for the active chat room.

  • Endpoint: GET /chat/messages/
  • Query Parameters:
  • chatId: The ID of the current chat.
  • c: Cursor string for pagination.
  • Authorization: Required (Bearer Token)
  • Response Structure (MessageListResponse):
    {
      "next": "url_string | null",
      "previous": "url_string | null",
      "results": [
        {
          "message_id": "string",
          "text": "string",
          "is_read": false,
          "is_own": true
        }
      ]
    }
    

3. Send Message

Posts a new message to the chat room.

  • Endpoint: POST /chat/messages/
  • Payload (SendMessagePayload):
    {
      "text": "string",
      "is_read": false,
      "chat_id": "string | null",
      "order_id": "string"
    }
    
  • Authorization: Required (Bearer Token)

4. Mark Messages as Read

Sends an array of message IDs to the server to update their read status.

  • Endpoint: POST /chat/messages/read_message/
  • Payload:
    {
      "messageId": ["message_id_1", "message_id_2"]
    }
    
  • Authorization: Required (Bearer Token)