"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";










var _chunk35XIT2CFcjs = require('../../chunk-35XIT2CF.cjs');
require('../../chunk-VFKQMAUF.cjs');


var _chunkOTKJASSXcjs = require('../../chunk-OTKJASSX.cjs');






















var _chunkZDF6F7EDcjs = require('../../chunk-ZDF6F7ED.cjs');


var _chunkWT5JV2GScjs = require('../../chunk-WT5JV2GS.cjs');
require('../../chunk-24KCAECR.cjs');
require('../../chunk-65CPJ4SX.cjs');
require('../../chunk-XQFFGR6U.cjs');
require('../../chunk-P5EE2VJX.cjs');
require('../../chunk-27APPAJN.cjs');
require('../../chunk-XL4V2PYG.cjs');
require('../../chunk-BZFW3FOF.cjs');




var _chunkG7UE6RKVcjs = require('../../chunk-G7UE6RKV.cjs');
require('../../chunk-OZ3GH6OQ.cjs');





var _chunkUXZ3ZJ3Mcjs = require('../../chunk-UXZ3ZJ3M.cjs');
require('../../chunk-664KA5FI.cjs');
require('../../chunk-WZW7C7TF.cjs');
require('../../chunk-WBR7H6E3.cjs');
require('../../chunk-VRHGVLSL.cjs');

// src/components/tickets/ticket-center.tsx
var _react = require('react');
var _reactquery = require('@tanstack/react-query');
_chunkUXZ3ZJ3Mcjs.init_button2.call(void 0, );
var _lucidereact = require('lucide-react');

// src/components/tickets/ticket-open-form.tsx

_chunkUXZ3ZJ3Mcjs.init_button2.call(void 0, );

// src/components/tickets/types.ts
function isOptimistic(t) {
  return t._optimistic === true;
}
var TICKET_TEXT_MAX_CHARS = 5e3;
var TOAST_COPY = {
  open_success: { title: "Ticket opened", description: "We received your message and will follow up shortly." },
  open_mirror_pending: { title: "Ticket opened", description: "Syncing \u2014 your ticket will appear momentarily." },
  close_success: { title: "Ticket closed" },
  reopen_success: { title: "Ticket reopened" },
  comment_success: { title: "Comment added" },
  attach_success: { title: "Files attached" }
  // Failure variants are constructed dynamically from MappedTicketActionError.
};

// src/components/tickets/ticket-open-form.tsx
var _jsxruntime = require('react/jsx-runtime');
var COUNTER_VISIBLE_AT = Math.floor(TICKET_TEXT_MAX_CHARS * 0.8);
function TicketOpenForm({
  onSubmit,
  isSubmitting,
  supportSystemDown
}) {
  const [subject, setSubject] = _react.useState.call(void 0, "");
  const [content, setContent] = _react.useState.call(void 0, "");
  const { attachments, readyAttachments, hasInflightUploads, addFiles, removeAttachment, clear } = _chunkZDF6F7EDcjs.useChatAttachments.call(void 0, );
  const trimmedSubject = subject.trim();
  const trimmedContent = content.trim();
  const overCap = content.length > TICKET_TEXT_MAX_CHARS;
  const showCounter = content.length >= COUNTER_VISIBLE_AT;
  const canSubmit = !isSubmitting && !supportSystemDown && !hasInflightUploads && trimmedSubject.length > 0 && trimmedContent.length > 0 && !overCap;
  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    const ok = await onSubmit({
      subject: trimmedSubject,
      content: trimmedContent,
      attachments: readyAttachments
    });
    if (ok) {
      setSubject("");
      setContent("");
      clear();
    }
  };
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZDF6F7EDcjs.Card, { className: "p-6", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: handleSubmit, className: "flex flex-col md:flex-row gap-6", children: [
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0 md:max-w-md", children: [
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "text-2xl font-semibold text-ods-text-primary mb-2", children: "Need Support?" }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-secondary text-sm", children: "Can't find what you're looking for? Submit a support ticket below \u2014 we'll follow up shortly." }),
      supportSystemDown && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mt-4 text-sm text-ods-error", children: "Support system temporarily unavailable. Please try again shortly." })
    ] }),
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0 flex flex-col gap-4", children: [
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          "label",
          {
            htmlFor: "ticket-subject",
            className: "block text-sm font-medium text-ods-text-primary mb-1",
            children: "Ticket Subject"
          }
        ),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          _chunkUXZ3ZJ3Mcjs.Input,
          {
            id: "ticket-subject",
            type: "text",
            placeholder: "Enter Subject Here",
            value: subject,
            onChange: (e) => setSubject(e.target.value),
            disabled: isSubmitting || supportSystemDown,
            maxLength: 200
          }
        )
      ] }),
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          "label",
          {
            htmlFor: "ticket-content",
            className: "block text-sm font-medium text-ods-text-primary mb-1",
            children: "Your Message"
          }
        ),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          _chunkZDF6F7EDcjs.Textarea,
          {
            id: "ticket-content",
            placeholder: "Describe your issue or question in detail...",
            value: content,
            onChange: (e) => setContent(e.target.value),
            disabled: isSubmitting || supportSystemDown,
            rows: 5,
            className: "resize-none"
          }
        ),
        showCounter && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, 
          "p",
          {
            className: `mt-1 text-xs text-right ${overCap ? "text-ods-error" : "text-ods-text-secondary"}`,
            children: [
              content.length,
              "/",
              TICKET_TEXT_MAX_CHARS
            ]
          }
        )
      ] }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        _chunkZDF6F7EDcjs.ChatAttachmentChipStrip,
        {
          attachments,
          onRemove: removeAttachment,
          disabled: isSubmitting || supportSystemDown
        }
      ),
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between gap-3", children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          _chunkZDF6F7EDcjs.ChatAttachmentAddButton,
          {
            attachmentsEnabled: !supportSystemDown,
            attachmentsCount: attachments.length,
            onAddFiles: addFiles,
            disabled: isSubmitting
          }
        ),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          _chunkUXZ3ZJ3Mcjs.Button,
          {
            type: "submit",
            disabled: !canSubmit,
            loading: isSubmitting,
            children: "Open Ticket"
          }
        )
      ] })
    ] })
  ] }) });
}

// src/components/tickets/ticket-row.tsx


// src/components/collapsible.tsx
var _reactcollapsible = require('@radix-ui/react-collapsible'); var CollapsiblePrimitive = _interopRequireWildcard(_reactcollapsible);
var Collapsible = CollapsiblePrimitive.Root;
var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;

// src/components/tickets/ticket-detail-drawer.tsx
_chunkUXZ3ZJ3Mcjs.init_button2.call(void 0, );


// src/components/tickets/hooks/use-ticket-engagements.ts

var LIST_ENGAGEMENTS_ENDPOINT = "/api/chat/agent/list-engagements";
function useTicketEngagements(externalTicketId, enabled = true) {
  const identity = _chunkZDF6F7EDcjs.useChatIdentity.call(void 0, );
  const identityKey = _nullishCoalesce(_optionalChain([identity, 'access', _ => _.user, 'optionalAccess', _2 => _2.email]), () => ( "anon"));
  const queryEnabled = enabled && identity.authTier !== "anon" && !!_optionalChain([identity, 'access', _3 => _3.user, 'optionalAccess', _4 => _4.email]) && !!externalTicketId && !externalTicketId.startsWith("temp-");
  const query = _reactquery.useQuery.call(void 0, {
    queryKey: ["ticket-engagements", externalTicketId, identityKey],
    enabled: queryEnabled,
    // Caches OFF — same reasoning as `useTicketsList`. The conversation
    // timeline must reflect HubSpot truth on every drawer-open; a stale
    // window risks hiding a freshly-arrived agent reply.
    staleTime: 0,
    gcTime: 0,
    refetchOnMount: "always",
    refetchOnWindowFocus: true,
    queryFn: async () => {
      const response = await _chunkZDF6F7EDcjs.embedAuthedFetch.call(void 0, LIST_ENGAGEMENTS_ENDPOINT, {
        method: "POST",
        body: JSON.stringify({ ticket_id: externalTicketId })
      });
      if (!response.ok) {
        const text = await response.text().catch(() => "");
        throw new Error(`list-engagements failed: ${response.status} ${text.slice(0, 200)}`);
      }
      const body = await response.json();
      return Array.isArray(body.engagements) ? body.engagements : [];
    }
  });
  return {
    engagements: _nullishCoalesce(query.data, () => ( [])),
    isLoading: queryEnabled && query.isLoading,
    isFetching: query.isFetching,
    error: _nullishCoalesce(query.error, () => ( null)),
    refetch: () => {
      void query.refetch();
    }
  };
}

