@wealthx/shadcn 1.5.11 → 1.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.turbo/turbo-build.log +88 -88
  2. package/CHANGELOG.md +12 -0
  3. package/dist/{chunk-O5CP6VP6.mjs → chunk-BF5FKUF6.mjs} +104 -63
  4. package/dist/{chunk-ZMTCMP2G.mjs → chunk-EB626HVW.mjs} +70 -3
  5. package/dist/chunk-KICT4VQL.mjs +508 -0
  6. package/dist/chunk-V23CBULF.mjs +432 -0
  7. package/dist/components/ui/ai-conversations.js +70 -3
  8. package/dist/components/ui/ai-conversations.mjs +1 -1
  9. package/dist/components/ui/appointment-calendar-view.js +177 -176
  10. package/dist/components/ui/appointment-calendar-view.mjs +1 -1
  11. package/dist/components/ui/bank-statement-generate-dialog.js +209 -107
  12. package/dist/components/ui/bank-statement-generate-dialog.mjs +2 -1
  13. package/dist/components/ui/resource-center/index.js +1030 -0
  14. package/dist/components/ui/resource-center/index.mjs +29 -0
  15. package/dist/index.js +661 -403
  16. package/dist/index.mjs +16 -14
  17. package/dist/styles.css +1 -1
  18. package/package.json +4 -4
  19. package/src/components/index.tsx +2 -0
  20. package/src/components/ui/ai-conversations.tsx +157 -23
  21. package/src/components/ui/appointment-calendar-view.tsx +211 -199
  22. package/src/components/ui/bank-statement-generate-dialog.tsx +147 -96
  23. package/src/components/ui/resource-center/index.tsx +35 -0
  24. package/src/components/ui/resource-center/resource-cards.tsx +218 -0
  25. package/src/components/ui/resource-center/resource-carousel.tsx +122 -0
  26. package/src/components/ui/resource-center/resource-center-header.tsx +95 -0
  27. package/src/components/ui/resource-center/resource-email-editor-dialog.tsx +131 -0
  28. package/src/components/ui/resource-center/resource-modal.tsx +76 -0
  29. package/src/components/ui/resource-center/types.ts +81 -0
  30. package/src/styles/styles-css.ts +1 -1
  31. package/tsup.config.ts +1 -1
  32. package/dist/chunk-IODGRCQG.mjs +0 -438
  33. package/dist/chunk-XYWEGBAA.mjs +0 -348
  34. package/dist/components/ui/resource-center.js +0 -748
  35. package/dist/components/ui/resource-center.mjs +0 -24
  36. package/src/components/ui/resource-center.tsx +0 -539
