{"version":3,"sources":["../../../../src/primitives/Scheduling/Admin/ResourcesTable.tsx"],"names":[],"mappings":"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","file":"ResourcesTable.mjs","sourcesContent":["import { useCallback, useState, type FormEvent, type ReactNode } from 'react';\nimport type { UseSchedulingAdminResult } from '../../../hooks/useSchedulingAdmin';\nimport type { UseGoogleCalendarConnectResult } from '../../../hooks/useGoogleCalendarConnect';\nimport type { SchedulingResource } from '../../../types/scheduling';\n\nexport interface SchedulingResourcesTableRowActions {\n  update: (patch: Partial<SchedulingResource>) => Promise<void>;\n  remove: () => Promise<void>;\n  /** Whether this row is currently expanded. Driven by table-internal state. */\n  expanded: boolean;\n  /** Flip expansion state for this row. */\n  toggleExpanded: () => void;\n}\n\nexport interface SchedulingResourcesTableProps {\n  admin: UseSchedulingAdminResult;\n  /**\n   * Optional. When provided, the sub-calendar dropdown is sourced from\n   * `connect.availableCalendars`. When omitted (or when the integration is\n   * not connected), the dropdown collapses to a \"Connect Google to map\n   * calendars\" hint.\n   */\n  connect?: UseGoogleCalendarConnectResult;\n  className?: string;\n  rowClassName?: string;\n  /**\n   * Wrapper className applied to the per-row expansion container. Only\n   * rendered when `renderExpanded` returns non-null and the row is in the\n   * expanded state.\n   */\n  expandedClassName?: string;\n  /**\n   * Class for the expand/collapse toggle button when using the default row\n   * renderer. Defaults to `buttonClassName`.\n   */\n  expandToggleClassName?: string;\n  inputClassName?: string;\n  buttonClassName?: string;\n  onCreated?: (resource: SchedulingResource) => void;\n  renderRow?: (\n    resource: SchedulingResource,\n    actions: SchedulingResourcesTableRowActions,\n  ) => ReactNode;\n  /**\n   * Optional renderer for the per-row expanded panel. When provided, each\n   * row gets a built-in expand toggle (default renderer) or `actions.toggleExpanded`\n   * (custom renderer) and the returned node renders inside the row's\n   * expansion container.\n   *\n   * Use this to mount per-stylist sub-primitives like\n   * `<SchedulingServicesPicker>`, `<SchedulingWorkingHoursEditor>`, and\n   * `<SchedulingTimeOffList>`. When omitted, no expansion UI is rendered —\n   * the table behaves exactly as it did before this prop existed.\n   */\n  renderExpanded?: (\n    resource: SchedulingResource,\n    actions: SchedulingResourcesTableRowActions,\n  ) => ReactNode;\n  addLabel?: ReactNode;\n}\n\nconst EMPTY_DRAFT: Partial<SchedulingResource> = {\n  name: '',\n  active: true,\n};\n\nexport function SchedulingResourcesTable({\n  admin,\n  connect,\n  className,\n  rowClassName,\n  expandedClassName,\n  expandToggleClassName,\n  inputClassName,\n  buttonClassName,\n  onCreated,\n  renderRow,\n  renderExpanded,\n  addLabel,\n}: SchedulingResourcesTableProps) {\n  const [draft, setDraft] = useState<Partial<SchedulingResource>>(EMPTY_DRAFT);\n\n  // Expansion state lives in the table, keyed by resource id. The default-row\n  // renderer wires the toggle through a built-in button; custom renderers\n  // use actions.toggleExpanded. Multiple rows can be expanded at once — the\n  // common admin task is \"configure rico, then alex\" and forcing only-one-at-a-time\n  // collapses any unsaved scroll position when the second row opens.\n  const [expandedIds, setExpandedIds] = useState<Set<string>>(() => new Set());\n  const toggleExpanded = useCallback((id: string) => {\n    setExpandedIds((prev) => {\n      const next = new Set(prev);\n      if (next.has(id)) next.delete(id);\n      else next.add(id);\n      return next;\n    });\n  }, []);\n\n  const submitNew = async (e: FormEvent<HTMLFormElement>) => {\n    e.preventDefault();\n    if (!draft.name) return;\n    const created = await admin.resources.create(draft);\n    if (created) {\n      setDraft(EMPTY_DRAFT);\n      onCreated?.(created);\n    }\n  };\n\n  const calendarsConnected =\n    connect && connect.status === 'connected' && connect.availableCalendars.length > 0;\n\n  return (\n    <div className={className}>\n      {admin.resources.loading && admin.resources.list.length === 0 ? (\n        <div>Loading resources…</div>\n      ) : null}\n      {admin.resources.error ? (\n        <div role=\"alert\">{admin.resources.error}</div>\n      ) : null}\n\n      {admin.resources.list.map((resource) => {\n        const expanded = expandedIds.has(resource.id);\n        const actions: SchedulingResourcesTableRowActions = {\n          update: async (patch: Partial<SchedulingResource>) => {\n            await admin.resources.update(resource.id, patch);\n          },\n          remove: async () => {\n            await admin.resources.remove(resource.id);\n          },\n          expanded,\n          toggleExpanded: () => toggleExpanded(resource.id),\n        };\n\n        const expandedNode =\n          renderExpanded && expanded ? renderExpanded(resource, actions) : null;\n\n        if (renderRow) {\n          return (\n            <div key={resource.id}>\n              {renderRow(resource, actions)}\n              {expandedNode ? (\n                <div className={expandedClassName}>{expandedNode}</div>\n              ) : null}\n            </div>\n          );\n        }\n\n        return (\n          <div key={resource.id}>\n            <div className={rowClassName}>\n              <input\n                type=\"text\"\n                defaultValue={resource.name}\n                onBlur={(e) => {\n                  const next = e.target.value.trim();\n                  if (next && next !== resource.name) actions.update({ name: next });\n                }}\n                className={inputClassName}\n              />\n              {calendarsConnected ? (\n                <select\n                  value={resource.google_calendar_id ?? ''}\n                  onChange={(e) =>\n                    actions.update({ google_calendar_id: e.target.value || null })\n                  }\n                  className={inputClassName}\n                >\n                  <option value=\"\">No calendar mirror</option>\n                  {connect!.availableCalendars.map((cal) => (\n                    <option key={cal.id} value={cal.id}>\n                      {cal.summary}\n                      {cal.primary ? ' (primary)' : ''}\n                    </option>\n                  ))}\n                </select>\n              ) : (\n                <small>\n                  {connect\n                    ? 'Connect Google to map calendars'\n                    : 'Calendar mirror disabled'}\n                </small>\n              )}\n              <button\n                type=\"button\"\n                className={buttonClassName}\n                onClick={() => actions.update({ active: !resource.active })}\n              >\n                {resource.active ? 'Active' : 'Hidden'}\n              </button>\n              {renderExpanded ? (\n                <button\n                  type=\"button\"\n                  className={expandToggleClassName ?? buttonClassName}\n                  aria-expanded={expanded}\n                  onClick={actions.toggleExpanded}\n                >\n                  {expanded ? 'Close' : 'Configure'}\n                </button>\n              ) : null}\n              <button\n                type=\"button\"\n                className={buttonClassName}\n                onClick={() => actions.remove()}\n              >\n                Delete\n              </button>\n            </div>\n            {expandedNode ? (\n              <div className={expandedClassName}>{expandedNode}</div>\n            ) : null}\n          </div>\n        );\n      })}\n\n      <form onSubmit={submitNew} className={rowClassName}>\n        <input\n          type=\"text\"\n          required\n          placeholder=\"Name (e.g., stylist, instructor)\"\n          value={draft.name ?? ''}\n          onChange={(e) => setDraft((prev) => ({ ...prev, name: e.target.value }))}\n          className={inputClassName}\n        />\n        <input\n          type=\"email\"\n          placeholder=\"Email (optional)\"\n          value={draft.email ?? ''}\n          onChange={(e) => setDraft((prev) => ({ ...prev, email: e.target.value }))}\n          className={inputClassName}\n        />\n        <button type=\"submit\" className={buttonClassName}>\n          {addLabel ?? 'Add resource'}\n        </button>\n      </form>\n    </div>\n  );\n}\n"]}