// src/components/tickets/ticket-linked-delivery-card.tsx

function TicketLinkedDeliveryCard({
  clickup,
  className
}) {
  const item = {
    id: clickup.external_id,
    title: _nullishCoalesce(clickup.title, () => ( "Linked delivery task")),
    description: _nullishCoalesce(clickup.description, () => ( "")),
    status: _nullishCoalesce(clickup.status, () => ( "unknown")),
    statusColor: _nullishCoalesce(clickup.status_color, () => ( "#87909e")),
    taskType: _nullishCoalesce(clickup.task_type, () => ( "Request")),
    customItemId: clickup.custom_item_id,
    listNames: clickup.list_names,
    dateOpened: _nullishCoalesce(clickup.date_opened, () => ( 0)),
    dateUpdated: _nullishCoalesce(_nullishCoalesce(clickup.date_updated, () => ( clickup.date_opened)), () => ( Date.now())),
    dateClosed: clickup.date_closed,
    clickupUrl: _nullishCoalesce(clickup.clickup_url, () => ( ""))
  };
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
    "div",
    {
      className: `rounded-md border border-ods-border bg-ods-bg overflow-hidden ${_nullishCoalesce(className, () => ( ""))}`,
      children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        _chunk35XIT2CFcjs.DeliveryRow,
        {
          item,
          href: clickup.delivery_href,
          caption: "Linked delivery"
        }
      )
    }
  );
}

// src/components/tickets/ticket-detail-drawer.tsx