package/dist/index.js CHANGED
@@ -369,6 +369,7 @@ __export(index_exports, {
369
369
  ResourceCarousel: () => ResourceCarousel,
370
370
  ResourceCenterHeader: () => ResourceCenterHeader,
371
371
  ResourceDocumentCard: () => ResourceDocumentCard,
372
+ ResourceEmailEditorDialog: () => ResourceEmailEditorDialog,
372
373
  ResourceEmailTemplateCard: () => ResourceEmailTemplateCard,
373
374
  ResourceModal: () => ResourceModal,
374
375
  ResourceVideoCard: () => ResourceVideoCard,
@@ -2615,15 +2616,19 @@ function ChatComposer({
2615
2616
  mode,
2616
2617
  channel: channelProp = "chat",
2617
2618
  onChannelChange,
2619
+ isEmailIntegrated = false,
2618
2620
  contactEmail = "",
2619
2621
  inputValue = "",
2620
2622
  onInputChange,
2621
2623
  onSend,
2624
+ onSendEmail,
2622
2625
  onTakeOver,
2623
2626
  onLetAiHandle,
2624
2627
  className
2625
2628
  }) {
2626
- const [channel, setChannel] = import_react5.default.useState(channelProp);
2629
+ const [channel, setChannel] = import_react5.default.useState(
2630
+ isEmailIntegrated ? channelProp : "chat"
2631
+ );
2627
2632
  const [emailTo, setEmailTo] = import_react5.default.useState(contactEmail);
2628
2633
  const [emailCc, setEmailCc] = import_react5.default.useState("");
2629
2634
  const [showCc, setShowCc] = import_react5.default.useState(false);
@@ -2673,7 +2678,7 @@ function ChatComposer({
2673
2678
  className
2674
2679
  ),
2675
2680
  children: [
2676
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2681
+ isEmailIntegrated && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2677
2682
  Tabs,
2678
2683
  {
2679
2684
  value: channel,
@@ -2808,7 +2813,12 @@ function ChatComposer({
2808
2813
  Button,
2809
2814
  {
2810
2815
  size: "sm",
2811
- onClick: () => onSend == null ? void 0 : onSend(inputValue),
2816
+ onClick: () => onSendEmail == null ? void 0 : onSendEmail({
2817
+ content: inputValue,
2818
+ to: emailTo,
2819
+ cc: emailCc,
2820
+ subject: emailSubject
2821
+ }),
2812
2822
  disabled: !inputValue.trim() || !emailTo.trim(),
2813
2823
  children: [
2814
2824
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.Send, { className: "mr-1.5 size-3.5" }),
@@ -2863,9 +2873,11 @@ function ChatThread({
2863
2873
  isAiTyping = false,
2864
2874
  channel,
2865
2875
  onChannelChange,
2876
+ isEmailIntegrated,
2866
2877
  inputValue,
2867
2878
  onInputChange,
2868
2879
  onSend,
2880
+ onSendEmail,
2869
2881
  onTakeOver,
2870
2882
  onLetAiHandle,
2871
2883
  onReopen,
@@ -2873,12 +2885,53 @@ function ChatThread({
2873
2885
  onUnmarkUrgent,
2874
2886
  onArchive,
2875
2887
  onAssignToAdvisor,
2888
+ hasMoreMessages,
2889
+ isLoadingMoreMessages,
2890
+ onLoadMoreMessages,
2876
2891
  onBack,
2877
2892
  onShowLeadInfo,
2878
2893
  className
2879
2894
  }) {
2880
2895
  const aiIsHandling = mode === "ai";
2881
2896
  const isClosed = status === "closed";
2897
+ const scrollRef = import_react5.default.useRef(null);
2898
+ const preLoadScrollHeightRef = import_react5.default.useRef(null);
2899
+ const handleScroll = (e) => {
2900
+ if (!hasMoreMessages || isLoadingMoreMessages || !onLoadMoreMessages) {
2901
+ return;
2902
+ }
2903
+ if (e.currentTarget.scrollTop <= 80) {
2904
+ preLoadScrollHeightRef.current = e.currentTarget.scrollHeight;
2905
+ onLoadMoreMessages();
2906
+ }
2907
+ };
2908
+ const prevLastMessageIdRef = import_react5.default.useRef(void 0);
2909
+ const prevContactIdRef = import_react5.default.useRef(contact.id);
2910
+ import_react5.default.useLayoutEffect(() => {
2911
+ var _a, _b;
2912
+ const el = scrollRef.current;
2913
+ if (!el) return;
2914
+ if (preLoadScrollHeightRef.current !== null) {
2915
+ el.scrollTop = el.scrollHeight - preLoadScrollHeightRef.current;
2916
+ preLoadScrollHeightRef.current = null;
2917
+ prevLastMessageIdRef.current = (_a = messages[messages.length - 1]) == null ? void 0 : _a.id;
2918
+ prevContactIdRef.current = contact.id;
2919
+ return;
2920
+ }
2921
+ const currentLastId = (_b = messages[messages.length - 1]) == null ? void 0 : _b.id;
2922
+ const contactChanged = prevContactIdRef.current !== contact.id;
2923
+ const tailChanged = prevLastMessageIdRef.current !== currentLastId;
2924
+ if (contactChanged || tailChanged) {
2925
+ el.scrollTop = el.scrollHeight;
2926
+ }
2927
+ prevLastMessageIdRef.current = currentLastId;
2928
+ prevContactIdRef.current = contact.id;
2929
+ }, [contact.id, messages]);
2930
+ import_react5.default.useLayoutEffect(() => {
2931
+ if (!isAiTyping) return;
2932
+ const el = scrollRef.current;
2933
+ if (el) el.scrollTop = el.scrollHeight;
2934
+ }, [isAiTyping]);
2882
2935
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cn("flex flex-col bg-background", className), children: [
2883
2936
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2884
2937
  "div",
@@ -2968,9 +3021,12 @@ function ChatThread({
2968
3021
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2969
3022
  "div",
2970
3023
  {
3024
+ ref: scrollRef,
3025
+ onScroll: handleScroll,
2971
3026
  className: "flex flex-1 flex-col gap-4 overflow-y-auto p-4",
2972
3027
  tabIndex: 0,
2973
3028
  children: [
3029
+ isLoadingMoreMessages && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex justify-center py-1 text-caption text-muted-foreground", children: "Loading older messages..." }),
2974
3030
  messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-1 flex-col items-center justify-center gap-2 text-muted-foreground", children: [
2975
3031
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.MessageSquare, { className: "size-8 opacity-30" }),
2976
3032
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm", children: "No messages yet" })
@@ -3008,10 +3064,12 @@ function ChatThread({
3008
3064
  mode,
3009
3065
  channel,
3010
3066
  onChannelChange,
3067
+ isEmailIntegrated,
3011
3068
  contactEmail: contact.email,
3012
3069
  inputValue,
3013
3070
  onInputChange,
3014
3071
  onSend,
3072
+ onSendEmail,
3015
3073
  onTakeOver,
3016
3074
  onLetAiHandle
3017
3075
  }
@@ -3362,11 +3420,15 @@ function ConversationsPage({
3362
3420
  onChannelFilterChange,
3363
3421
  channel,
3364
3422
  onChannelChange,
3423
+ isEmailIntegrated,
3365
3424
  inputValue,
3366
3425
  internalNotes,
3367
3426
  showLeadPanel = true,
3368
3427
  hasMore,
3369
3428
  isLoadingMore,
3429
+ hasMoreMessages,
3430
+ isLoadingMoreMessages,
3431
+ onLoadMoreMessages,
3370
3432
  isAiTyping,
3371
3433
  notesSaveStatus,
3372
3434
  onSelectConversation,
@@ -3375,6 +3437,7 @@ function ConversationsPage({
3375
3437
  onFilterChange,
3376
3438
  onInputChange,
3377
3439
  onSend,
3440
+ onSendEmail,
3378
3441
  onTakeOver,
3379
3442
  onLetAiHandle,
3380
3443
  onReopen,
@@ -3443,9 +3506,11 @@ function ConversationsPage({
3443
3506
  isAiTyping,
3444
3507
  channel,
3445
3508
  onChannelChange,
3509
+ isEmailIntegrated,
3446
3510
  inputValue,
3447
3511
  onInputChange,
3448
3512
  onSend,
3513
+ onSendEmail,
3449
3514
  onTakeOver,
3450
3515
  onLetAiHandle,
3451
3516
  onReopen,
@@ -3453,6 +3518,9 @@ function ConversationsPage({
3453
3518
  onUnmarkUrgent,
3454
3519
  onArchive,
3455
3520
  onAssignToAdvisor,
3521
+ hasMoreMessages,
3522
+ isLoadingMoreMessages,
3523
+ onLoadMoreMessages,
3456
3524
  onBack: () => setMobilePanel("list"),
3457
3525
  onShowLeadInfo: () => setMobilePanel("lead"),
3458
3526
  className: cn(
@@ -9392,32 +9460,26 @@ function AppointmentBookDialog({
9392
9460
  // src/components/ui/appointment-calendar-view.tsx
9393
9461
  var import_lucide_react27 = require("lucide-react");
9394
9462
  var import_jsx_runtime47 = require("react/jsx-runtime");
9395
- var STATUS_COLORS = {
9396
- pending: "border-l-warning bg-warning/5",
9397
- confirmed: "border-l-success bg-success/5",
9398
- cancelled: "border-l-destructive bg-destructive/5",
9399
- rescheduled: "border-l-info bg-info/5"
9400
- };
9401
- var STATUS_CONFIG2 = {
9463
+ var STATUS = {
9402
9464
  pending: {
9403
- variant: "warning",
9404
- label: "Pending",
9405
- icon: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react27.CalendarClock, { size: 12 })
9465
+ card: "border-l-warning bg-warning/[0.06]",
9466
+ badge: "warning",
9467
+ label: "Pending"
9406
9468
  },
9407
9469
  confirmed: {
9408
- variant: "success",
9409
- label: "Confirmed",
9410
- icon: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react27.Check, { size: 12 })
9470
+ card: "border-l-success bg-success/[0.06]",
9471
+ badge: "success",
9472
+ label: "Confirmed"
9411
9473
  },
9412
9474
  cancelled: {
9413
- variant: "destructive",
9414
- label: "Cancelled",
9415
- icon: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react27.X, { size: 12 })
9475
+ card: "border-l-destructive bg-destructive/[0.06]",
9476
+ badge: "destructive",
9477
+ label: "Cancelled"
9416
9478
  },
9417
9479
  rescheduled: {
9418
- variant: "info",
9419
- label: "Rescheduled",
9420
- icon: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react27.RefreshCw, { size: 12 })
9480
+ card: "border-l-info bg-info/[0.06]",
9481
+ badge: "info",
9482
+ label: "Rescheduled"
9421
9483
  }
9422
9484
  };
9423
9485
  function formatHour(h) {
@@ -9431,6 +9493,55 @@ function getHourFromTime(time) {
9431
9493
  return time.includes("PM") && h !== 12 ? h + 12 : h;
9432
9494
  }
9433
9495
  var DEFAULT_HOURS = [9, 10, 11, 12, 13, 14, 15, 16, 17];
9496
+ function TimeGutter({ hour }) {
9497
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex w-16 shrink-0 items-start justify-end border-r border-border pr-3 pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-caption text-muted-foreground", children: formatHour(hour) }) });
9498
+ }
9499
+ function DayCard({
9500
+ apt,
9501
+ onSelect
9502
+ }) {
9503
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9504
+ Button,
9505
+ {
9506
+ type: "button",
9507
+ variant: "ghost",
9508
+ onClick: () => onSelect == null ? void 0 : onSelect(apt),
9509
+ className: `h-auto w-full justify-start gap-3 border-l-2 px-3 py-3 text-left hover:opacity-80 ${STATUS[apt.status].card}`,
9510
+ children: [
9511
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Avatar, { className: "h-8 w-8 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AvatarFallback, { className: "text-caption", children: apt.clientAvatarInitials }) }),
9512
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
9513
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-body-small font-semibold", children: apt.clientName }),
9514
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "text-caption text-muted-foreground", children: [
9515
+ apt.timeStart,
9516
+ " \u2013 ",
9517
+ apt.timeEnd
9518
+ ] })
9519
+ ] }),
9520
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Badge, { variant: STATUS[apt.status].badge, children: STATUS[apt.status].label })
9521
+ ]
9522
+ }
9523
+ );
9524
+ }
9525
+ function AptChip({
9526
+ apt,
9527
+ onSelect,
9528
+ className
9529
+ }) {
9530
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9531
+ Button,
9532
+ {
9533
+ type: "button",
9534
+ variant: "ghost",
9535
+ onClick: () => onSelect == null ? void 0 : onSelect(apt),
9536
+ className: `h-auto w-full justify-start truncate border-l-2 text-left hover:opacity-80 ${STATUS[apt.status].card} ${className != null ? className : ""}`,
9537
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "truncate text-caption font-medium", children: [
9538
+ apt.timeStart,
9539
+ " ",
9540
+ apt.clientName
9541
+ ] })
9542
+ }
9543
+ );
9544
+ }
9434
9545
  function DayView({
9435
9546
  appointments,
9436
9547
  date,
@@ -9439,85 +9550,51 @@ function DayView({
9439
9550
  onSelectAppointment
9440
9551
  }) {
9441
9552
  const d = /* @__PURE__ */ new Date(date + "T00:00:00");
9442
- const dayLabel = formatWeekdayShort(d);
9443
- const dayShort = d.getDate();
9444
9553
  const isToday = date === today;
9445
9554
  const dayApts = appointments.filter((a) => a.date === date);
9446
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col", children: [
9447
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "grid grid-cols-[48px_1fr] border-b border-border", children: [
9448
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-r border-border" }),
9449
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9450
- "div",
9451
- {
9452
- className: `flex flex-col items-center gap-1 py-3 ${isToday ? "bg-primary/5" : ""}`,
9453
- children: [
9454
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9455
- "span",
9456
- {
9457
- className: `text-xs font-medium tracking-wide ${isToday ? "font-semibold text-primary" : "text-muted-foreground"}`,
9458
- children: dayLabel
9459
- }
9460
- ),
9461
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9462
- "span",
9463
- {
9464
- className: `flex h-10 w-10 items-center justify-center text-xl font-semibold ${isToday ? "bg-primary text-primary-foreground" : ""}`,
9465
- children: dayShort
9466
- }
9467
- )
9468
- ]
9469
- }
9470
- )
9555
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-1 flex-col", children: [
9556
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex shrink-0 border-b border-border", children: [
9557
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "w-16 shrink-0 border-r border-border" }),
9558
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-1 flex-col items-center gap-1 py-4", children: [
9559
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9560
+ "span",
9561
+ {
9562
+ className: `text-caption tracking-wide ${isToday ? "font-semibold text-primary" : "text-muted-foreground"}`,
9563
+ children: formatWeekdayShort(d)
9564
+ }
9565
+ ),
9566
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9567
+ "span",
9568
+ {
9569
+ className: `flex h-10 w-10 items-center justify-center text-xl font-semibold ${isToday ? "text-primary" : ""}`,
9570
+ children: d.getDate()
9571
+ }
9572
+ )
9573
+ ] })
9471
9574
  ] }),
9472
- hours.map((hour) => {
9575
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex flex-1 flex-col", children: hours.map((hour) => {
9473
9576
  const aptsAtHour = dayApts.filter(
9474
9577
  (a) => getHourFromTime(a.timeStart) === hour
9475
9578
  );
9476
9579
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9477
9580
  "div",
9478
9581
  {
9479
- className: "grid min-h-[60px] grid-cols-[48px_1fr] border-b border-border/40 last:border-b-0",
9582
+ className: "flex flex-1 border-b border-border/40 last:border-b-0",
9480
9583
  children: [
9481
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9482
- "div",
9483
- {
9484
- className: `flex items-start justify-end border-r border-border pr-2 pt-1 ${isToday ? "bg-primary/5" : ""}`,
9485
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-[10px] text-muted-foreground", children: formatHour(hour) })
9486
- }
9487
- ),
9488
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9489
- "div",
9584
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TimeGutter, { hour }),
9585
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex flex-1 flex-col gap-2 p-2", children: aptsAtHour.map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9586
+ DayCard,
9490
9587
  {
9491
- className: `flex flex-col gap-1.5 p-1.5 ${isToday ? "bg-primary/5" : ""}`,
9492
- children: aptsAtHour.map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9493
- Button,
9494
- {
9495
- type: "button",
9496
- variant: "ghost",
9497
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
9498
- className: `h-auto w-full justify-start gap-3 border-l-2 px-3 py-2 text-left hover:opacity-80 ${STATUS_COLORS[apt.status]}`,
9499
- children: [
9500
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Avatar, { className: "h-7 w-7 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AvatarFallback, { className: "text-xs", children: apt.clientAvatarInitials }) }),
9501
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
9502
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-sm font-semibold", children: apt.clientName }),
9503
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
9504
- apt.timeStart,
9505
- " \u2013 ",
9506
- apt.timeEnd
9507
- ] })
9508
- ] }),
9509
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Badge, { variant: STATUS_CONFIG2[apt.status].variant, children: STATUS_CONFIG2[apt.status].label })
9510
- ]
9511
- },
9512
- apt.id
9513
- ))
9514
- }
9515
- )
9588
+ apt,
9589
+ onSelect: onSelectAppointment
9590
+ },
9591
+ apt.id
9592
+ )) })
9516
9593
  ]
