Skip to content

ComplaintHeader ​

The top bar of the conversation pane: subject, status pill, received date, the complainer's identity, the related order, and — for staff — a status menu that only offers moves the API would accept. ComplaintPreview embeds it, but it is usable on its own.

vue
<script setup lang="ts">
import { ref } from "vue"
import RyderComplaintHeader from "@opeolluwa/ryder/components/complaints/ComplaintHeader.vue"
import type { ComplaintWritableStatus } from "@opeolluwa/ryder/types"

const status = ref<ComplaintWritableStatus | null>(null)
</script>

<template>
  <RyderComplaintHeader :row="row" @set-status="status = $event" />
</template>

Examples ​

vue
<script setup lang="ts">
import { ref } from "vue";
import ComplaintHeader from "../../../src/components/complaints/ComplaintHeader.vue";
import { row } from "./fixtures";
import type {
  ComplaintRow,
  ComplaintWritableStatus,
} from "../../../src/types/complaints";

// The demo owns the row, so a status pick re-renders the pill and the menu:
// resolved/closed complaints get no transitions left to offer.
const currentRow = ref<ComplaintRow>({ ...row });
const lastStatus = ref<ComplaintWritableStatus | null>(null);

function onSetStatus(status: ComplaintWritableStatus) {
  lastStatus.value = status;
  currentRow.value = {
    ...currentRow.value,
    complaint: { ...currentRow.value.complaint, status },
  };
}
</script>

<template>
  <div>
    <div
      class="rounded-xl border border-gray-100 bg-white dark:border-white/5 dark:bg-gray-950"
    >
      <ComplaintHeader :row="currentRow" @set-status="onSetStatus" />
    </div>

    <p class="mt-3 text-xs text-gray-500 dark:text-white/40">
      Last setStatus: {{ lastStatus ?? "—" }}
    </p>
  </div>
</template>

Props ​

PropTypeDefaultDescription
rowComplaintRow—The complaint (plus customer/order) to head.
statusMenubooleantrueOffer the "update status" dropdown. Off for the customer-facing app.
showCustomerbooleantrueShow the complainer's avatar, name and email. The customer-facing app hides it.

Emits ​

EventPayloadDescription
setStatus[status: ComplaintWritableStatus]A menu item was picked. Legal transitions only: in_progress, resolved or closed — never open.

Slots ​

None.

Notes ​

  • The menu is built from complaintStatusTransitions, so it lists only forward moves from the current status: open → in progress/resolved/closed, in_progress → resolved/closed, and no items at all for resolved/closed — the dropdown trigger is hidden even with statusMenu on.
  • The status pill treats null as open (resolveStatus), stays amber while the complaint is resolvable and turns emerald once resolved or closed.
  • Uses useIsMobile() (max-width: 1023px, Tailwind's lg boundary): the customer/order meta row collapses on mobile unless row.order exists.
  • row.customer?.email and row.order are both optional — the header renders whichever parts are present.