function TicketDetailDrawer({
  ticket,
  busy,
  supportSystemDown,
  onSendMessage,
  onClose,
  onReopen,
  onActionCollapsed
}) {
  const isClosed = (_nullishCoalesce(ticket.status, () => ( ""))).toUpperCase() === "CLOSED";
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-ods-card border-t border-ods-border px-4 py-4 flex flex-col gap-4", children: [
    ticket.clickup && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TicketLinkedDeliveryCard, { clickup: ticket.clickup }),
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs font-medium text-ods-text-secondary mb-2 uppercase tracking-wider", children: "Conversation" }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TicketTimelinePanel, { ticket })
    ] }),
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-t border-ods-border pt-4", children: isClosed ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      ReopenAction,
      {
        ticketRef: { id: ticket.id, external_id: ticket.external_id },
        busy,
        supportSystemDown,
        onReopen,
        onActionCollapsed
      }
    ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      OpenActions,
      {
        ticket,
        busy,
        supportSystemDown,
        onSendMessage,
        onClose,
        onActionCollapsed
      }
    ) })
  ] });
}
var TURN_SEPARATOR_RE = /[\s]{1,16}---[\s]{1,16}/g;
function TicketTimelinePanel({ ticket }) {
  const identity = _chunkZDF6F7EDcjs.useChatIdentity.call(void 0, );
  const externalId = isOptimistic(ticket) ? null : ticket.external_id;
  const { engagements, isLoading } = useTicketEngagements(externalId, !!externalId);
  const bodyTurns = ticket.body ? ticket.body.split(TURN_SEPARATOR_RE).map((t) => t.trim()).filter(Boolean) : [];
  const sessionEmailLower = _nullishCoalesce(_optionalChain([identity, 'access', _5 => _5.user, 'optionalAccess', _6 => _6.email, 'optionalAccess', _7 => _7.trim, 'call', _8 => _8(), 'access', _9 => _9.toLowerCase, 'call', _10 => _10()]), () => ( null));
  const isViewerTheCustomer = !!sessionEmailLower && ticket.customer_emails.some((e) => e.trim().toLowerCase() === sessionEmailLower);
  const viewerName = _optionalChain([identity, 'access', _11 => _11.user, 'optionalAccess', _12 => _12.name, 'optionalAccess', _13 => _13.trim, 'call', _14 => _14()]) || null;
  const ticketCustomerName = _optionalChain([ticket, 'access', _15 => _15.customer_name, 'optionalAccess', _16 => _16.trim, 'call', _17 => _17()]) || null;
  const customerName = (isViewerTheCustomer ? viewerName : null) || ticketCustomerName || viewerName || _optionalChain([identity, 'access', _18 => _18.user, 'optionalAccess', _19 => _19.email]) || "You";
  const customerAvatar = isViewerTheCustomer ? _nullishCoalesce(_optionalChain([identity, 'access', _20 => _20.user, 'optionalAccess', _21 => _21.avatarUrl]), () => ( void 0)) : void 0;
  if (bodyTurns.length === 0 && engagements.length === 0) {
    if (isLoading) {
      return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.ConversationCardRowSkeletonList, { rows: 2 });
    }
    return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      _chunk35XIT2CFcjs.EmptyState,
      {
        type: "generic",
        title: "No conversation yet",
        description: "Reply below to start the thread with the support team.",
        showCTA: false
      }
    );
  }
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-ods-card border border-ods-border rounded-[6px] overflow-hidden w-full", children: [
    bodyTurns.map((turn, i) => {
      const isResolution = turn.startsWith("[Resolution]");
      const role = i === 0 ? "Original message" : isResolution ? "Resolution" : `Update ${i}`;
      const text = isResolution ? turn.replace(/^\[Resolution\]\s*/, "") : turn;
      return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        _chunk35XIT2CFcjs.ConversationCardRow,
        {
          author: customerName,
          role,
          avatarSrc: customerAvatar,
          body: text,
          variant: "current-user"
        },
        `body-${i}-${turn.slice(0, 24)}`
      );
    }),
    engagements.map((eng) => {
      const isCustomer = eng.authorRole === "customer";
      const isOwnReply = isCustomer && !!eng.authorId && !!_optionalChain([identity, 'access', _22 => _22.user, 'optionalAccess', _23 => _23.email]) && eng.authorId.toLowerCase() === identity.user.email.toLowerCase();
      let author;
      let avatarSrc;
      if (isCustomer && isOwnReply) {
        author = _optionalChain([identity, 'access', _24 => _24.user, 'optionalAccess', _25 => _25.name, 'optionalAccess', _26 => _26.trim, 'call', _27 => _27()]) || customerName;
        avatarSrc = _nullishCoalesce(_optionalChain([identity, 'access', _28 => _28.user, 'optionalAccess', _29 => _29.avatarUrl]), () => ( void 0));
      } else if (isCustomer) {
        author = ticketCustomerName || "Customer";
        avatarSrc = void 0;
      } else if (eng.authorName && eng.authorAvatarUrl) {
        author = eng.authorName;
        avatarSrc = eng.authorAvatarUrl;
      } else {
        author = "Support team";
        avatarSrc = void 0;
      }
      return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        _chunk35XIT2CFcjs.ConversationCardRow,
        {
          author,
          role: "Reply",
          avatarSrc,
          timestamp: eng.createdAt,
          body: stripAttachmentsPreamble(_nullishCoalesce(eng.body, () => ( ""))),
          attachments: mapEngagementAttachments(eng.attachments),
          variant: isCustomer ? "current-user" : "support"
        },
        eng.id
      );
    }),
    isLoading && // Trailing single-row skeleton when the panel already has
    // content rendered — drawer is showing the customer's body
    // turns + cached engagements while a background refetch is
    // in flight. Single row keeps the placeholder modest.
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.ConversationCardRowSkeletonList, { rows: 1 })
  ] });
}
function mapEngagementAttachments(files) {
  return files.map((f) => ({
    id: f.id,
    fileName: _nullishCoalesce(f.name, () => ( `file-${f.id}`)),
    fileSize: f.size ? formatBytes(f.size) : "",
    onDownload: f.url ? () => window.open(f.url, "_blank", "noopener,noreferrer") : void 0
  }));
}
function formatBytes(size) {
  if (size < 1024) return `${size} B`;
  if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`;
  return `${(size / (1024 * 1024)).toFixed(1)} MB`;
}
var ATTACHMENTS_PREAMBLE_RE = /\s*\n\s*Attachments\b[^]*$/i;
function stripAttachmentsPreamble(body) {
  return body.replace(ATTACHMENTS_PREAMBLE_RE, "").trim();
}
function ReopenAction({
  ticketRef,
  busy,
  supportSystemDown,
  onReopen,
  onActionCollapsed
}) {
  const handleReopen = async () => {
    const ok = await onReopen(ticketRef);
    if (ok) onActionCollapsed();
  };
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-end", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
    _chunkUXZ3ZJ3Mcjs.Button,
    {
      type: "button",
      onClick: () => void handleReopen(),
      disabled: busy || supportSystemDown,
      loading: busy,
      children: "Reopen"
    }
  ) });
}
function OpenActions({
  ticket,
  busy,
  supportSystemDown,
  onSendMessage,
  onClose,
  onActionCollapsed
}) {
  const [messageText, setMessageText] = _react.useState.call(void 0, "");
  const [resolution, setResolution] = _react.useState.call(void 0, "");
  const [closeDialogOpen, setCloseDialogOpen] = _react.useState.call(void 0, false);
  const attachments = _chunkZDF6F7EDcjs.useChatAttachments.call(void 0, );
  const disabled = busy || supportSystemDown;
  const ticketRef = { id: ticket.id, external_id: ticket.external_id };
  const hasText = messageText.trim().length > 0;
  const hasReadyFiles = attachments.readyAttachments.length > 0;
  const canSend = !disabled && (hasText || hasReadyFiles) && !attachments.hasInflightUploads;
  const sendMessage = async () => {
    if (!canSend) return;
    const ok = await onSendMessage(ticketRef, messageText.trim(), attachments.readyAttachments);
    if (ok) {
      setMessageText("");
      attachments.clear();
    }
  };
  const confirmClose = async () => {
    setCloseDialogOpen(false);
    const ok = await onClose(ticketRef, resolution.trim() || void 0);
    setResolution("");
    if (ok) onActionCollapsed();
  };
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-3", children: [
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        _chunkZDF6F7EDcjs.Textarea,
        {
          value: messageText,
          onChange: (e) => setMessageText(e.target.value),
          placeholder: "Type a reply\u2026 (attach files if needed)",
          disabled,
          rows: 3,
          maxLength: TICKET_TEXT_MAX_CHARS
        }
      ),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        _chunkZDF6F7EDcjs.ChatAttachmentChipStrip,
        {
          attachments: attachments.attachments,
          onRemove: attachments.removeAttachment,
          disabled
        }
      ),
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between items-center gap-2 flex-wrap", children: [
        /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
          /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
            _chunkZDF6F7EDcjs.ChatAttachmentAddButton,
            {
              attachmentsEnabled: !supportSystemDown,
              attachmentsCount: attachments.attachments.length,
              onAddFiles: attachments.addFiles,
              disabled
            }
          ),
          /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs text-ods-text-secondary", children: "Attach files" })
        ] }),
        /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
          /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
            _chunkUXZ3ZJ3Mcjs.Button,
            {
              type: "button",
              variant: "transparent",
              onClick: () => setCloseDialogOpen(true),
              disabled,
              className: "bg-ods-error hover:bg-ods-error-hover text-white border-transparent",
              children: "Close ticket"
            }
          ),
          /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
            _chunkUXZ3ZJ3Mcjs.Button,
            {
              type: "button",
              onClick: () => void sendMessage(),
              disabled: !canSend,
              loading: busy,
              children: "Send reply"
            }
          )
        ] })
      ] })
    ] }),
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZDF6F7EDcjs.AlertDialog, { open: closeDialogOpen, onOpenChange: setCloseDialogOpen, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZDF6F7EDcjs.AlertDialogContent, { className: "bg-ods-card border-ods-border", children: [
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZDF6F7EDcjs.AlertDialogHeader, { children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZDF6F7EDcjs.AlertDialogTitle, { className: "text-ods-text-primary font-['DM_Sans'] text-[20px] font-semibold", children: "Close this ticket?" }),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZDF6F7EDcjs.AlertDialogDescription, { className: "text-ods-text-secondary font-['DM_Sans'] text-[14px]", children: "Add an optional resolution note below. You can reopen the ticket later if needed." })
      ] }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        _chunkZDF6F7EDcjs.Textarea,
        {
          value: resolution,
          onChange: (e) => setResolution(e.target.value),
          placeholder: "Resolution (optional)",
          rows: 3,
          maxLength: TICKET_TEXT_MAX_CHARS,
          className: "mt-2"
        }
      ),
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZDF6F7EDcjs.AlertDialogFooter, { children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          _chunkZDF6F7EDcjs.AlertDialogCancel,
          {
            disabled: busy,
            className: "bg-transparent border-ods-border text-ods-text-primary hover:bg-ods-border",
            children: "Cancel"
          }
        ),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          _chunkZDF6F7EDcjs.AlertDialogAction,
          {
            onClick: () => void confirmClose(),
            disabled: busy,
            className: "bg-ods-error hover:bg-ods-error-hover text-white",
            children: "Close ticket"
          }
        )
      ] })
    ] }) })
  ] });
}

// src/components/tickets/ticket-row.tsx

function TicketRow({
  ticket,
  expanded,
  onToggle,
  busy,
  supportSystemDown,
  onSendMessage,
  onClose,
  onReopen,
  onActionCollapsed
}) {
  const optimistic = isOptimistic(ticket);
  const rowRef = _react.useRef.call(void 0, null);
  const handleClick = _react.useCallback.call(void 0, () => {
    onToggle(ticket.id);
    _chunkZDF6F7EDcjs.scrollElementIntoView.call(void 0, rowRef.current, {
      adjustTargetY: (raw) => {
        if (!rowRef.current) return raw;
        const expandedDrawer = document.querySelector(
          'div[id^="ticket-drawer-"]'
        );
        if (!(expandedDrawer instanceof HTMLElement)) return raw;
        const drawerRect = expandedDrawer.getBoundingClientRect();
        const myRect = rowRef.current.getBoundingClientRect();
        if (drawerRect.bottom > myRect.top) return raw;
        return raw - drawerRect.height;
      }
    });
  }, [onToggle, ticket.id]);
  const tileData = {
    id: ticket.id,
    title: _nullishCoalesce(ticket.subject, () => ( "(untitled)")),
    ticketNumber: `#${ticket.external_id}`,
    status: _nullishCoalesce(ticket.status, () => ( "OPEN")),
    // Surface the HubSpot pipeline stage label ("New" / "Closed" /
    // "Waiting on contact" / "Waiting on version release") instead of
    // the canonical "Active"/"Resolved" default. The variant + check
    // icon still come from `status` (CLOSED → check; OPEN → no check),
    // so the badge accurately reflects "Closed" with a checkmark.
    statusLabel: _nullishCoalesce(ticket.pipeline_stage_label, () => ( void 0)),
    category: _nullishCoalesce(ticket.customer_company, () => ( void 0)),
    timeAgo: ticket.hubspot_updated_at ? _chunkZDF6F7EDcjs.formatRelativeTime.call(void 0, ticket.hubspot_updated_at) : void 0,
    // Linked-work chip: surfaced whenever the ticket has a linked
    // ClickUp task. Uses the linked task's own status so the chip text
    // reads "Working" / "Waiting on version release" / etc. — useful
    // signal pre-expand. Falls back to a generic "Linked work" label
    // when the task exists but its status hasn't synced yet.
    linkedTaskLabel: ticket.clickup ? ticket.clickup.status ? ticket.clickup.status.replace(/\b\w/g, (c) => c.toUpperCase()) : "Linked work" : void 0
  };
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: rowRef, className: "scroll-mt-24", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, 
    Collapsible,
    {
      open: expanded && !optimistic,
      className: "border-b border-ods-border last:border-b-0",
      children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          _chunkZDF6F7EDcjs.ChatTicketItem,
          {
            ticket: tileData,
            onClick: optimistic ? void 0 : handleClick,
            "aria-expanded": expanded && !optimistic,
            "aria-controls": `ticket-drawer-${ticket.id}`
          }
        ),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          CollapsibleContent2,
          {
            id: `ticket-drawer-${ticket.id}`,
            className: "overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
            children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
              TicketDetailDrawer,
              {
                ticket,
                busy,
                supportSystemDown,
                onSendMessage,
                onClose,
                onReopen,
                onActionCollapsed
              }
            )
          }
        )
      ]
    }
  ) });
}