9517
9594
  },
9518
9595
  hour
9519
9596
  );
9520
- })
9597
+ }) })
9521
9598
  ] });
9522
9599
  }
9523
9600
  function WeekView({
@@ -9527,49 +9604,39 @@ function WeekView({
9527
9604
  hours,
9528
9605
  onSelectAppointment
9529
9606
  }) {
9530
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col overflow-x-auto", children: [
9531
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9532
- "div",
9533
- {
9534
- className: "grid border-b border-border",
9535
- style: { gridTemplateColumns: `48px repeat(${weekDays.length}, 1fr)` },
9536
- children: [
9537
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-r border-border" }),
9538
- weekDays.map((day) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9539
- "div",
9540
- {
9541
- className: `flex flex-col items-center border-r border-border py-2 last:border-r-0 ${day.date === today ? "bg-primary/5" : ""}`,
9542
- children: [
9543
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9544
- "span",
9545
- {
9546
- className: `text-xs font-medium ${day.date === today ? "font-semibold text-primary" : "text-muted-foreground"}`,
9547
- children: day.label
9548
- }
9549
- ),
9550
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9551
- "span",
9552
- {
9553
- className: `text-sm font-semibold ${day.date === today ? "text-primary" : ""}`,
9554
- children: day.short
9555
- }
9556
- )
9557
- ]
9558
- },
9559
- day.date
9560
- ))
9561
- ]
9562
- }
9563
- ),
9564
- hours.map((hour) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9607
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-1 flex-col overflow-x-auto", children: [
9608
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex shrink-0 border-b border-border", children: [
9609
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "w-16 shrink-0 border-r border-border" }),
9610
+ weekDays.map((day) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9611
+ "div",
9612
+ {
9613
+ className: "flex flex-1 flex-col items-center border-r border-border py-3 last:border-r-0",
9614
+ children: [
9615
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9616
+ "span",
9617
+ {
9618
+ className: `text-caption ${day.date === today ? "font-semibold text-primary" : "text-muted-foreground"}`,
9619
+ children: day.label
9620
+ }
9621
+ ),
9622
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9623
+ "span",
9624
+ {
9625
+ className: `text-body-small font-semibold ${day.date === today ? "text-primary" : ""}`,
9626
+ children: day.short
9627
+ }
9628
+ )
9629
+ ]
9630
+ },
9631
+ day.date
9632
+ ))
9633
+ ] }),
9634
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex flex-1 flex-col", children: hours.map((hour) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9565
9635
  "div",
9566
9636
  {
9567
- className: "grid border-b border-border/40 last:border-b-0",
9568
- style: {
9569
- gridTemplateColumns: `48px repeat(${weekDays.length}, 1fr)`
9570
- },
9637
+ className: "flex flex-1 border-b border-border/40 last:border-b-0",
9571
9638
  children: [
9572
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex items-start justify-end border-r border-border pr-2 pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-[10px] text-muted-foreground", children: formatHour(hour) }) }),
9639
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TimeGutter, { hour }),
9573
9640
  weekDays.map((day) => {
9574
9641
  const aptsAtCell = appointments.filter(
9575
9642
  (a) => a.date === day.date && getHourFromTime(a.timeStart) === hour
@@ -9577,19 +9644,13 @@ function WeekView({
9577
9644
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9578
9645
  "div",
9579
9646
  {
9580
- className: `min-h-[44px] overflow-hidden border-r border-border/40 p-0.5 last:border-r-0 ${day.date === today ? "bg-primary/5" : ""}`,
9581
- children: aptsAtCell.map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9582
- Button,
9647
+ className: "flex flex-1 flex-col overflow-hidden border-r border-border/40 p-1 last:border-r-0",
9648
+ children: aptsAtCell.map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9649
+ AptChip,
9583
9650
  {
9584
- type: "button",
9585
- variant: "ghost",
9586
- className: `h-auto w-full justify-start truncate border-l-2 px-1 py-1 text-left text-xs font-medium hover:opacity-80 ${STATUS_COLORS[apt.status]}`,
9587
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
9588
- children: [
9589
- apt.timeStart,
9590
- " ",
9591
- apt.clientName
9592
- ]
9651
+ apt,
9652
+ onSelect: onSelectAppointment,
9653
+ className: "px-2 py-1.5"
9593
9654
  },
9594
9655
  apt.id
9595
9656
  ))
@@ -9600,7 +9661,7 @@ function WeekView({
9600
9661
  ]
9601
9662
  },
9602
9663
  hour
9603
- ))
9664
+ )) })
9604
9665
  ] });
9605
9666
  }
9606
9667
  var MONTH_DAY_HEADERS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
@@ -9632,19 +9693,19 @@ function MonthView({
9632
9693
  const vd = /* @__PURE__ */ new Date(viewDate + "T00:00:00");
9633
9694
  const grid = generateMonthGrid(vd.getFullYear(), vd.getMonth());
9634
9695
  const toIso = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
9635
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col", children: [
9636
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "grid grid-cols-7 border-b border-border", children: MONTH_DAY_HEADERS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9696
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-1 flex-col", children: [
9697
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "grid shrink-0 grid-cols-7 border-b border-border", children: MONTH_DAY_HEADERS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9637
9698
  "div",
9638
9699
  {
9639
9700
  className: "flex items-center justify-center border-r border-border/40 py-2 last:border-r-0",
9640
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-xs font-medium text-muted-foreground", children: d })
9701
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-caption font-medium text-muted-foreground", children: d })
9641
9702
  },
9642
9703
  d
9643
9704
  )) }),
9644
- grid.map((week, wi) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9705
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex flex-1 flex-col", children: grid.map((week, wi) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9645
9706
  "div",
9646
9707
  {
9647
- className: "grid grid-cols-7 border-b border-border last:border-b-0",
9708
+ className: "flex flex-1 border-b border-border last:border-b-0",
9648
9709
  children: week.map((day, di) => {
9649
9710
  const iso = day ? toIso(day) : null;
9650
9711
  const dayApts = iso ? appointments.filter((a) => a.date === iso) : [];
@@ -9652,32 +9713,26 @@ function MonthView({
9652
9713
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9653
9714
  "div",
9654
9715
  {
9655
- className: `min-h-[80px] border-r border-border/40 p-1 last:border-r-0 ${!day ? "bg-muted/20" : ""} ${isToday ? "bg-primary/5" : ""}`,
9716
+ className: `min-w-0 flex-1 border-r border-border/40 p-1.5 last:border-r-0 ${!day ? "bg-muted/20" : ""}`,
9656
9717
  children: day && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
9657
9718
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9658
9719
  "div",
9659
9720
  {
9660
- className: `mb-1 flex h-6 w-6 items-center justify-center text-xs font-semibold ${isToday ? "bg-primary text-primary-foreground" : "text-foreground"}`,
9721
+ className: `mb-1 flex h-6 w-6 items-center justify-center text-xs font-semibold ${isToday ? "text-primary" : "text-foreground"}`,
9661
9722
  children: day.getDate()
9662
9723
  }
9663
9724
  ),
9664
9725
  /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
9665
- dayApts.slice(0, 2).map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9666
- Button,
9726
+ dayApts.slice(0, 2).map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9727
+ AptChip,
9667
9728
  {
9668
- type: "button",
9669
- variant: "ghost",
9670
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
9671
- className: `h-auto w-full justify-start truncate border-l-2 px-1 py-0.5 text-left text-[10px] font-medium hover:opacity-80 ${STATUS_COLORS[apt.status]}`,
9672
- children: [
9673
- apt.timeStart,
9674
- " ",
9675
- apt.clientName
9676
- ]
9729
+ apt,
9730
+ onSelect: onSelectAppointment,
9731
+ className: "px-1.5 py-1"
9677
9732
  },
9678
9733
  apt.id
9679
9734
  )),
9680
- dayApts.length > 2 && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("p", { className: "px-1 text-[10px] text-muted-foreground", children: [
9735
+ dayApts.length > 2 && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("p", { className: "px-1 text-caption text-muted-foreground", children: [
9681
9736
  "+",
9682
9737
  dayApts.length - 2,
9683
9738
  " more"
@@ -9690,7 +9745,7 @@ function MonthView({
9690
9745
  })
9691
9746
  },
9692
9747
  wi
9693
- ))
9748
+ )) })
9694
9749
  ] });
9695
9750
  }
9696
9751
  function AppointmentCalendarView({
@@ -9711,7 +9766,7 @@ function AppointmentCalendarView({
9711
9766
  }) {
9712
9767
  var _a;
9713
9768
  const effectiveViewDate = (_a = viewDate != null ? viewDate : dayViewDate) != null ? _a : today;
9714
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col border border-border bg-card", children: [
9769
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-1 flex-col min-h-0 border border-border bg-card", children: [
9715
9770
  /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between gap-4 px-4 py-3", children: [
9716
9771
  /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
9717
9772
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
@@ -9724,7 +9779,7 @@ function AppointmentCalendarView({
9724
9779
  children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react27.ChevronLeft, { className: "h-3.5 w-3.5" })
9725
9780
  }
9726
9781
  ),
9727
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "text-sm font-medium", children: periodLabel }),
9782
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "text-label-medium", children: periodLabel }),
9728
9783
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9729
9784
  Button,
