{"version":3,"sources":["../../../../src/primitives/Scheduling/Admin/WorkingHoursEditor.tsx"],"names":[],"mappings":"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","file":"WorkingHoursEditor.mjs","sourcesContent":["import { useMemo, useState, type ReactNode } from 'react';\nimport type { UseSchedulingAdminResult } from '../../../hooks/useSchedulingAdmin';\nimport type { SchedulingWorkingHours } from '../../../types/scheduling';\n\nconst DAYS: Array<{ dow: number; label: string; short: string }> = [\n  { dow: 0, label: 'Sunday', short: 'Sun' },\n  { dow: 1, label: 'Monday', short: 'Mon' },\n  { dow: 2, label: 'Tuesday', short: 'Tue' },\n  { dow: 3, label: 'Wednesday', short: 'Wed' },\n  { dow: 4, label: 'Thursday', short: 'Thu' },\n  { dow: 5, label: 'Friday', short: 'Fri' },\n  { dow: 6, label: 'Saturday', short: 'Sat' },\n];\n\nconst DEFAULT_NEW_ROW = { start_time: '09:00', end_time: '17:00' };\n\nexport interface SchedulingWorkingHoursEditorProps {\n  admin: UseSchedulingAdminResult;\n  /**\n   * Resource whose hours we're editing. Pass `null` for site-wide hours\n   * (rows where `resource_id is null`) — used by the \"Salon hours\" panel.\n   */\n  resourceId: string | null;\n  className?: string;\n  dayClassName?: string;\n  dayLabelClassName?: string;\n  rowClassName?: string;\n  inputClassName?: string;\n  buttonClassName?: string;\n  addButtonClassName?: string;\n  emptyDayClassName?: string;\n  errorClassName?: string;\n  /** Default 'short'. Use 'long' for \"Tuesday\" instead of \"Tue\". */\n  dayLabelFormat?: 'short' | 'long';\n  /**\n   * Localized copy hooks. Defaults are English.\n   */\n  emptyDayLabel?: ReactNode;\n  addRowLabel?: ReactNode;\n  removeRowLabel?: ReactNode;\n}\n\nexport function SchedulingWorkingHoursEditor({\n  admin,\n  resourceId,\n  className,\n  dayClassName,\n  dayLabelClassName,\n  rowClassName,\n  inputClassName,\n  buttonClassName,\n  addButtonClassName,\n  emptyDayClassName,\n  errorClassName,\n  dayLabelFormat = 'short',\n  emptyDayLabel = 'Closed',\n  addRowLabel = '+ Add hours',\n  removeRowLabel = 'Remove',\n}: SchedulingWorkingHoursEditorProps) {\n  // Group existing rows by day-of-week. Multiple rows per day = split shifts\n  // (e.g. 09:00-13:00 and 14:00-18:00 with a lunch break in the middle).\n  const byDay = useMemo(() => {\n    const map = new Map<number, SchedulingWorkingHours[]>();\n    for (const row of admin.workingHours.list) {\n      // Filter to the scope we're editing — per-resource OR site-wide.\n      const matches =\n        resourceId === null ? row.resource_id === null : row.resource_id === resourceId;\n      if (!matches) continue;\n      const list = map.get(row.day_of_week) ?? [];\n      list.push(row);\n      map.set(row.day_of_week, list);\n    }\n    // Sort each day's rows by start time so split shifts read top-to-bottom.\n    for (const list of map.values()) {\n      list.sort((a, b) => a.start_time.localeCompare(b.start_time));\n    }\n    return map;\n  }, [admin.workingHours.list, resourceId]);\n\n  // Local-only \"row currently being edited\" state — we don't push every\n  // keystroke to the server. PATCH fires on blur (existing row) or on submit\n  // (new row), mirroring the ResourcesTable convention.\n  const [drafts, setDrafts] = useState<Record<number, { start_time: string; end_time: string }>>({});\n  const draftFor = (dow: number) => drafts[dow] ?? DEFAULT_NEW_ROW;\n\n  const setDraft = (dow: number, patch: Partial<{ start_time: string; end_time: string }>) =>\n    setDrafts((prev) => ({ ...prev, [dow]: { ...draftFor(dow), ...patch } }));\n\n  const addRow = async (dow: number) => {\n    const draft = draftFor(dow);\n    if (!isValidTimeRange(draft.start_time, draft.end_time)) return;\n    await admin.workingHours.create({\n      resource_id: resourceId,\n      day_of_week: dow,\n      start_time: draft.start_time,\n      end_time: draft.end_time,\n    } as Partial<SchedulingWorkingHours>);\n    setDrafts((prev) => ({ ...prev, [dow]: DEFAULT_NEW_ROW }));\n  };\n\n  const updateRow = async (\n    row: SchedulingWorkingHours,\n    patch: Partial<Pick<SchedulingWorkingHours, 'start_time' | 'end_time'>>,\n  ) => {\n    if (\n      patch.start_time === row.start_time &&\n      patch.end_time === row.end_time\n    ) {\n      return;\n    }\n    const next = { ...row, ...patch };\n    if (!isValidTimeRange(next.start_time, next.end_time)) return;\n    await admin.workingHours.update(row.id, patch);\n  };\n\n  const removeRow = async (id: string) => {\n    await admin.workingHours.remove(id);\n  };\n\n  return (\n    <div className={className}>\n      {admin.workingHours.error ? (\n        <div className={errorClassName} role=\"alert\">\n          {admin.workingHours.error}\n        </div>\n      ) : null}\n      {DAYS.map(({ dow, label, short }) => {\n        const rows = byDay.get(dow) ?? [];\n        return (\n          <div key={dow} className={dayClassName}>\n            <div className={dayLabelClassName}>\n              {dayLabelFormat === 'short' ? short : label}\n            </div>\n            {rows.length === 0 ? (\n              <div className={emptyDayClassName}>{emptyDayLabel}</div>\n            ) : null}\n            {rows.map((row) => (\n              <div key={row.id} className={rowClassName}>\n                <input\n                  type=\"time\"\n                  defaultValue={row.start_time}\n                  onBlur={(e) => updateRow(row, { start_time: e.target.value })}\n                  className={inputClassName}\n                  aria-label={`${label} start time`}\n                />\n                <input\n                  type=\"time\"\n                  defaultValue={row.end_time}\n                  onBlur={(e) => updateRow(row, { end_time: e.target.value })}\n                  className={inputClassName}\n                  aria-label={`${label} end time`}\n                />\n                <button\n                  type=\"button\"\n                  onClick={() => removeRow(row.id)}\n                  className={buttonClassName}\n                >\n                  {removeRowLabel}\n                </button>\n              </div>\n            ))}\n            <div className={rowClassName}>\n              <input\n                type=\"time\"\n                value={draftFor(dow).start_time}\n                onChange={(e) => setDraft(dow, { start_time: e.target.value })}\n                className={inputClassName}\n                aria-label={`${label} new start time`}\n              />\n              <input\n                type=\"time\"\n                value={draftFor(dow).end_time}\n                onChange={(e) => setDraft(dow, { end_time: e.target.value })}\n                className={inputClassName}\n                aria-label={`${label} new end time`}\n              />\n              <button\n                type=\"button\"\n                onClick={() => addRow(dow)}\n                className={addButtonClassName ?? buttonClassName}\n                disabled={!isValidTimeRange(draftFor(dow).start_time, draftFor(dow).end_time)}\n              >\n                {addRowLabel}\n              </button>\n            </div>\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n\nfunction isValidTimeRange(start: string, end: string): boolean {\n  // Times come in as 'HH:MM'. Compare as strings — works for ISO time-of-day\n  // because lex order matches chronological order within a day.\n  if (!/^\\d{2}:\\d{2}$/.test(start) || !/^\\d{2}:\\d{2}$/.test(end)) return false;\n  return start < end;\n}\n"]}