// src/components/tickets/hooks/use-tickets-list.ts

var FIND_TICKET_ENDPOINT = "/api/chat/agent/find-ticket";
var DEFAULT_PAGE_SIZE = 20;
function useTicketsList(filters) {
  const customerEmail = filters.customerEmail;
  const search = (_nullishCoalesce(filters.search, () => ( ""))).trim();
  const status = (_nullishCoalesce(filters.status, () => ( ""))).trim().toLowerCase();
  const statusFilter = status && status !== "all" ? status : "";
  const page = Math.max(1, Math.floor(_nullishCoalesce(filters.page, () => ( 1))) || 1);
  const pageSize = Math.max(1, Math.min(100, Math.floor(_nullishCoalesce(filters.pageSize, () => ( DEFAULT_PAGE_SIZE))) || DEFAULT_PAGE_SIZE));
  const enabled = !!customerEmail;
  const identityKey = customerEmail || "anon";
  const query = _reactquery.useQuery.call(void 0, {
    queryKey: ["tickets", "self", identityKey, search, statusFilter, page, pageSize],
    enabled,
    // Caches OFF — every mount + every focus + every navigation triggers
    // a fresh fetch. The ticket data is the customer's own list of
    // tickets they expect to be live (sync agents reply, statuses flip,
    // new comments arrive); a stale window of any size is worse than
    // a sub-second refetch.
    staleTime: 0,
    gcTime: 0,
    refetchOnMount: "always",
    refetchOnWindowFocus: true,
    queryFn: async () => {
      const body = {
        query: search,
        page,
        pageSize
      };
      if (statusFilter) body.status = statusFilter;
      const response = await _chunkZDF6F7EDcjs.embedAuthedFetch.call(void 0, FIND_TICKET_ENDPOINT, {
        method: "POST",
        body: JSON.stringify(body)
      });
      if (!response.ok) {
        const text = await response.text().catch(() => "");
        throw new Error(`find-ticket failed: ${response.status} ${text.slice(0, 200)}`);
      }
      return await response.json();
    }
  });
  const data = query.data;
  const totalCount = _nullishCoalesce(_nullishCoalesce(_optionalChain([data, 'optionalAccess', _30 => _30.totalCount]), () => ( _optionalChain([data, 'optionalAccess', _31 => _31.count]))), () => ( (_nullishCoalesce(_optionalChain([data, 'optionalAccess', _32 => _32.tickets, 'optionalAccess', _33 => _33.length]), () => ( 0)))));
  const echoedPage = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _34 => _34.page]), () => ( page));
  const echoedPageSize = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _35 => _35.pageSize]), () => ( pageSize));
  const totalPages = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _36 => _36.totalPages]), () => ( Math.max(1, Math.ceil(totalCount / echoedPageSize))));
  return {
    tickets: _nullishCoalesce(_optionalChain([data, 'optionalAccess', _37 => _37.tickets]), () => ( [])),
    // Loading-state-truth = `data === undefined`. TanStack v5's
    // `isPending` / `isLoading` flags can be `false` in transient
    // windows where the query is enabled-but-fetch-not-yet-fired
    // OR where stale-data exists from a sibling cache slot — both
    // produced the EmptyState flash on /tickets first load. Treating
    // "no data for THIS query slot yet" as the universal loading
    // signal can't lie:
    //   - Initial render after enabled flips: data === undefined → load
    //   - Background refetch with existing data: data !== undefined → no load
    //   - Filter-change refetch landing on empty results: data?.tickets===[]
    //     + isFetching → bridge skeleton (the `||` branch)
    // Loading-state-truth = `data === undefined`. TanStack v5's
    // `isPending` / `isLoading` flags can be `false` in transient
    // windows where the query is enabled-but-fetch-not-yet-fired
    // OR where stale-data exists from a sibling cache slot. Treating
    // "no data for THIS query slot yet" as the universal loading
    // signal can't lie:
    //   - Initial render after enabled flips: data === undefined → load
    //   - Background refetch with existing data: data !== undefined → no load
    //   - Filter-change refetch landing on empty results: data?.tickets===[]
    //     + isFetching → bridge skeleton (the `||` branch)
    isLoading: enabled && (data === void 0 || query.isFetching && (_nullishCoalesce(_optionalChain([data, 'optionalAccess', _38 => _38.tickets]), () => ( []))).length === 0),
    isFetching: query.isFetching,
    error: _nullishCoalesce(query.error, () => ( null)),
    refetch: () => {
      void query.refetch();
    },
    lastUpdatedAt: query.dataUpdatedAt || null,
    totalCount,
    page: echoedPage,
    pageSize: echoedPageSize,
    totalPages
  };
}

// src/components/tickets/hooks/use-ticket-actions.ts