9730
9785
  {
@@ -9745,38 +9800,52 @@ function AppointmentCalendarView({
9745
9800
  {
9746
9801
  defaultValue: defaultView,
9747
9802
  onValueChange: (v) => onViewChange == null ? void 0 : onViewChange(v),
9748
- className: "flex flex-col",
9803
+ className: "flex flex-col flex-1 min-h-0",
9749
9804
  children: [
9750
9805
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "px-4 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(TabsList, { children: [
9751
9806
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TabsTrigger, { value: "day", children: "Day" }),
9752
9807
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TabsTrigger, { value: "week", children: "Week" }),
9753
9808
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TabsTrigger, { value: "month", children: "Month" })
9754
9809
  ] }) }),
9755
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TabsContent, { value: "day", className: "mt-0 max-h-[75vh] overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9756
- DayView,
9810
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9811
+ TabsContent,
9757
9812
  {
9758
- appointments,
9759
- date: effectiveViewDate,
9760
- today,
9761
- hours,
9762
- onSelectAppointment
9813
+ value: "day",
9814
+ className: "mt-0 min-h-0 flex-1 flex flex-col overflow-y-auto",
9815
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9816
+ DayView,
9817
+ {
9818
+ appointments,
9819
+ date: effectiveViewDate,
9820
+ today,
9821
+ hours,
9822
+ onSelectAppointment
9823
+ }
9824
+ )
9763
9825
  }
9764
- ) }),
9765
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TabsContent, { value: "week", className: "mt-0 max-h-[75vh] overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9766
- WeekView,
9826
+ ),
9827
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9828
+ TabsContent,
9767
9829
  {
9768
- appointments,
9769
- weekDays,
9770
- today,
9771
- hours,
9772
- onSelectAppointment
9830
+ value: "week",
9831
+ className: "mt-0 min-h-0 flex-1 flex flex-col overflow-y-auto",
9832
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9833
+ WeekView,
9834
+ {
9835
+ appointments,
9836
+ weekDays,
9837
+ today,
9838
+ hours,
9839
+ onSelectAppointment
9840
+ }
9841
+ )
9773
9842
  }
9774
- ) }),
9843
+ ),
9775
9844
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9776
9845
  TabsContent,
9777
9846
  {
9778
9847
  value: "month",
9779
- className: "mt-0 max-h-[75vh] overflow-y-auto",
9848
+ className: "mt-0 min-h-0 flex-1 flex flex-col overflow-y-auto",
9780
9849
  children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9781
9850
  MonthView,
9782
9851
  {
@@ -9798,7 +9867,7 @@ function AppointmentCalendarView({
9798
9867
  var import_react14 = __toESM(require("react"));
9799
9868
  var import_lucide_react28 = require("lucide-react");
9800
9869
  var import_jsx_runtime48 = require("react/jsx-runtime");
9801
- var STATUS_CONFIG3 = {
9870
+ var STATUS_CONFIG2 = {
9802
9871
  pending: {
9803
9872
  variant: "warning",
9804
9873
  label: "Pending",
@@ -9852,7 +9921,7 @@ function AppointmentDetailSheet({
9852
9921
  const [confirmAction, setConfirmAction] = import_react14.default.useState(null);
9853
9922
  const [rescheduleOpen, setRescheduleOpen] = import_react14.default.useState(false);
9854
9923
  if (!appointment) return null;
9855
- const { variant, label, icon } = STATUS_CONFIG3[appointment.status];
9924
+ const { variant, label, icon } = STATUS_CONFIG2[appointment.status];
9856
9925
  const isCancelled = appointment.status === "cancelled";
9857
9926
  const isConfirmed = appointment.status === "confirmed";
9858
9927
  const fmt2 = appointment.meetingFormat;
@@ -11991,6 +12060,11 @@ function BankStatementDocumentTable({
11991
12060
  var import_react21 = require("react");
11992
12061
  var import_date_fns3 = require("date-fns");
11993
12062
  var import_jsx_runtime61 = require("react/jsx-runtime");
12063
+ var APPLICANT_TYPE_LABELS = {
12064
+ primary: "Main applicant",
12065
+ secondary: "Co-applicant"
12066
+ };
12067
+ var ACCOUNTS_PAGE_SIZE = 5;
11994
12068
  function toIsoDate(date) {
11995
12069
  return date.toISOString().slice(0, 10);
11996
12070
  }
@@ -12014,29 +12088,37 @@ function BankStatementGenerateDialog({
12014
12088
  }) {
12015
12089
  const [statementName, setStatementName] = (0, import_react21.useState)("Bank Statement 1");
12016
12090
  const [rangePreset, setRangePreset] = (0, import_react21.useState)(90);
12017
- const [fromDate, setFromDate] = (0, import_react21.useState)("");
12018
- const [toDate, setToDate] = (0, import_react21.useState)("");
12091
+ const [fromDate, setFromDate] = (0, import_react21.useState)(
12092
+ () => presetToDateRange(90).from
12093
+ );
12094
+ const [toDate, setToDate] = (0, import_react21.useState)(() => presetToDateRange(90).to);
12019
12095
  const [applicantType, setApplicantType] = (0, import_react21.useState)("");
12020
12096
  const [selectedAccountIds, setSelectedAccountIds] = (0, import_react21.useState)([]);
12097
+ const [accountPage, setAccountPage] = (0, import_react21.useState)(1);
12021
12098
  (0, import_react21.useEffect)(() => {
12022
12099
  if (!open) return;
12023
12100
  const timer = setTimeout(() => {
12024
- setStatementName("Bank Statement 1");
12025
- setApplicantType("");
12026
- setSelectedAccountIds([]);
12027
12101
  const { from, to } = presetToDateRange(90);
12102
+ setStatementName("Bank Statement 1");
12028
12103
  setRangePreset(90);
12029
12104
  setFromDate(from);
12030
12105
  setToDate(to);
12106
+ setApplicantType("");
12107
+ setSelectedAccountIds([]);
12108
+ setAccountPage(1);
12031
12109
  }, 0);
12032
12110
  return () => clearTimeout(timer);
12033
12111
  }, [open]);
12034
12112
  const handleApplicantTypeChange = (type) => {
12035
12113
  setApplicantType(type);
12036
12114
  setSelectedAccountIds([]);
12115
+ setAccountPage(1);
12037
12116
  onApplicantTypeChange == null ? void 0 : onApplicantTypeChange(type);
12038
12117
  };
12039
- const applyPreset = (preset) => {
12118
+ const handlePresetChange = (val) => {
12119
+ if (val.length === 0) return;
12120
+ const raw = val[0];
12121
+ const preset = raw === "custom" ? "custom" : Number(raw);
12040
12122
  setRangePreset(preset);
12041
12123
  if (preset !== "custom") {
12042
12124
  const { from, to } = presetToDateRange(preset);
@@ -12052,12 +12134,13 @@ function BankStatementGenerateDialog({
12052
12134
  );
12053
12135
  };
12054
12136
  const handleToggleAll = () => {
12055
- if (areAllSelected) {
12056
- setSelectedAccountIds([]);
12057
- } else {
12058
- setSelectedAccountIds(bankAccounts.map((a) => a.id));
12059
- }
12137
+ setSelectedAccountIds(areAllSelected ? [] : bankAccounts.map((a) => a.id));
12060
12138
  };
12139
+ const accountPageCount = Math.ceil(bankAccounts.length / ACCOUNTS_PAGE_SIZE);
12140
+ const pagedAccounts = bankAccounts.slice(
12141
+ (accountPage - 1) * ACCOUNTS_PAGE_SIZE,
12142
+ accountPage * ACCOUNTS_PAGE_SIZE
12143
+ );
12061
12144
  const periodLabel = (0, import_react21.useMemo)(() => {
12062
12145
  if (fromDate && toDate) {
12063
12146
  return `${(0, import_date_fns3.format)((0, import_date_fns3.parseISO)(fromDate), "dd MMM yyyy")} \u2013 ${(0, import_date_fns3.format)((0, import_date_fns3.parseISO)(toDate), "dd MMM yyyy")}`;
@@ -12079,7 +12162,8 @@ function BankStatementGenerateDialog({
12079
12162
  return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Dialog, { open, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
12080
12163
  DialogContent,
12081
12164
  {
12082
- className: cn("max-w-[700px]", className),
12165
+ size: "3xl",
12166
+ className,
12083
12167
  "data-slot": "bank-statement-generate-dialog",
12084
12168
  children: [
12085
12169
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(DialogTitle, { children: "Generate Bank Statement" }) }),
@@ -12103,15 +12187,7 @@ function BankStatementGenerateDialog({
12103
12187
  type: "single",
12104
12188
  variant: "outline",
12105
12189
  value: [String(rangePreset)],
12106
- onValueChange: (val) => {
12107
- if (val.length === 0) return;
12108
- const raw = val[0];
12109
- if (raw === "custom") {
12110
- applyPreset("custom");
12111
- } else {
12112
- applyPreset(Number(raw));
12113
- }
12114
- },
12190
+ onValueChange: handlePresetChange,
12115
12191
  className: "w-full",
12116
12192
  children: [
12117
12193
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(ToggleGroupItem, { value: "90", className: "flex-1", children: "3 Months" }),
@@ -12147,19 +12223,18 @@ function BankStatementGenerateDialog({
12147
12223
  {
12148
12224
  value: applicantType,
12149
12225
  onValueChange: (v) => handleApplicantTypeChange(v),
12226
+ items: APPLICANT_TYPE_LABELS,
12150
12227
  children: [
12151
12228
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(SelectValue, { placeholder: "Applicant Type" }) }),
12152
12229
  /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(SelectContent, { children: [
12153
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(SelectItem, { value: "primary", children: "Main applicant" }),
12154
- hasCoApplicant && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(SelectItem, { value: "secondary", children: "Co-applicant" })
12230
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(SelectItem, { value: "primary", children: APPLICANT_TYPE_LABELS.primary }),
12231
+ hasCoApplicant && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(SelectItem, { value: "secondary", children: APPLICANT_TYPE_LABELS.secondary })
12155
12232
  ] })
12156
12233
  ]
12157
12234
  }
12158
12235
  ),
12159
- applicantType && /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "mt-1", children: [
12160
- isLoadingAccounts && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "flex items-center justify-center p-6", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Spinner, { size: "lg" }) }),
12161
- !isLoadingAccounts && bankAccounts.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "py-4 text-center text-body-medium text-muted-foreground", children: "No bank accounts found for the selected applicant" }),
12162
- !isLoadingAccounts && bankAccounts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(Table, { children: [
12236
+ applicantType && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "mt-1", children: isLoadingAccounts ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "flex items-center justify-center p-6", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Spinner, { size: "lg" }) }) : bankAccounts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "py-4 text-center text-body-medium text-muted-foreground", children: "No bank accounts found for the selected applicant" }) : /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
12237
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(Table, { className: "table-fixed", children: [
12163
12238
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(TableRow, { children: [
12164
12239
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { className: "w-10", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
12165
12240
  Checkbox,
@@ -12171,42 +12246,77 @@ function BankStatementGenerateDialog({
12171
12246
  }
12172
12247
  ) }),
12173
12248
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { children: "Account Name" }),
12174
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { children: "Account Number" }),
12175
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { children: "Period" }),
12176
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { children: "Last Updated" })
12249
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { className: "w-40", children: "Account Number" }),
12250
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { className: "w-52", children: "Period" }),
12251
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { className: "w-28", children: "Last Updated" })
12177
12252
  ] }) }),
12178
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableBody, { children: bankAccounts.map((account) => {
12253
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableBody, { children: pagedAccounts.map((account) => {
12179
12254
  var _a, _b;
12180
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(TableRow, { children: [
12181
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
12182
- Checkbox,
12183
- {
12184
- checked: selectedAccountIds.includes(account.id),
12185
- onCheckedChange: () => handleToggleAccount(account.id),
12186
- "aria-label": `Select ${account.name}`
12187
- }
12188
- ) }),
12189
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex items-center gap-2", children: [
12190
- account.institutionLogo && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
12191
- "img",
12192
- {
12193
- src: account.institutionLogo,
12194
- alt: (_a = account.institutionName) != null ? _a : "",
12195
- className: "size-8 rounded object-cover"
12196
- }
12197
- ),
12198
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-body-medium font-semibold", children: account.name || account.institutionName || "\u2014" })
12199
- ] }) }),
12200
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-body-medium", children: (_b = account.accountNo) != null ? _b : "\u2014" }) }),
12201
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-body-medium", children: periodLabel }) }),
12202
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-body-medium", children: account.lastUpdated ? (0, import_date_fns3.format)(
12203
- (0, import_date_fns3.parseISO)(account.lastUpdated),
12204
- "dd MMM yyyy"
12205
- ) : "\u2014" }) })
12206
- ] }, account.id);
12255
+ const isSelected = selectedAccountIds.includes(
12256
+ account.id
12257
+ );
12258
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
12259
+ TableRow,
12260
+ {
12261
+ "data-state": isSelected ? "selected" : void 0,
12262
+ children: [
12263
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
12264
+ Checkbox,
12265
+ {
12266
+ checked: isSelected,
12267
+ onCheckedChange: () => handleToggleAccount(account.id),
12268
+ "aria-label": `Select ${account.name}`
12269
+ }
12270
+ ) }),
12271
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex items-center gap-2", children: [
12272
+ account.institutionLogo && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
12273
+ "img",
12274
+ {
12275
+ src: account.institutionLogo,
12276
+ alt: (_a = account.institutionName) != null ? _a : "",
12277
+ className: "size-8 object-cover"
12278
+ }
12279
+ ),
12280
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-body-medium font-semibold", children: account.name || account.institutionName || "\u2014" })
12281
+ ] }) }),
12282
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-body-medium", children: (_b = account.accountNo) != null ? _b : "\u2014" }) }),
12283
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-body-medium", children: periodLabel }) }),
12284
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-body-medium", children: account.lastUpdated ? (0, import_date_fns3.format)(
12285
+ (0, import_date_fns3.parseISO)(account.lastUpdated),
12286
+ "dd MMM yyyy"
12287
+ ) : "\u2014" }) })
12288
+ ]
12289
+ },
12290
+ account.id
12291
+ );
12207
12292
  }) })