var TICKET_ACTION_ENDPOINT = "/api/chat/agent/ticket-action";
var MIRROR_SYNC_BACKOFF_MS = [3e3, 6e3, 12e3];
function useTicketActions(options) {
  const queryClient = _reactquery.useQueryClient.call(void 0, );
  const { prependOptimistic, removeOptimistic, removeTicketFromCache, toast: toast2, onSupportSystemDown } = options;
  const formInFlightRef = _react.useRef.call(void 0, false);
  const [isSubmittingForm, setIsSubmittingForm] = _react.useState.call(void 0, false);
  const busyRowsRef = _react.useRef.call(void 0, /* @__PURE__ */ new Set());
  const [busyRows, setBusyRows] = _react.useState.call(void 0, () => /* @__PURE__ */ new Set());
  const setRowBusy = _react.useCallback.call(void 0, (id, busy) => {
    if (busy) busyRowsRef.current.add(id);
    else busyRowsRef.current.delete(id);
    setBusyRows(new Set(busyRowsRef.current));
  }, []);
  const isRowBusy = _react.useCallback.call(void 0, (id) => busyRows.has(id), [busyRows]);
  const watcherControllersRef = _react.useRef.call(void 0, /* @__PURE__ */ new Map());
  _react.useEffect.call(void 0, () => {
    return () => {
      for (const controller of watcherControllersRef.current.values()) {
        controller.abort();
      }
      watcherControllersRef.current.clear();
    };
  }, []);
  const queueRef = _react.useRef.call(void 0, Promise.resolve());
  const enqueue = _react.useCallback.call(void 0, (work) => {
    const next = queueRef.current.then(work, work);
    queueRef.current = next.catch(() => void 0);
    return next;
  }, []);
  const executeTicketAction = _react.useCallback.call(void 0, 
    async (toolName, args) => {
      const res = await _chunkZDF6F7EDcjs.embedAuthedFetch.call(void 0, TICKET_ACTION_ENDPOINT, {
        method: "POST",
        body: JSON.stringify({ tool_name: toolName, args })
      });
      const body = await res.json().catch(() => ({}));
      if (!res.ok) {
        const code = resolveErrorCode(body.code, res.status);
        const message = body.error || `${toolName} failed (${res.status})`;
        throw new TicketActionFailure(code, message, res);
      }
      return body;
    },
    []
  );
  const watchMirrorSync = _react.useCallback.call(void 0, 
    (placeholderId, expectedTicketId) => {
      const prior = watcherControllersRef.current.get(placeholderId);
      if (prior) prior.abort();
      const controller = new AbortController();
      watcherControllersRef.current.set(placeholderId, controller);
      const schedule = async () => {
        try {
          for (let i = 0; i < MIRROR_SYNC_BACKOFF_MS.length; i++) {
            if (controller.signal.aborted) return;
            await new Promise((resolve) => {
              const t = setTimeout(resolve, MIRROR_SYNC_BACKOFF_MS[i]);
              controller.signal.addEventListener(
                "abort",
                () => {
                  clearTimeout(t);
                  resolve();
                },
                { once: true }
              );
            });
            if (controller.signal.aborted) return;
            await queryClient.invalidateQueries({ queryKey: ["tickets"] });
            if (expectedTicketId && cacheContainsTicket(queryClient, expectedTicketId)) {
              removeOptimistic(placeholderId);
              return;
            }
          }
          if (!controller.signal.aborted) {
            removeOptimistic(placeholderId);
            toast2({
              title: "Couldn't confirm ticket",
              description: "If the ticket doesn't appear shortly, please contact support.",
              variant: "destructive"
            });
          }
        } finally {
          if (watcherControllersRef.current.get(placeholderId) === controller) {
            watcherControllersRef.current.delete(placeholderId);
          }
        }
      };
      void schedule();
    },
    [queryClient, removeOptimistic, toast2]
  );
  const surfaceError = _react.useCallback.call(void 0, 
    (err, action) => {
      const mapped = mapTicketActionError(err);
      if (mapped.supportSystemDown) onSupportSystemDown();
      toast2({
        title: `Could not ${action}`,
        description: mapped.message,
        variant: "destructive"
      });
      return mapped;
    },
    [toast2, onSupportSystemDown]
  );
  const submitTicket = _react.useCallback.call(void 0, 
    async (input) => {
      if (formInFlightRef.current) return false;
      formInFlightRef.current = true;
      setIsSubmittingForm(true);
      const placeholderId = `temp-${cryptoRandomId()}`;
      const placeholder = {
        id: placeholderId,
        external_id: "Pending sync\u2026",
        subject: input.subject.trim(),
        preview: input.content.trim().slice(0, 400),
        body: input.content.trim(),
        status: "OPEN",
        pipeline_stage_label: "New",
        clickup_task_id: null,
        clickup: null,
        priority: null,
        customer_emails: [],
        customer_company: null,
        // Optimistic placeholder has no resolved HubSpot contact yet
        // — the real ticket row replaces this within a couple of
        // seconds via the mirror refetch. Drawer uses live chat
        // identity for own-replies during this window anyway.
        customer_name: null,
        hubspot_updated_at: (/* @__PURE__ */ new Date()).toISOString(),
        _optimistic: true
      };
      prependOptimistic(placeholder);
      try {
        return await enqueue(async () => {
          const result = await executeTicketAction("create_ticket", {
            subject: input.subject.trim(),
            content: input.content.trim(),
            ..._optionalChain([input, 'access', _39 => _39.attachments, 'optionalAccess', _40 => _40.length]) ? { attachments: input.attachments } : {}
          });
          if (result.mirror_synced === false) {
            toast2(TOAST_COPY.open_mirror_pending);
            watchMirrorSync(placeholderId, result.ticket_id);
          } else {
            toast2(TOAST_COPY.open_success);
            await queryClient.invalidateQueries({ queryKey: ["tickets"] });
            removeOptimistic(placeholderId);
          }
          return true;
        });
      } catch (err) {
        removeOptimistic(placeholderId);
        surfaceError(err, "open ticket");
        return false;
      } finally {
        formInFlightRef.current = false;
        setIsSubmittingForm(false);
      }
    },
    [
      enqueue,
      executeTicketAction,
      prependOptimistic,
      removeOptimistic,
      queryClient,
      toast2,
      watchMirrorSync,
      surfaceError
    ]
  );
  const updateTicket = _react.useCallback.call(void 0, 
    async (ticket, serverArgs, successCopy, action) => {
      if (busyRowsRef.current.has(ticket.id)) return false;
      setRowBusy(ticket.id, true);
      try {
        return await enqueue(async () => {
          await executeTicketAction("update_ticket", {
            ...serverArgs,
            ticket_id: ticket.external_id
          });
          toast2(successCopy);
          await Promise.all([
            queryClient.invalidateQueries({ queryKey: ["tickets"] }),
            queryClient.invalidateQueries({ queryKey: ["ticket-engagements"] })
          ]);
          return true;
        });
      } catch (err) {
        const mapped = surfaceError(err, action);
        if (mapped.removeRowFromCache) {
          removeTicketFromCache(ticket.id);
        }
        return false;
      } finally {
        setRowBusy(ticket.id, false);
      }
    },
    // `busyRowsRef` is read via .current — needs no dep entry. `busyRows`
    // state isn't read inside this callback (only by `isRowBusy` selector
    // outside), so listing it would churn the closure on every flag flip
    // and cascade-recreate addNote/closeTicket/etc.
    [setRowBusy, enqueue, executeTicketAction, queryClient, toast2, surfaceError, removeTicketFromCache]
  );
  const sendMessage = _react.useCallback.call(void 0, 
    (ticket, text, attachments) => {
      const trimmed = text.trim();
      const hasText = trimmed.length > 0;
      const hasFiles = attachments.length > 0;
      if (!hasText && !hasFiles) return Promise.resolve(false);
      return updateTicket(
        ticket,
        {
          ...hasText ? { content_addendum: trimmed } : {},
          ...hasFiles ? { attachments } : {}
        },
        TOAST_COPY.comment_success,
        "send message"
      );
    },
    [updateTicket]
  );
  const closeTicket = _react.useCallback.call(void 0, 
    (ticket, resolution) => updateTicket(
      ticket,
      {
        status: "CLOSED",
        ..._optionalChain([resolution, 'optionalAccess', _41 => _41.trim, 'call', _42 => _42()]) ? { resolution: resolution.trim() } : {}
      },
      TOAST_COPY.close_success,
      "close ticket"
    ),
    [updateTicket]
  );
  const reopenTicket = _react.useCallback.call(void 0, 
    (ticket) => updateTicket(ticket, { status: "OPEN" }, TOAST_COPY.reopen_success, "reopen ticket"),
    [updateTicket]
  );
  return _react.useMemo.call(void 0, 
    () => ({
      submitTicket,
      sendMessage,
      closeTicket,
      reopenTicket,
      isSubmittingForm,
      isRowBusy
    }),
    [submitTicket, sendMessage, closeTicket, reopenTicket, isSubmittingForm, isRowBusy]
  );
}
var TicketActionFailure = class extends Error {
  constructor(code, message, response) {
    super(message);
    this.code = code;
    this.response = response;
  }
};
function mapTicketActionError(err) {
  if (err instanceof TicketActionFailure) {
    switch (err.code) {
      case "PROPOSAL_NOT_CLAIMABLE":
        return {
          code: err.code,
          message: "This action was already processed.",
          supportSystemDown: false,
          removeRowFromCache: false
        };
      case "TICKET_NOT_FOUND":
        return {
          code: err.code,
          message: "This ticket is no longer available.",
          supportSystemDown: false,
          removeRowFromCache: true
        };
      case "TICKET_OWNERSHIP_DENIED":
        return {
          code: err.code,
          message: "You can only act on tickets you opened.",
          supportSystemDown: false,
          removeRowFromCache: false
        };
      case "HUBSPOT_DISCONNECTED":
        return {
          code: err.code,
          message: "Support system temporarily unavailable.",
          supportSystemDown: true,
          removeRowFromCache: false
        };
      case "RATE_LIMITED": {
        const retryAfterRaw = _optionalChain([err, 'access', _43 => _43.response, 'optionalAccess', _44 => _44.headers, 'access', _45 => _45.get, 'call', _46 => _46("Retry-After")]);
        const retryAfterSeconds = retryAfterRaw ? parseInt(retryAfterRaw, 10) : void 0;
        return {
          code: err.code,
          message: retryAfterSeconds ? `Too many actions. Try again in ${retryAfterSeconds}s.` : "Too many actions. Try again shortly.",
          supportSystemDown: false,
          removeRowFromCache: false,
          ...retryAfterSeconds ? { retryAfterSeconds } : {}
        };
      }
      case "INVALID_TOOL_ARGS":
        return {
          code: err.code,
          message: "Your input was rejected. Please review and try again.",
          supportSystemDown: false,
          removeRowFromCache: false
        };
      default:
        return {
          code: "UNKNOWN",
          message: err.message || "Something went wrong. Please try again.",
          supportSystemDown: false,
          removeRowFromCache: false
        };
    }
  }
  return {
    code: "UNKNOWN",
    message: err instanceof Error ? err.message : "Something went wrong. Please try again.",
    supportSystemDown: false,
    removeRowFromCache: false
  };
}
function cryptoRandomId() {
  if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
    return crypto.randomUUID();
  }
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
}
function cacheContainsTicket(queryClient, expectedTicketId) {
  const entries = queryClient.getQueriesData({ queryKey: ["tickets"] });
  for (const [, data] of entries) {
    if (Array.isArray(data) && data.some((t) => t.external_id === expectedTicketId)) {
      return true;
    }
  }
  return false;
}
function resolveErrorCode(bodyCode, status) {
  if (bodyCode) return bodyCode;
  if (status === 429) return "RATE_LIMITED";
  if (status === 412) return "HUBSPOT_DISCONNECTED";
  return "UNKNOWN";
}

// src/components/tickets/ticket-center.tsx

function TicketCenter({ toast: toast2 = _chunkWT5JV2GScjs.toast } = {}) {
  const identity = _chunkZDF6F7EDcjs.useChatIdentity.call(void 0, );
  if (identity.isLoading) {
    return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TicketCenterSkeleton, {});
  }
  if (identity.authTier === "anon" || !_optionalChain([identity, 'access', _47 => _47.user, 'optionalAccess', _48 => _48.email])) {
    return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      _chunk35XIT2CFcjs.EmptyState,
      {
        type: "generic",
        title: "Sign in to manage tickets",
        description: "View, open, and follow up on support tickets after signing in.",
        showCTA: false
      }
    );
  }
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
    TicketCenterAuthed,
    {
      toast: toast2,
      sessionEmail: identity.user.email
    }
  );
}
function TicketCenterAuthed({
  toast: toast2,
  sessionEmail
}) {
  const queryClient = _reactquery.useQueryClient.call(void 0, );
  const { tickets, isLoading, isFetching, refetch, lastUpdatedAt } = useTicketsList({
    customerEmail: sessionEmail
  });
  const [optimisticTickets, setOptimisticTickets] = _react.useState.call(void 0, []);
  const [expandedTicketId, setExpandedTicketId] = _react.useState.call(void 0, null);
  const [supportSystemDown, setSupportSystemDown] = _react.useState.call(void 0, false);
  const prependOptimistic = _react.useCallback.call(void 0, (placeholder) => {
    setOptimisticTickets((prev) => [placeholder, ...prev]);
  }, []);
  const removeOptimistic = _react.useCallback.call(void 0, (placeholderId) => {
    setOptimisticTickets((prev) => prev.filter((t) => t.id !== placeholderId));
    setExpandedTicketId((prev) => prev === placeholderId ? null : prev);
  }, []);
  const removeTicketFromCache = _react.useCallback.call(void 0, 
    (ticketId) => {
      queryClient.setQueriesData(
        { queryKey: ["tickets"] },
        (prev) => (_nullishCoalesce(prev, () => ( []))).filter((t) => t.id !== ticketId)
      );
      setExpandedTicketId((prev) => prev === ticketId ? null : prev);
    },
    [queryClient]
  );
  const actions = useTicketActions({
    prependOptimistic,
    removeOptimistic,
    removeTicketFromCache,
    toast: toast2,
    onSupportSystemDown: () => setSupportSystemDown(true)
  });
  const toggleRow = _react.useCallback.call(void 0, (id) => {
    setExpandedTicketId((prev) => prev === id ? null : id);
  }, []);
  const merged = [...optimisticTickets, ...tickets];
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-6", children: [
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      TicketOpenForm,
      {
        onSubmit: (input) => actions.submitTicket(input),
        isSubmitting: actions.isSubmittingForm,
        supportSystemDown
      }
    ),
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between gap-3", children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs font-medium text-ods-text-secondary uppercase tracking-wider", children: "Your Current Tickets" }),
        /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3 text-xs text-ods-text-secondary", children: [
          lastUpdatedAt && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { children: [
            "Updated ",
            _chunkZDF6F7EDcjs.formatRelativeTime.call(void 0, new Date(lastUpdatedAt))
          ] }),
          /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
            _chunkUXZ3ZJ3Mcjs.Button,
            {
              type: "button",
              variant: "transparent",
              size: "small",
              onClick: refetch,
              disabled: isFetching,
              "aria-label": "Refresh ticket list",
              leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.RefreshCw, { className: "h-4 w-4" })
            }
          )
        ] })
      ] }),
      isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TicketListSkeleton, {}) : merged.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZDF6F7EDcjs.Card, { className: "p-6", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        _chunk35XIT2CFcjs.EmptyState,
        {
          type: "generic",
          title: "No tickets yet",
          description: "Open one above to start the conversation.",
          showCTA: false
        }
      ) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZDF6F7EDcjs.Card, { className: "overflow-hidden", children: merged.map((ticket) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        TicketRow,
        {
          ticket,
          expanded: expandedTicketId === ticket.id,
          onToggle: toggleRow,
          busy: isOptimistic(ticket) ? false : actions.isRowBusy(ticket.id),
          supportSystemDown,
          onSendMessage: actions.sendMessage,
          onClose: actions.closeTicket,
          onReopen: actions.reopenTicket,
          onActionCollapsed: () => setExpandedTicketId(null)
        },
        ticket.id
      )) })
    ] })
  ] });
}
function TicketCenterSkeleton() {
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-6", children: [
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZDF6F7EDcjs.Card, { className: "p-6", children: [
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUXZ3ZJ3Mcjs.Skeleton, { className: "h-7 w-48 mb-4" }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUXZ3ZJ3Mcjs.Skeleton, { className: "h-10 w-full mb-3" }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUXZ3ZJ3Mcjs.Skeleton, { className: "h-24 w-full" })
    ] }),
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TicketListSkeleton, {})
  ] });
}
function TicketListSkeleton() {
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZDF6F7EDcjs.Card, { className: "overflow-hidden", children: [0, 1, 2].map((i) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "h-20 px-4 flex items-center gap-4 border-b border-ods-border last:border-b-0", children: [
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 flex flex-col gap-2", children: [
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUXZ3ZJ3Mcjs.Skeleton, { className: "h-4 w-2/3" }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUXZ3ZJ3Mcjs.Skeleton, { className: "h-3 w-full" })
    ] }),
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUXZ3ZJ3Mcjs.Skeleton, { className: "h-8 w-20" }),
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUXZ3ZJ3Mcjs.Skeleton, { className: "h-8 w-16" })
  ] }, i)) });
}

// src/components/tickets/help-center-list.tsx


_chunk35XIT2CFcjs.init_unified_pagination.call(void 0, );

// src/components/tickets/help-center-card.tsx