12293
+ ] }),
12294
+ accountPageCount > 1 && /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex items-center justify-between pt-2", children: [
12295
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "text-body-small text-muted-foreground", children: [
12296
+ (accountPage - 1) * ACCOUNTS_PAGE_SIZE + 1,
12297
+ "\u2013",
12298
+ Math.min(
12299
+ accountPage * ACCOUNTS_PAGE_SIZE,
12300
+ bankAccounts.length
12301
+ ),
12302
+ " ",
12303
+ "of ",
12304
+ bankAccounts.length,
12305
+ " accounts"
12306
+ ] }),
12307
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
12308
+ PaginationNavButtons,
12309
+ {
12310
+ hasPrev: accountPage > 1,
12311
+ hasNext: accountPage < accountPageCount,
12312
+ onFirst: () => setAccountPage(1),
12313
+ onPrev: () => setAccountPage((p) => p - 1),
12314
+ onNext: () => setAccountPage((p) => p + 1),
12315
+ onLast: () => setAccountPage(accountPageCount)
12316
+ }
12317
+ )
12208
12318
  ] })
12209
- ] })
12319
+ ] }) })
12210
12320
  ] }),
12211
12321
  /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(DialogFooter, { children: [
12212
12322
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Button, { variant: "ghost", onClick: onClose, children: "Cancel" }),
@@ -21872,7 +21982,7 @@ function ApplicantCardTab({
21872
21982
  ] });
21873
21983
  }
21874
21984
  var STATUS_OPTIONS = ["verified", "pending", "rejected"];