var STICKY_HEADER_OFFSET_PX = 96;
function HelpCenterCard({
  ticket,
  expanded,
  onToggle,
  busy,
  supportSystemDown,
  onSendMessage,
  onClose,
  onReopen,
  onActionCollapsed
}) {
  const optimistic = isOptimistic(ticket);
  const rawStatus = (_nullishCoalesce(ticket.status, () => ( "OPEN"))).toUpperCase();
  const priority = (_nullishCoalesce(ticket.priority, () => ( ""))).toUpperCase();
  const relativeUpdated = ticket.hubspot_updated_at ? _chunkZDF6F7EDcjs.formatRelativeTime.call(void 0, ticket.hubspot_updated_at) : "recently";
  const title = (ticket.subject || "").trim() || "(untitled)";
  const subtitle = `UPDATED ${relativeUpdated}, #${ticket.external_id || "\u2014"}${ticket.pipeline_stage_label ? `, ${ticket.pipeline_stage_label}` : ""}`;
  const description = _nullishCoalesce(_nullishCoalesce(ticket.preview, () => ( ticket.body)), () => ( ""));
  const isExpandable = !optimistic;
  const isExpanded = expanded && isExpandable;
  const rowRef = _react.useRef.call(void 0, null);
  const handleClick = _react.useCallback.call(void 0, () => {
    onToggle(ticket.id);
    _chunkZDF6F7EDcjs.scrollElementIntoView.call(void 0, rowRef.current, {
      headerOffset: STICKY_HEADER_OFFSET_PX,
      adjustTargetY: (raw) => {
        if (!rowRef.current) return raw;
        const expandedDrawer = document.querySelector(
          'div[id^="help-center-drawer-"]'
        );
        if (!(expandedDrawer instanceof HTMLElement)) return raw;
        const drawerRect = expandedDrawer.getBoundingClientRect();
        const myRect = rowRef.current.getBoundingClientRect();
        if (drawerRect.bottom > myRect.top) return raw;
        return raw - drawerRect.height;
      }
    });
  }, [onToggle, ticket.id]);
  const rightBadges = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      _chunkZDF6F7EDcjs.StatusBadge,
      {
        text: rawStatus,
        colorScheme: _chunkZDF6F7EDcjs.getStatusColorScheme.call(void 0, rawStatus),
        variant: "card",
        className: "border border-ods-border"
      }
    ),
    priority && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      _chunkZDF6F7EDcjs.StatusBadge,
      {
        text: priority,
        colorScheme: mapPriorityScheme(priority),
        variant: "card",
        className: "border border-ods-border"
      }
    )
  ] });
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, 
    "div",
    {
      ref: rowRef,
      style: { scrollMarginTop: STICKY_HEADER_OFFSET_PX },
      className: `border-b border-ods-border last:border-b-0 ${optimistic ? "opacity-60" : ""}`,
      "aria-busy": optimistic || void 0,
      children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          "button",
          {
            type: "button",
            onClick: isExpandable ? handleClick : void 0,
            disabled: !isExpandable,
            "aria-expanded": isExpandable ? isExpanded : void 0,
            "aria-controls": isExpanded ? `help-center-drawer-${ticket.id}` : void 0,
            className: "w-full text-left p-[12px] md:p-[16px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent focus-visible:ring-inset disabled:cursor-default",
            children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
              _chunk35XIT2CFcjs.DevCardRowContent,
              {
                title,
                subtitle,
                description,
                emptyDescription: "No description provided",
                rightBadges
              }
            )
          }
        ),
        isExpanded && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { id: `help-center-drawer-${ticket.id}`, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
          TicketDetailDrawer,
          {
            ticket,
            busy,
            supportSystemDown,
            onSendMessage,
            onClose,
            onReopen,
            onActionCollapsed
          }
        ) })
      ]
    }
  );
}
function mapPriorityScheme(priority) {
  if (priority === "HIGH" || priority === "URGENT") return "error";
  if (priority === "MEDIUM") return "warning";
  return "default";
}

// src/components/tickets/help-center-create-form.tsx


var SUBJECT_MAX_CHARS = 200;
function HelpCenterCreateFormSkeleton() {
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "h-full flex flex-col border border-ods-border rounded-2xl md:rounded-3xl p-6 md:p-8 lg:p-10", children: [
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mb-6 md:mb-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-10 w-72 bg-ods-border rounded animate-pulse mb-3 md:mb-4" }) }),
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col flex-grow space-y-4 md:space-y-6", children: [
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", "aria-hidden": true }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", "aria-hidden": true }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", "aria-hidden": true }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", "aria-hidden": true }),
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[27px] w-20 bg-ods-border rounded animate-pulse mb-1" }),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-12 w-full bg-ods-border rounded animate-pulse" })
      ] }),
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col flex-grow", children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[27px] w-32 bg-ods-border rounded animate-pulse mb-1" }),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-24 w-full bg-ods-border rounded animate-pulse flex-grow" })
      ] }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-7 w-7 bg-ods-border rounded animate-pulse shrink-0" }),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-4 w-40 bg-ods-border rounded animate-pulse" })
      ] }) }),
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col md:flex-row gap-4 md:gap-6 items-center justify-end w-full pt-2 mt-auto", children: [
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-4 w-72 bg-ods-border rounded animate-pulse" }),
        /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-12 w-32 bg-ods-border rounded animate-pulse" })
      ] })
    ] })
  ] });
}
function HelpCenterCreateForm({
  actions,
  sessionName,
  sessionEmail,
  supportSystemDown = false
}) {
  const [subject, setSubject] = _react.useState.call(void 0, "");
  const [subjectError, setSubjectError] = _react.useState.call(void 0, null);
  const subjectField = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
    /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZDF6F7EDcjs.Label, { htmlFor: "help-center-subject", children: [
      "Subject",
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-ods-accent", children: "*" })
    ] }),
    /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      _chunkUXZ3ZJ3Mcjs.Input,
      {
        id: "help-center-subject",
        type: "text",
        value: subject,
        onChange: (e) => {
          setSubject(e.target.value);
          if (subjectError) setSubjectError(null);
        },
        placeholder: "Briefly describe what's going on",
        maxLength: SUBJECT_MAX_CHARS,
        "aria-invalid": !!subjectError,
        "aria-describedby": subjectError ? "help-center-subject-error" : void 0,
        disabled: supportSystemDown,
        className: "bg-ods-card border-ods-border text-ods-text-primary placeholder-ods-text-secondary px-3 h-12"
      }
    ),
    subjectError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      "span",
      {
        id: "help-center-subject-error",
        className: "text-ods-error text-xs font-['DM_Sans'] mt-1",
        children: subjectError
      }
    )
  ] });
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
    _chunkOTKJASSXcjs.ContactForm,
    {
      title: "Open a new ticket",
      footerText: "The support team typically responds within one business day.",
      hideFields: ["name", "email", "companySize", "referralSource", "helpCategory"],
      defaultValues: {
        name: sessionName,
        email: sessionEmail,
        helpCategory: "Support Request"
      },
      extraTopField: subjectField,
      submitLabel: "Open ticket",
      attachmentsEnabled: true,
      onCustomSubmit: async (data, attachments) => {
        const trimmedSubject = subject.trim();
        if (!trimmedSubject) {
          setSubjectError("Subject is required");
          throw new Error("SUBJECT_REQUIRED");
        }
        setSubjectError(null);
        const ok = await actions.submitTicket({
          subject: trimmedSubject,
          content: data.message,
          attachments: attachments.length > 0 ? attachments : void 0
        });
        if (ok) {
          setSubject("");
        } else {
          throw new Error("TICKET_SUBMIT_FAILED");
        }
      }
    }
  );
}

// src/components/tickets/help-center-list.tsx

function HelpCenterList({ toast: toast2 = _chunkWT5JV2GScjs.toast } = {}) {
  const identity = _chunkZDF6F7EDcjs.useChatIdentity.call(void 0, );
  const searchParams = _chunkG7UE6RKVcjs.useSearchParams.call(void 0, );
  const router = _chunkG7UE6RKVcjs.useRouter.call(void 0, );
  const pathname = _chunkG7UE6RKVcjs.usePathname.call(void 0, );
  const search = searchParams.get("search") || "";
  const status = searchParams.get("status") || "all";
  const rawPage = Number(searchParams.get("page"));
  const page = Number.isFinite(rawPage) && rawPage > 0 ? Math.floor(rawPage) : 1;
  if (identity.isLoading) {
    return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.DevSectionPage, { sectionKey: "tickets", preControls: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpCenterCreateFormSkeleton, {}), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.DevCardRowSkeletonList, {}) });
  }
  if (identity.authTier === "anon" || !_optionalChain([identity, 'access', _49 => _49.user, 'optionalAccess', _50 => _50.email])) {
    return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.DevSectionPage, { sectionKey: "tickets", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      _chunk35XIT2CFcjs.EmptyState,
      {
        type: "generic",
        title: "Sign in to manage tickets",
        description: "View, open, and follow up on support tickets after signing in.",
        showCTA: false
      }
    ) });
  }
  const sessionName = [_optionalChain([identity, 'access', _51 => _51.user, 'optionalAccess', _52 => _52.firstName]), _optionalChain([identity, 'access', _53 => _53.user, 'optionalAccess', _54 => _54.lastName])].filter(Boolean).join(" ").trim() || _optionalChain([identity, 'access', _55 => _55.user, 'optionalAccess', _56 => _56.email, 'optionalAccess', _57 => _57.split, 'call', _58 => _58("@"), 'access', _59 => _59[0]]) || "Customer";
  const sessionEmail = identity.user.email;
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
    HelpCenterListAuthed,
    {
      search,
      status,
      page,
      searchParams,
      router,
      pathname,
      toast: toast2,
      sessionName,
      sessionEmail
    }
  );
}
function HelpCenterListAuthed({
  search,
  status,
  page,
  searchParams,
  router,
  pathname,
  toast: toast2,
  sessionName,
  sessionEmail
}) {
  const queryClient = _reactquery.useQueryClient.call(void 0, );
  const { tickets, isLoading, isFetching, error, refetch, totalPages } = useTicketsList({
    // `sessionEmail` is drilled in from the parent — see the same
    // pattern + race-cause rationale documented in
    // `HelpCenterCreateForm.sessionName/sessionEmail`. Calling
    // `useChatIdentity` inside `useTicketsList` would race the
    // parent's already-resolved identity and produce an empty-state
    // flash on first render.
    customerEmail: sessionEmail,
    search,
    status,
    page
  });
  const [optimisticTickets, setOptimisticTickets] = _react.useState.call(void 0, []);
  const [expandedTicketId, setExpandedTicketId] = _react.useState.call(void 0, null);
  const [supportSystemDown, setSupportSystemDown] = _react.useState.call(void 0, false);
  const prependOptimistic = _react.useCallback.call(void 0, (placeholder) => {
    setOptimisticTickets((prev) => [placeholder, ...prev]);
  }, []);
  const removeOptimistic = _react.useCallback.call(void 0, (placeholderId) => {
    setOptimisticTickets((prev) => prev.filter((t) => t.id !== placeholderId));
    setExpandedTicketId((prev) => prev === placeholderId ? null : prev);
  }, []);
  const removeTicketFromCache = _react.useCallback.call(void 0, 
    (ticketId) => {
      queryClient.setQueriesData(
        { queryKey: ["tickets"] },
        (prev) => (_nullishCoalesce(prev, () => ( []))).filter((t) => t.id !== ticketId)
      );
      setExpandedTicketId((prev) => prev === ticketId ? null : prev);
    },
    [queryClient]
  );
  const actions = useTicketActions({
    prependOptimistic,
    removeOptimistic,
    removeTicketFromCache,
    toast: toast2,
    onSupportSystemDown: () => setSupportSystemDown(true)
  });
  const toggleRow = _react.useCallback.call(void 0, (id) => {
    setExpandedTicketId((prev) => prev === id ? null : id);
  }, []);
  const merged = [...optimisticTickets, ...tickets];
  const hasActiveFilters = search !== "" || status !== "" && status !== "all";
  const hasResults = merged.length > 0;
  const form = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
    HelpCenterCreateForm,
    {
      actions,
      sessionName,
      sessionEmail,
      supportSystemDown
    }
  );
  const body = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "w-full flex flex-col gap-[40px]", children: [
    error && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-ods-card border border-ods-border rounded-[6px] p-[40px] text-center w-full flex flex-col items-center gap-3", children: [
      /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-ods-error text-base", children: [
        "Couldn\u2019t load your tickets. ",
        error.message
      ] }),
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUXZ3ZJ3Mcjs.Button, { type: "button", variant: "accent", onClick: () => refetch(), children: "Retry" })
    ] }),
    !error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full", children: isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.DevCardRowSkeletonList, {}) : !hasResults && isFetching ? (
      // Bridge state — background refetch in flight and the
      // optimistic placeholder was just removed by the mutation
      // callback. Without this branch "No tickets yet" would flash
      // for ~50ms between `removeOptimistic` and the server
      // response landing.
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.DevCardRowSkeletonList, { rows: 1 })
    ) : !hasResults ? hasActiveFilters ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      _chunk35XIT2CFcjs.EmptyState,
      {
        type: "search",
        title: "No tickets found",
        description: "No tickets match your current filters. Try clearing them or broadening your search.",
        showCTA: true,
        ctaText: "Reset filters",
        onCtaClick: () => {
          const params = new URLSearchParams(searchParams.toString());
          params.delete("search");
          params.delete("status");
          router.replace(`${pathname}?${params.toString()}`, { scroll: false });
        }
      }
    ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
      _chunk35XIT2CFcjs.EmptyState,
      {
        type: "generic",
        title: "No tickets yet",
        description: "Open one above to start the conversation with the support team.",
        showCTA: false
      }
    ) : (
      // `overflow-clip` (NOT `overflow-hidden`) — both visually
      // clip the rounded corners, but `hidden` makes the element
      // a "scroll container" per CSSOM spec, which causes
      // `scrollIntoView` calls inside (`<HelpCenterCard>` click
      // handlers) to try scrolling THIS div (can't, overflow
      // hidden) instead of bubbling up to the window. `clip`
      // keeps the visual clip but NOT the scroll-container
      // status, so click-to-scroll actually moves the page.
      /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-ods-card border border-ods-border rounded-[6px] overflow-clip w-full", children: merged.map((ticket) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 
        HelpCenterCard,
        {
          ticket,
          expanded: expandedTicketId === ticket.id,
          onToggle: toggleRow,
          busy: isOptimistic(ticket) ? false : actions.isRowBusy(ticket.id),
          supportSystemDown,
          onSendMessage: actions.sendMessage,
          onClose: actions.closeTicket,
          onReopen: actions.reopenTicket,
          onActionCollapsed: () => setExpandedTicketId(null)
        },
        ticket.id
      )) })
    ) }),
    !error && totalPages > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.UnifiedPagination, { currentPage: page, totalPages })
  ] });
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk35XIT2CFcjs.DevSectionPage, { sectionKey: "tickets", preControls: form, children: body });
}
















exports.HelpCenterCard = HelpCenterCard; exports.HelpCenterCreateForm = HelpCenterCreateForm; exports.HelpCenterCreateFormSkeleton = HelpCenterCreateFormSkeleton; exports.HelpCenterList = HelpCenterList; exports.TICKET_TOAST_COPY = TOAST_COPY; exports.TicketCenter = TicketCenter; exports.TicketDetailDrawer = TicketDetailDrawer; exports.TicketLinkedDeliveryCard = TicketLinkedDeliveryCard; exports.TicketOpenForm = TicketOpenForm; exports.TicketRow = TicketRow; exports.isOptimistic = isOptimistic; exports.mapTicketActionError = mapTicketActionError; exports.useTicketActions = useTicketActions; exports.useTicketEngagements = useTicketEngagements; exports.useTicketsList = useTicketsList;
//# sourceMappingURL=index.cjs.map