21875
- var STATUS_CONFIG4 = {
21985
+ var STATUS_CONFIG3 = {
21876
21986
  verified: {
21877
21987
  Icon: import_lucide_react56.CheckCircle2,
21878
21988
  label: "Verified",
@@ -21905,7 +22015,7 @@ function DocRow({
21905
22015
  label: statusLabel,
21906
22016
  iconCls,
21907
22017
  triggerCls
21908
- } = STATUS_CONFIG4[status];
22018
+ } = STATUS_CONFIG3[status];
21909
22019
  return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
21910
22020
  "div",
21911
22021
  {
@@ -21953,7 +22063,7 @@ function DocRow({
21953
22063
  }
21954
22064
  ),
21955
22065
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(SelectContent, { children: STATUS_OPTIONS.map((v) => {
21956
- const { Icon, label, iconCls: iconCls2 } = STATUS_CONFIG4[v];
22066
+ const { Icon, label, iconCls: iconCls2 } = STATUS_CONFIG3[v];
21957
22067
  return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(SelectItem, { value: v, children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("span", { className: "flex items-center gap-1.5", children: [
21958
22068
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Icon, { className: cn("size-3.5", iconCls2) }),
21959
22069
  label
@@ -26352,7 +26462,7 @@ function IncomeWorkDetails({
26352
26462
  // src/components/ui/loan-application-badge.tsx
26353
26463
  var import_lucide_react66 = require("lucide-react");
26354
26464
  var import_jsx_runtime128 = require("react/jsx-runtime");
26355
- var STATUS_CONFIG5 = {
26465
+ var STATUS_CONFIG4 = {
26356
26466
  SENT: {
26357
26467
  label: "Sent Application",
26358
26468
  statusClassName: "border-info/40 bg-info/10 text-info-text",
@@ -26373,7 +26483,7 @@ function LoanApplicationBadge({
26373
26483
  status,
26374
26484
  className
26375
26485
  }) {
26376
- const { label, statusClassName, showCheck } = STATUS_CONFIG5[status];
26486
+ const { label, statusClassName, showCheck } = STATUS_CONFIG4[status];
26377
26487
  return /* @__PURE__ */ (0, import_jsx_runtime128.jsxs)(
26378
26488
  Badge,
26379
26489
  {
@@ -26549,10 +26659,107 @@ function ChevronRightIcon4({ className }) {
26549
26659
  );
26550
26660
  }
26551
26661
 
26552
- // src/components/ui/resource-center.tsx
26662
+ // src/components/ui/resource-center/resource-carousel.tsx
26553
26663
  var import_react43 = require("react");
26554
26664
  var import_lucide_react67 = require("lucide-react");
26555
26665
  var import_jsx_runtime131 = require("react/jsx-runtime");
26666
+ function ResourceCarousel({
26667
+ title,
26668
+ items,
26669
+ headerAction,
26670
+ onViewModeChange,
26671
+ className
26672
+ }) {
26673
+ const scrollRef = (0, import_react43.useRef)(null);
26674
+ const [viewMode, setViewMode] = (0, import_react43.useState)("compact");
26675
+ function scrollLeft() {
26676
+ var _a;
26677
+ (_a = scrollRef.current) == null ? void 0 : _a.scrollBy({ left: -380, behavior: "smooth" });
26678
+ }
26679
+ function scrollRight() {
26680
+ var _a;
26681
+ (_a = scrollRef.current) == null ? void 0 : _a.scrollBy({ left: 380, behavior: "smooth" });
26682
+ }
26683
+ return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: cn("flex flex-col gap-4", className), children: [
26684
+ (title || headerAction) && /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
26685
+ /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex flex-1 items-center gap-4 min-w-0", children: [
26686
+ title && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("h2", { className: "text-h3 text-foreground", children: title }),
26687
+ headerAction && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex-1 flex justify-end", children: headerAction })
26688
+ ] }),
26689
+ /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26690
+ ToggleGroup,
26691
+ {
26692
+ type: "single",
26693
+ variant: "outline",
26694
+ value: [viewMode],
26695
+ onValueChange: (v) => {
26696
+ if (v.length > 0) {
26697
+ const mode = v[0];
26698
+ setViewMode(mode);
26699
+ onViewModeChange == null ? void 0 : onViewModeChange(mode);
26700
+ }
26701
+ },
26702
+ "aria-label": "View mode",
26703
+ children: [
26704
+ /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(ToggleGroupItem, { value: "compact", "aria-label": "Compact view", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.GalleryHorizontal, { className: "size-4" }) }),
26705
+ /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(ToggleGroupItem, { value: "grid", "aria-label": "Grid view", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.LayoutGrid, { className: "size-4" }) })
26706
+ ]
26707
+ }
26708
+ )
26709
+ ] }),
26710
+ items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "py-8 text-center text-body-small text-muted-foreground", children: "No items available" }) : viewMode === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "grid grid-cols-4 gap-6 max-[1280px]:grid-cols-3 max-[900px]:grid-cols-2 max-[600px]:grid-cols-1", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { children: item }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "group/track relative", children: [
26711
+ /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26712
+ "button",
26713
+ {
26714
+ type: "button",
26715
+ onClick: scrollLeft,
26716
+ "aria-label": "Scroll left",
26717
+ className: cn(
26718
+ "absolute left-0 top-1/2 z-10 -translate-x-1/2 -translate-y-1/2",
26719
+ "flex size-9 items-center justify-center",
26720
+ "border border-border bg-background shadow-sm",
26721
+ "opacity-0 transition-opacity duration-200 group-hover/track:opacity-100",
26722
+ "hover:bg-muted focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
26723
+ ),
26724
+ children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.ChevronLeft, { className: "size-4 text-foreground" })
26725
+ }
26726
+ ),
26727
+ /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26728
+ "div",
26729
+ {
26730
+ ref: scrollRef,
26731
+ className: "flex gap-4 overflow-x-auto scroll-smooth pb-2",
26732
+ style: { scrollbarWidth: "none" },
26733
+ children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "w-[360px] shrink-0", children: item }, i))
26734
+ }
26735
+ ),
26736
+ /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26737
+ "button",
26738
+ {
26739
+ type: "button",
26740
+ onClick: scrollRight,
26741
+ "aria-label": "Scroll right",
26742
+ className: cn(
26743
+ "absolute right-0 top-1/2 z-10 translate-x-1/2 -translate-y-1/2",
26744
+ "flex size-9 items-center justify-center",
26745
+ "border border-border bg-background shadow-sm",
26746
+ "opacity-0 transition-opacity duration-200 group-hover/track:opacity-100",
26747
+ "hover:bg-muted focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
26748
+ ),
26749
+ children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.ChevronRight, { className: "size-4 text-foreground" })
26750
+ }
26751
+ )
26752
+ ] })
26753
+ ] });
26754
+ }
26755
+
26756
+ // src/components/ui/resource-center/resource-center-header.tsx
26757
+ var import_react44 = require("react");
26758
+ var import_lucide_react69 = require("lucide-react");
26759
+
26760
+ // src/components/ui/resource-center/resource-modal.tsx
26761
+ var import_lucide_react68 = require("lucide-react");
26762
+ var import_jsx_runtime132 = require("react/jsx-runtime");
26556
26763
  function ResourceModal({
26557
26764
  open,
26558
26765
  onClose,
@@ -26561,17 +26768,17 @@ function ResourceModal({
26561
26768
  tags,
26562
26769
  attachments
26563
26770
  }) {
26564
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(Dialog, { open, onOpenChange: (v) => !v && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26771
+ return /* @__PURE__ */ (0, import_jsx_runtime132.jsx)(Dialog, { open, onOpenChange: (v) => !v && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime132.jsxs)(
26565
26772
  DialogContent,
26566
26773
  {
26567
26774
  size: "2xl",
26568
26775
  className: "flex flex-col gap-4 p-0 overflow-hidden",
26569
26776
  children: [
26570
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(DialogHeader, { className: "px-6 pt-6 pb-0", children: [
26571
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(DialogTitle, { className: "text-lg font-semibold", children: title }),
26572
- tags && tags.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex flex-wrap gap-1.5 pt-1", children: tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(Badge, { variant: "secondary", className: "text-xs", children: tag }, tag)) })
26777
+ /* @__PURE__ */ (0, import_jsx_runtime132.jsxs)(DialogHeader, { className: "px-6 pt-6 pb-0", children: [
26778
+ /* @__PURE__ */ (0, import_jsx_runtime132.jsx)(DialogTitle, { className: "text-h5", children: title }),
26779
+ tags && tags.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime132.jsx)("div", { className: "flex flex-wrap gap-1.5 pt-1", children: tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime132.jsx)(Badge, { variant: "secondary", children: tag }, tag)) })
26573
26780
  ] }),
26574
- videoUrl && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "aspect-video w-full bg-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26781
+ videoUrl && /* @__PURE__ */ (0, import_jsx_runtime132.jsx)("div", { className: "aspect-video w-full bg-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime132.jsx)(
26575
26782
  "iframe",
26576
26783
  {
26577
26784
  src: videoUrl,
@@ -26581,54 +26788,139 @@ function ResourceModal({
26581
26788
  allowFullScreen: true
26582
26789
  }
26583
26790
  ) }),
26584
- attachments && attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex flex-col gap-2 px-6 pb-6", children: [
26585
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Attachments" }),
26586
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex flex-col gap-1", children: attachments.map((attachment, i) => /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26791
+ attachments && attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime132.jsxs)("div", { className: "flex flex-col gap-2 px-6 pb-6", children: [
26792
+ /* @__PURE__ */ (0, import_jsx_runtime132.jsx)("p", { className: "text-body-small font-medium text-foreground", children: "Attachments" }),
26793
+ /* @__PURE__ */ (0, import_jsx_runtime132.jsx)("div", { className: "flex flex-col gap-1", children: attachments.map((attachment, i) => /* @__PURE__ */ (0, import_jsx_runtime132.jsxs)(
26587
26794
  "a",
26588
26795
  {
26589
26796
  href: attachment.url,
26590
26797
  download: true,
26591
- className: "flex items-center gap-2 text-sm text-primary hover:underline",
26798
+ className: "flex items-center gap-2 text-body-small text-primary hover:underline",
26592
26799
  children: [
26593
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.Download, { className: "size-3.5 shrink-0" }),
26800
+ /* @__PURE__ */ (0, import_jsx_runtime132.jsx)(import_lucide_react68.Download, { className: "size-3.5 shrink-0" }),
26594
26801
  attachment.name
26595
26802
  ]
26596
26803
  },
26597
26804
  i
26598
26805
  )) })
26599
26806
  ] }),
26600
- (!attachments || attachments.length === 0) && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "pb-2" })
26807
+ (!attachments || attachments.length === 0) && /* @__PURE__ */ (0, import_jsx_runtime132.jsx)("div", { className: "pb-2" })
26601
26808
  ]
26602
26809
  }
26603
26810
  ) });
26604
26811
  }
26812
+
26813
+ // src/components/ui/resource-center/resource-center-header.tsx
26814
+ var import_jsx_runtime133 = require("react/jsx-runtime");
26815
+ function ResourceCenterHeader({
26816
+ title,
26817
+ description,
26818
+ backgroundImageUrl,
26819
+ backgroundVideoUrl,
26820
+ watchVideoUrl
26821
+ }) {
26822
+ const [watchModalOpen, setWatchModalOpen] = (0, import_react44.useState)(false);
26823
+ const hasBackground = !!backgroundImageUrl || !!backgroundVideoUrl;
26824
+ return /* @__PURE__ */ (0, import_jsx_runtime133.jsxs)(import_jsx_runtime133.Fragment, { children: [
26825
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsxs)(
26826
+ "div",
26827
+ {
26828
+ className: cn(
26829
+ "relative flex min-h-[480px] w-full items-center overflow-hidden max-[900px]:min-h-[360px] max-[600px]:min-h-[260px]"
26830
+ ),
26831
+ children: [
26832
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
26833
+ "div",
26834
+ {
26835
+ className: cn(
26836
+ "absolute inset-0 z-[0]",
26837
+ hasBackground ? "bg-foreground" : "bg-gradient-to-br from-primary to-foreground"
26838
+ )
26839
+ }
26840
+ ),
26841
+ backgroundImageUrl && !backgroundVideoUrl && /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
26842
+ "img",
26843
+ {
26844
+ src: backgroundImageUrl,
26845
+ alt: "",
26846
+ "aria-hidden": "true",
26847
+ className: "absolute inset-0 h-full w-full object-cover z-[1]"
26848
+ }
26849
+ ),
26850
+ backgroundVideoUrl && /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
26851
+ "video",
26852
+ {
26853
+ className: "absolute inset-0 h-full w-full object-cover z-[1]",
26854
+ src: backgroundVideoUrl,
26855
+ autoPlay: true,
26856
+ muted: true,
26857
+ loop: true,
26858
+ playsInline: true
26859
+ }
26860
+ ),
26861
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
26862
+ "div",
26863
+ {
26864
+ className: cn(
26865
+ "absolute inset-0 z-[2]",
26866
+ hasBackground ? "bg-black/50" : "bg-black/20"
26867
+ )
26868
+ }
26869
+ ),
26870
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsxs)("div", { className: "relative z-[3] flex flex-col gap-4 px-8 py-12 md:px-16 max-w-3xl", children: [
26871
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsx)("h1", { className: "text-[56px] font-bold text-white leading-none max-[900px]:text-[40px] max-[600px]:text-[32px]", children: title }),
26872
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsx)("p", { className: "text-body-medium text-white/80 leading-relaxed", children: description }),
26873
+ watchVideoUrl && /* @__PURE__ */ (0, import_jsx_runtime133.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime133.jsxs)(Button, { variant: "default", onClick: () => setWatchModalOpen(true), children: [
26874
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(import_lucide_react69.Play, { className: "mr-2 size-4" }),
26875
+ "Watch Now"
26876
+ ] }) })
26877
+ ] })
26878
+ ]
26879
+ }
26880
+ ),
26881
+ watchVideoUrl && /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
26882
+ ResourceModal,
26883
+ {
26884
+ open: watchModalOpen,
26885
+ onClose: () => setWatchModalOpen(false),
26886
+ title,
26887
+ videoUrl: watchVideoUrl
26888
+ }
26889
+ )
26890
+ ] });
26891
+ }
26892
+
26893
+ // src/components/ui/resource-center/resource-cards.tsx
26894
+ var import_react45 = require("react");
26895
+ var import_lucide_react70 = require("lucide-react");
26896
+ var import_jsx_runtime134 = require("react/jsx-runtime");
26605
26897
  function ResourceVideoCard({ video }) {
26606
- const [modalOpen, setModalOpen] = (0, import_react43.useState)(false);
26607
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(import_jsx_runtime131.Fragment, { children: [
26608
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26898
+ const [modalOpen, setModalOpen] = (0, import_react45.useState)(false);
26899
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(import_jsx_runtime134.Fragment, { children: [
26900
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
26609
26901
  "button",
26610
26902
  {
26611
26903
  type: "button",
26612
26904
  onClick: () => setModalOpen(true),
26613
26905
  className: "group relative flex w-full flex-col gap-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
26614
26906
  children: [
26615
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "relative w-full overflow-hidden bg-muted aspect-video", children: [
26616
- video.thumbnailUrl ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26907
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "relative w-full overflow-hidden bg-muted aspect-video", children: [
26908
+ video.thumbnailUrl ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26617
26909
  "img",
26618
26910
  {
26619
26911
  src: video.thumbnailUrl,
26620
26912
  alt: video.title,
26621
26913
  className: "h-full w-full object-cover transition-transform duration-200 group-hover:scale-105"
26622
26914
  }
26623
- ) : /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.Play, { className: "size-10 text-muted-foreground opacity-40" }) }),
26624
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-black/30 opacity-0 transition-opacity duration-200 group-hover:opacity-100", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex size-12 items-center justify-center bg-background/90", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.Play, { className: "size-5 text-foreground" }) }) }),
26625
- video.duration && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("span", { className: "absolute bottom-2 right-2 bg-black/70 px-1.5 py-0.5 text-xs font-medium text-white", children: video.duration })
26915
+ ) : /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(import_lucide_react70.Play, { className: "size-10 text-muted-foreground opacity-40" }) }),
26916
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-black/30 opacity-0 transition-opacity duration-200 group-hover:opacity-100", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "flex size-12 items-center justify-center bg-background/90", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(import_lucide_react70.Play, { className: "size-5 text-foreground" }) }) }),
26917
+ video.duration && /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { className: "absolute bottom-2 right-2 bg-black/70 px-1.5 py-0.5 text-caption text-white", children: video.duration })
26626
26918
  ] }),
26627
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-sm font-medium text-foreground leading-snug line-clamp-2 group-hover:text-primary", children: video.title })
26919
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "text-body-medium font-semibold text-foreground leading-snug line-clamp-2", children: video.title })
26628
26920
  ]
26629
26921
  }
26630
26922
  ),
26631
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26923
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26632
26924
  ResourceModal,
26633
26925
  {
26634
26926
  open: modalOpen,
@@ -26646,7 +26938,7 @@ function ResourceEmailTemplateCard({
26646
26938
  onClick
26647
26939
  }) {
26648
26940
  if (template.isAddTemplate) {
26649
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26941
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
26650
26942
  "button",
26651
26943
  {
26652
26944
  type: "button",
@@ -26654,25 +26946,25 @@ function ResourceEmailTemplateCard({
26654
26946
  className: cn(
26655
26947
  "flex w-full flex-col items-center justify-center gap-3",
26656
26948
  "border-2 border-dashed border-border bg-muted/40",
26657
- "aspect-[3/4] hover:border-primary hover:bg-muted/70 transition-colors",
26949
+ "aspect-video hover:border-primary hover:bg-muted/70 transition-colors",
26658
26950
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
26659
26951
  ),
26660
26952
  children: [
26661
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex size-10 items-center justify-center border-2 border-dashed border-muted-foreground/40", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("span", { className: "text-2xl text-muted-foreground/60", children: "+" }) }),
26662
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-sm font-medium text-muted-foreground", children: "Add Template" })
26953
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "flex size-10 items-center justify-center border-2 border-dashed border-muted-foreground/40", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { className: "text-2xl text-muted-foreground/60", children: "+" }) }),
26954
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "text-body-small font-medium text-muted-foreground", children: "Add Template" })
26663
26955
  ]
26664
26956
  }
26665
26957
  );
26666
26958
  }
26667
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26959
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
26668
26960
  "button",
26669
26961
  {
26670
26962
  type: "button",
26671
26963
  onClick,
26672
26964
  className: "group relative flex w-full flex-col gap-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
26673
26965
  children: [
26674
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "relative w-full overflow-hidden border border-border bg-background aspect-[3/4]", children: [
26675
- template.htmlContent ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26966
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "relative w-full overflow-hidden border border-border bg-background aspect-video", children: [
26967
+ template.htmlContent ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26676
26968
  "iframe",
26677
26969
  {
26678
26970
  srcDoc: template.htmlContent,
@@ -26686,12 +26978,12 @@ function ResourceEmailTemplateCard({
26686
26978
  },
26687
26979
  sandbox: "allow-same-origin"
26688
26980
  }
26689
- ) : /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex h-full w-full items-center justify-center bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-xs text-muted-foreground", children: "No preview available" }) }),
26690
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-foreground/60 opacity-0 transition-opacity duration-200 group-hover:opacity-100", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("span", { className: "text-sm font-medium text-white", children: "Use Template" }) })
26981
+ ) : /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "flex h-full w-full items-center justify-center bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "text-caption text-muted-foreground", children: "No preview available" }) }),
26982
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-foreground/60 opacity-0 transition-opacity duration-200 group-hover:opacity-100", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { className: "text-body-small font-medium text-white", children: "Use Template" }) })
26691
26983
  ] }),
26692
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
26693
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-sm font-medium text-foreground leading-snug line-clamp-1", children: template.title }),
26694
- template.type && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(Badge, { variant: "secondary", className: "shrink-0 text-xs", children: template.type === "system" ? "System" : "Company" })
26984
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
26985
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "text-body-small font-medium text-foreground leading-snug line-clamp-1", children: template.title }),
26986
+ template.type && /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(Badge, { variant: "secondary", className: "shrink-0", children: template.type === "system" ? "System" : "Company" })
26695
26987
  ] })
26696
26988
  ]
26697
26989
  }
@@ -26701,42 +26993,42 @@ function ResourceDocumentCard({
26701
26993
  document: document2,
26702
26994
  onClick
26703
26995
  }) {
26704
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
26705
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26996
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
26997
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
26706
26998
  "button",
26707
26999
  {
26708
27000
  type: "button",
26709
27001
  onClick,
26710
- className: "group relative w-full overflow-hidden border border-border bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring aspect-[3/4]",
27002
+ className: "group relative w-full overflow-hidden border border-border bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring aspect-video",
26711
27003
  children: [
26712
- document2.pdfUrl ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
27004
+ document2.pdfUrl ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26713
27005
  "iframe",
26714
27006
  {
26715
27007
  src: document2.pdfUrl,
26716
27008
  title: document2.title,
26717
27009
  className: "h-full w-full pointer-events-none"
26718
27010
  }
26719
- ) : document2.thumbnailUrl ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
27011
+ ) : document2.thumbnailUrl ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26720
27012
  "img",
26721
27013
  {
26722
27014
  src: document2.thumbnailUrl,
26723
27015
  alt: document2.title,
26724
27016
  className: "h-full w-full object-cover"
26725
27017
  }
26726
- ) : /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex h-full w-full flex-col items-center justify-center gap-2", children: [
26727
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex items-center justify-center bg-muted-foreground/10 p-4", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.Download, { className: "size-8 text-muted-foreground opacity-50" }) }),
26728
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("span", { className: "text-xs text-muted-foreground", children: document2.title })
27018
+ ) : /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "flex h-full w-full flex-col items-center justify-center gap-2", children: [
27019
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "flex items-center justify-center bg-muted-foreground/10 p-4", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(import_lucide_react70.Download, { className: "size-8 text-muted-foreground opacity-50" }) }),
27020
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("span", { className: "text-caption text-muted-foreground", children: document2.title })
26729
27021
  ] }),
26730
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "absolute inset-0 bg-foreground/40 opacity-0 transition-opacity duration-200 group-hover:opacity-100" })
27022
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "absolute inset-0 bg-foreground/40 opacity-0 transition-opacity duration-200 group-hover:opacity-100" })
26731
27023
  ]
26732
27024
  }
26733
27025
  ),
26734
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
26735
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex flex-col gap-1 min-w-0", children: [
26736
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-sm font-medium text-foreground leading-snug line-clamp-1", children: document2.title }),
26737
- document2.tags && document2.tags.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "flex flex-wrap gap-1", children: document2.tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(Badge, { variant: "secondary", className: "text-xs", children: tag }, tag)) })
27026
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
27027
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { className: "flex flex-col gap-1 min-w-0", children: [
27028
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("p", { className: "text-body-small font-medium text-foreground leading-snug line-clamp-1", children: document2.title }),
27029
+ document2.tags && document2.tags.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "flex flex-wrap gap-1", children: document2.tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(Badge, { variant: "secondary", children: tag }, tag)) })
26738
27030
  ] }),
26739
- document2.downloadUrl && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
27031
+ document2.downloadUrl && /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26740
27032
  "a",
26741
27033
  {
26742
27034
  href: document2.downloadUrl,
@@ -26744,134 +27036,99 @@ function ResourceDocumentCard({
26744
27036
  onClick: (e) => e.stopPropagation(),
26745
27037
  className: "shrink-0",
26746
27038
  "aria-label": `Download ${document2.title}`,
26747
- children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(Button, { variant: "outline", size: "icon", className: "size-8", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.Download, { className: "size-4" }) })
27039
+ children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(Button, { variant: "outline", size: "icon", className: "size-8", children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(import_lucide_react70.Download, { className: "size-4" }) })
26748
27040
  }
26749
27041
  )
26750
27042
  ] })
26751
27043
  ] });
26752
27044
  }
26753
- function ResourceCarousel({
26754
- title,
26755
- items,
26756
- headerAction,
26757
- className
27045
+
27046
+ // src/components/ui/resource-center/resource-email-editor-dialog.tsx
27047
+ var import_react46 = require("react");
27048
+ var import_jsx_runtime135 = require("react/jsx-runtime");
27049
+ var EDITOR_CONTENT_TYPES = [
27050
+ "Columns",
27051
+ "Button",
27052
+ "Divider",
27053
+ "Heading",
27054
+ "Paragraph",
27055
+ "Image",
27056
+ "Social",
27057
+ "Menu",
27058
+ "HTML"
27059
+ ];
27060
+ function ResourceEmailEditorDialog({
27061
+ open,
27062
+ onClose,
27063
+ onSave,
27064
+ editorSlot
26758
27065
  }) {
26759
- const scrollRef = (0, import_react43.useRef)(null);
26760
- function scrollLeft() {
26761
- var _a;
26762
- (_a = scrollRef.current) == null ? void 0 : _a.scrollBy({ left: -300, behavior: "smooth" });
27066
+ const [templateName, setTemplateName] = (0, import_react46.useState)("");
27067
+ function handleSave() {
27068
+ onSave(templateName);
26763
27069
  }
26764
- function scrollRight() {
26765
- var _a;
26766
- (_a = scrollRef.current) == null ? void 0 : _a.scrollBy({ left: 300, behavior: "smooth" });
27070
+ function handleClose() {
27071
+ setTemplateName("");
27072
+ onClose();
26767
27073
  }
26768
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: cn("flex flex-col gap-4", className), children: [
26769
- (title || headerAction) && /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
26770
- title && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("h2", { className: "text-lg font-semibold text-foreground", children: title }),
26771
- headerAction && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "shrink-0", children: headerAction })
26772
- ] }),
26773
- items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "py-8 text-center text-sm text-muted-foreground", children: "No items available" }) : /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "group relative", children: [
26774
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
27074
+ return /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(Dialog, { open, onOpenChange: (v) => !v && handleClose(), children: /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)(
27075
+ DialogContent,
27076
+ {
27077
+ size: "4xl",
27078
+ className: "flex flex-col gap-0 p-0 overflow-hidden h-[90vh]",
27079
+ children: [
27080
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "shrink-0 border-b border-border px-6 py-4", children: [
27081
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("p", { className: "text-label-small text-muted-foreground mb-1", children: "Template Name" }),
27082
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
27083
+ Input,
27084
+ {
27085
+ placeholder: "Enter template name",
27086
+ value: templateName,
27087
+ onChange: (e) => setTemplateName(e.target.value),
27088
+ className: "border-none shadow-none px-0 text-body-medium h-auto focus-visible:ring-0 bg-transparent"
27089
+ }
27090
+ )
27091
+ ] }),
27092
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("div", { className: "flex-1 overflow-hidden", children: editorSlot != null ? editorSlot : /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(EditorPlaceholder, {}) }),
27093
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "shrink-0 flex items-center justify-between border-t border-border px-6 py-4", children: [
27094
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(Button, { variant: "outline", onClick: handleClose, children: "Back" }),
27095
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(Button, { variant: "default", onClick: handleSave, children: "Save Email" })
27096
+ ] })
27097
+ ]
27098
+ }
27099
+ ) });
27100
+ }
27101
+ function EditorPlaceholder() {
27102
+ return /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "flex h-full", children: [
27103
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("div", { className: "flex flex-1 items-center justify-center bg-[#f4f4f4]", children: /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("div", { className: "max-w-[500px] w-full border-2 border-dashed border-[#9ecbf0] bg-[#e8f4ff] px-16 py-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("p", { className: "text-body-small text-[#5c9fd8]", children: "No content here. Drag content from right." }) }) }),
27104
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)("div", { className: "w-[280px] shrink-0 flex flex-col border-l border-border bg-background", children: [
27105
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("div", { className: "flex border-b border-border", children: ["Content", "Blocks", "Body"].map((tab, i) => /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
26775
27106
  "button",
26776
27107
  {
26777
27108
  type: "button",
26778
- onClick: scrollLeft,
26779
- "aria-label": "Scroll left",
26780
27109
  className: cn(
26781
- "absolute left-0 top-1/2 z-10 -translate-x-1/2 -translate-y-1/2",
26782
- "flex size-9 items-center justify-center",
26783
- "border border-border bg-background shadow-sm",
26784
- "opacity-0 transition-opacity duration-200 group-hover:opacity-100",
26785
- "hover:bg-muted focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
27110
+ "flex flex-1 flex-col items-center gap-1 py-3 text-caption",
27111
+ i === 0 ? "text-foreground border-b-2 border-foreground" : "text-muted-foreground"
26786
27112
  ),
26787
- children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.ChevronLeft, { className: "size-4 text-foreground" })
26788
- }
26789
- ),
26790
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
27113
+ children: tab
27114
+ },
27115
+ tab
27116
+ )) }),
27117
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("div", { className: "grid grid-cols-3 gap-2 p-3", children: EDITOR_CONTENT_TYPES.map((item) => /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)(
26791
27118
  "div",
26792
27119
  {
26793
- ref: scrollRef,
26794
- className: "flex gap-4 overflow-x-auto scroll-smooth pb-2",
26795
- style: { scrollbarWidth: "none" },
26796
- children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "w-[220px] shrink-0", children: item }, i))
26797
- }
26798
- ),
26799
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26800
- "button",
26801
- {
26802
- type: "button",
26803
- onClick: scrollRight,
26804
- "aria-label": "Scroll right",
26805
- className: cn(
26806
- "absolute right-0 top-1/2 z-10 translate-x-1/2 -translate-y-1/2",
26807
- "flex size-9 items-center justify-center",
26808
- "border border-border bg-background shadow-sm",
26809
- "opacity-0 transition-opacity duration-200 group-hover:opacity-100",
26810
- "hover:bg-muted focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
26811
- ),
26812
- children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.ChevronRight, { className: "size-4 text-foreground" })
26813
- }
26814
- )
27120
+ className: "flex flex-col items-center gap-1.5 border border-border p-2 hover:bg-muted transition-colors cursor-grab",
27121
+ children: [
27122
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("div", { className: "size-6 bg-foreground/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("span", { className: "text-[10px] text-foreground/40", children: "\u25A4" }) }),
27123
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("span", { className: "text-[11px] text-foreground leading-none text-center", children: item })
27124
+ ]
27125
+ },
27126
+ item
27127
+ )) }),
27128
+ /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("div", { className: "mt-auto border-t border-border py-2.5 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime135.jsx)("span", { className: "text-caption text-muted-foreground", children: "\u26A1 by Unlayer Editor" }) })
26815
27129
  ] })
26816
27130
  ] });
26817
27131
  }
26818
- function ResourceCenterHeader({
26819
- title,
26820
- description,
26821
- backgroundVideoUrl,
26822
- watchVideoUrl
26823
- }) {
26824
- const [watchModalOpen, setWatchModalOpen] = (0, import_react43.useState)(false);
26825
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(import_jsx_runtime131.Fragment, { children: [
26826
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26827
- "div",
26828
- {
26829
- className: cn(
26830
- "relative flex min-h-[400px] w-full items-center overflow-hidden bg-foreground"
26831
- ),
26832
- children: [
26833
- backgroundVideoUrl ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26834
- "video",
26835
- {
26836
- className: "absolute inset-0 h-full w-full object-cover opacity-60 z-[1]",
26837
- src: backgroundVideoUrl,
26838
- autoPlay: true,
26839
- muted: true,
26840
- loop: true,
26841
- playsInline: true
26842
- }
26843
- ) : /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "absolute inset-0 bg-foreground z-[1]" }),
26844
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "absolute inset-0 bg-black/40 z-[1]" }),
26845
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "relative z-[2] flex flex-col gap-4 px-8 py-12 md:px-16 max-w-3xl", children: [
26846
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("h1", { className: "text-3xl font-bold text-background md:text-4xl", children: title }),
26847
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-base text-background/80 leading-relaxed", children: description }),
26848
- watchVideoUrl && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26849
- Button,
26850
- {
26851
- variant: "outline",
26852
- className: "border-background text-background bg-transparent hover:bg-background/10 hover:text-background",
26853
- onClick: () => setWatchModalOpen(true),
26854
- children: [
26855
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.Play, { className: "mr-2 size-4" }),
26856
- "Watch Now"
26857
- ]
26858
- }
26859
- ) })
26860
- ] })
26861
- ]
26862
- }
26863
- ),
26864
- watchVideoUrl && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26865
- ResourceModal,
26866
- {
26867
- open: watchModalOpen,
26868
- onClose: () => setWatchModalOpen(false),
26869
- title,
26870
- videoUrl: watchVideoUrl
26871
- }
26872
- )
26873
- ] });
26874
- }
26875
27132
  // Annotate the CommonJS export names for ESM import in node:
26876
27133
  0 && (module.exports = {
26877
27134
  AICollectedDataSection,
@@ -27164,6 +27421,7 @@ function ResourceCenterHeader({
27164
27421
  ResourceCarousel,
27165
27422
  ResourceCenterHeader,
27166
27423
  ResourceDocumentCard,
27424
+ ResourceEmailEditorDialog,
27167
27425
  ResourceEmailTemplateCard,
27168
27426
  ResourceModal,
27169
27427
  ResourceVideoCard,