@wealthx/shadcn 1.5.12 → 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 (32) hide show
  1. package/.turbo/turbo-build.log +74 -74
  2. package/CHANGELOG.md +6 -0
  3. package/dist/{chunk-CPM6P63C.mjs → chunk-BF5FKUF6.mjs} +53 -24
  4. package/dist/chunk-KICT4VQL.mjs +508 -0
  5. package/dist/chunk-V23CBULF.mjs +432 -0
  6. package/dist/components/ui/appointment-calendar-view.js +177 -176
  7. package/dist/components/ui/appointment-calendar-view.mjs +1 -1
  8. package/dist/components/ui/bank-statement-generate-dialog.js +163 -76
  9. package/dist/components/ui/bank-statement-generate-dialog.mjs +2 -1
  10. package/dist/components/ui/resource-center/index.js +1030 -0
  11. package/dist/components/ui/resource-center/index.mjs +29 -0
  12. package/dist/index.js +540 -364
  13. package/dist/index.mjs +15 -13
  14. package/dist/styles.css +1 -1
  15. package/package.json +4 -4
  16. package/src/components/index.tsx +2 -0
  17. package/src/components/ui/appointment-calendar-view.tsx +211 -199
  18. package/src/components/ui/bank-statement-generate-dialog.tsx +125 -97
  19. package/src/components/ui/resource-center/index.tsx +35 -0
  20. package/src/components/ui/resource-center/resource-cards.tsx +218 -0
  21. package/src/components/ui/resource-center/resource-carousel.tsx +122 -0
  22. package/src/components/ui/resource-center/resource-center-header.tsx +95 -0
  23. package/src/components/ui/resource-center/resource-email-editor-dialog.tsx +131 -0
  24. package/src/components/ui/resource-center/resource-modal.tsx +76 -0
  25. package/src/components/ui/resource-center/types.ts +81 -0
  26. package/src/styles/styles-css.ts +1 -1
  27. package/tsup.config.ts +1 -1
  28. package/dist/chunk-IODGRCQG.mjs +0 -438
  29. package/dist/chunk-XYWEGBAA.mjs +0 -348
  30. package/dist/components/ui/resource-center.js +0 -748
  31. package/dist/components/ui/resource-center.mjs +0 -24
  32. 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,
@@ -9459,32 +9460,26 @@ function AppointmentBookDialog({
9459
9460
  // src/components/ui/appointment-calendar-view.tsx
9460
9461
  var import_lucide_react27 = require("lucide-react");
9461
9462
  var import_jsx_runtime47 = require("react/jsx-runtime");
9462
- var STATUS_COLORS = {
9463
- pending: "border-l-warning bg-warning/5",
9464
- confirmed: "border-l-success bg-success/5",
9465
- cancelled: "border-l-destructive bg-destructive/5",
9466
- rescheduled: "border-l-info bg-info/5"
9467
- };
9468
- var STATUS_CONFIG2 = {
9463
+ var STATUS = {
9469
9464
  pending: {
9470
- variant: "warning",
9471
- label: "Pending",
9472
- 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"
9473
9468
  },
9474
9469
  confirmed: {
9475
- variant: "success",
9476
- label: "Confirmed",
9477
- 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"
9478
9473
  },
9479
9474
  cancelled: {
9480
- variant: "destructive",
9481
- label: "Cancelled",
9482
- 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"
9483
9478
  },
9484
9479
  rescheduled: {
9485
- variant: "info",
9486
- label: "Rescheduled",
9487
- 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"
9488
9483
  }
9489
9484
  };
9490
9485
  function formatHour(h) {
@@ -9498,6 +9493,55 @@ function getHourFromTime(time) {
9498
9493
  return time.includes("PM") && h !== 12 ? h + 12 : h;
9499
9494
  }
9500
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
+ }
9501
9545
  function DayView({
9502
9546
  appointments,
9503
9547
  date,
@@ -9506,85 +9550,51 @@ function DayView({
9506
9550
  onSelectAppointment
9507
9551
  }) {
9508
9552
  const d = /* @__PURE__ */ new Date(date + "T00:00:00");
9509
- const dayLabel = formatWeekdayShort(d);
9510
- const dayShort = d.getDate();
9511
9553
  const isToday = date === today;
9512
9554
  const dayApts = appointments.filter((a) => a.date === date);
9513
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col", children: [
9514
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "grid grid-cols-[48px_1fr] border-b border-border", children: [
9515
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-r border-border" }),
9516
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9517
- "div",
9518
- {
9519
- className: `flex flex-col items-center gap-1 py-3 ${isToday ? "bg-primary/5" : ""}`,
9520
- children: [
9521
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9522
- "span",
9523
- {
9524
- className: `text-xs font-medium tracking-wide ${isToday ? "font-semibold text-primary" : "text-muted-foreground"}`,
9525
- children: dayLabel
9526
- }
9527
- ),
9528
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9529
- "span",
9530
- {
9531
- className: `flex h-10 w-10 items-center justify-center text-xl font-semibold ${isToday ? "bg-primary text-primary-foreground" : ""}`,
9532
- children: dayShort
9533
- }
9534
- )
9535
- ]
9536
- }
9537
- )
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
+ ] })
9538
9574
  ] }),
9539
- hours.map((hour) => {
9575
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex flex-1 flex-col", children: hours.map((hour) => {
9540
9576
  const aptsAtHour = dayApts.filter(
9541
9577
  (a) => getHourFromTime(a.timeStart) === hour
9542
9578
  );
9543
9579
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9544
9580
  "div",
9545
9581
  {
9546
- 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",
9547
9583
  children: [
9548
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9549
- "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,
9550
9587
  {
9551
- className: `flex items-start justify-end border-r border-border pr-2 pt-1 ${isToday ? "bg-primary/5" : ""}`,
9552
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-[10px] text-muted-foreground", children: formatHour(hour) })
9553
- }
9554
- ),
9555
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9556
- "div",
9557
- {
9558
- className: `flex flex-col gap-1.5 p-1.5 ${isToday ? "bg-primary/5" : ""}`,
9559
- children: aptsAtHour.map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9560
- Button,
9561
- {
9562
- type: "button",
9563
- variant: "ghost",
9564
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
9565
- 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]}`,
9566
- children: [
9567
- /* @__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 }) }),
9568
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
9569
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-sm font-semibold", children: apt.clientName }),
9570
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
9571
- apt.timeStart,
9572
- " \u2013 ",
9573
- apt.timeEnd
9574
- ] })
9575
- ] }),
9576
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Badge, { variant: STATUS_CONFIG2[apt.status].variant, children: STATUS_CONFIG2[apt.status].label })
9577
- ]
9578
- },
9579
- apt.id
9580
- ))
9581
- }
9582
- )
9588
+ apt,
9589
+ onSelect: onSelectAppointment
9590
+ },
9591
+ apt.id
9592
+ )) })
9583
9593
  ]
9584
9594
  },
9585
9595
  hour
9586
9596
  );
9587
- })
9597
+ }) })
9588
9598
  ] });
9589
9599
  }
9590
9600
  function WeekView({
@@ -9594,49 +9604,39 @@ function WeekView({
9594
9604
  hours,
9595
9605
  onSelectAppointment
9596
9606
  }) {
9597
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col overflow-x-auto", children: [
9598
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9599
- "div",
9600
- {
9601
- className: "grid border-b border-border",
9602
- style: { gridTemplateColumns: `48px repeat(${weekDays.length}, 1fr)` },
9603
- children: [
9604
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-r border-border" }),
9605
- weekDays.map((day) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9606
- "div",
9607
- {
9608
- className: `flex flex-col items-center border-r border-border py-2 last:border-r-0 ${day.date === today ? "bg-primary/5" : ""}`,
9609
- children: [
9610
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9611
- "span",
9612
- {
9613
- className: `text-xs font-medium ${day.date === today ? "font-semibold text-primary" : "text-muted-foreground"}`,
9614
- children: day.label
9615
- }
9616
- ),
9617
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9618
- "span",
9619
- {
9620
- className: `text-sm font-semibold ${day.date === today ? "text-primary" : ""}`,
9621
- children: day.short
9622
- }
9623
- )
9624
- ]
9625
- },
9626
- day.date
9627
- ))
9628
- ]
9629
- }
9630
- ),
9631
- 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)(
9632
9635
  "div",
9633
9636
  {
9634
- className: "grid border-b border-border/40 last:border-b-0",
9635
- style: {
9636
- gridTemplateColumns: `48px repeat(${weekDays.length}, 1fr)`
9637
- },
9637
+ className: "flex flex-1 border-b border-border/40 last:border-b-0",
9638
9638
  children: [
9639
- /* @__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 }),
9640
9640
  weekDays.map((day) => {
9641
9641
  const aptsAtCell = appointments.filter(
9642
9642
  (a) => a.date === day.date && getHourFromTime(a.timeStart) === hour
@@ -9644,19 +9644,13 @@ function WeekView({
9644
9644
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9645
9645
  "div",
9646
9646
  {
9647
- className: `min-h-[44px] overflow-hidden border-r border-border/40 p-0.5 last:border-r-0 ${day.date === today ? "bg-primary/5" : ""}`,
9648
- children: aptsAtCell.map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9649
- 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,
9650
9650
  {
9651
- type: "button",
9652
- variant: "ghost",
9653
- 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]}`,
9654
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
9655
- children: [
9656
- apt.timeStart,
9657
- " ",
9658
- apt.clientName
9659
- ]
9651
+ apt,
9652
+ onSelect: onSelectAppointment,
9653
+ className: "px-2 py-1.5"
9660
9654
  },
9661
9655
  apt.id
9662
9656
  ))
@@ -9667,7 +9661,7 @@ function WeekView({
9667
9661
  ]
9668
9662
  },
9669
9663
  hour
9670
- ))
9664
+ )) })
9671
9665
  ] });
9672
9666
  }
9673
9667
  var MONTH_DAY_HEADERS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
@@ -9699,19 +9693,19 @@ function MonthView({
9699
9693
  const vd = /* @__PURE__ */ new Date(viewDate + "T00:00:00");
9700
9694
  const grid = generateMonthGrid(vd.getFullYear(), vd.getMonth());
9701
9695
  const toIso = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
9702
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col", children: [
9703
- /* @__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)(
9704
9698
  "div",
9705
9699
  {
9706
9700
  className: "flex items-center justify-center border-r border-border/40 py-2 last:border-r-0",
9707
- 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 })
9708
9702
  },
9709
9703
  d
9710
9704
  )) }),
9711
- 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)(
9712
9706
  "div",
9713
9707
  {
9714
- 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",
9715
9709
  children: week.map((day, di) => {
9716
9710
  const iso = day ? toIso(day) : null;
9717
9711
  const dayApts = iso ? appointments.filter((a) => a.date === iso) : [];
@@ -9719,32 +9713,26 @@ function MonthView({
9719
9713
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9720
9714
  "div",
9721
9715
  {
9722
- 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" : ""}`,
9723
9717
  children: day && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
9724
9718
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9725
9719
  "div",
9726
9720
  {
9727
- 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"}`,
9728
9722
  children: day.getDate()
9729
9723
  }
9730
9724
  ),
9731
9725
  /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
9732
- dayApts.slice(0, 2).map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9733
- Button,
9726
+ dayApts.slice(0, 2).map((apt) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9727
+ AptChip,
9734
9728
  {
9735
- type: "button",
9736
- variant: "ghost",
9737
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
9738
- 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]}`,
9739
- children: [
9740
- apt.timeStart,
9741
- " ",
9742
- apt.clientName
9743
- ]
9729
+ apt,
9730
+ onSelect: onSelectAppointment,
9731
+ className: "px-1.5 py-1"
9744
9732
  },
9745
9733
  apt.id
9746
9734
  )),
9747
- 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: [
9748
9736
  "+",
9749
9737
  dayApts.length - 2,
9750
9738
  " more"
@@ -9757,7 +9745,7 @@ function MonthView({
9757
9745
  })
9758
9746
  },
9759
9747
  wi
9760
- ))
9748
+ )) })
9761
9749
  ] });
9762
9750
  }
9763
9751
  function AppointmentCalendarView({
@@ -9778,7 +9766,7 @@ function AppointmentCalendarView({
9778
9766
  }) {
9779
9767
  var _a;
9780
9768
  const effectiveViewDate = (_a = viewDate != null ? viewDate : dayViewDate) != null ? _a : today;
9781
- 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: [
9782
9770
  /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between gap-4 px-4 py-3", children: [
9783
9771
  /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
9784
9772
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
@@ -9791,7 +9779,7 @@ function AppointmentCalendarView({
9791
9779
  children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react27.ChevronLeft, { className: "h-3.5 w-3.5" })
9792
9780
  }
9793
9781
  ),
9794
- /* @__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 }),
9795
9783
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9796
9784
  Button,
9797
9785
  {
@@ -9812,38 +9800,52 @@ function AppointmentCalendarView({
9812
9800
  {
9813
9801
  defaultValue: defaultView,
9814
9802
  onValueChange: (v) => onViewChange == null ? void 0 : onViewChange(v),
9815
- className: "flex flex-col",
9803
+ className: "flex flex-col flex-1 min-h-0",
9816
9804
  children: [
9817
9805
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "px-4 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(TabsList, { children: [
9818
9806
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TabsTrigger, { value: "day", children: "Day" }),
9819
9807
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TabsTrigger, { value: "week", children: "Week" }),
9820
9808
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TabsTrigger, { value: "month", children: "Month" })
9821
9809
  ] }) }),
9822
- /* @__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)(
9823
- DayView,
9810
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9811
+ TabsContent,
9824
9812
  {
9825
- appointments,
9826
- date: effectiveViewDate,
9827
- today,
9828
- hours,
9829
- 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
+ )
9830
9825
  }
9831
- ) }),
9832
- /* @__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)(
9833
- WeekView,
9826
+ ),
9827
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9828
+ TabsContent,
9834
9829
  {
9835
- appointments,
9836
- weekDays,
9837
- today,
9838
- hours,
9839
- 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
+ )
9840
9842
  }
9841
- ) }),
9843
+ ),
9842
9844
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9843
9845
  TabsContent,
9844
9846
  {
9845
9847
  value: "month",
9846
- className: "mt-0 max-h-[75vh] overflow-y-auto",
9848
+ className: "mt-0 min-h-0 flex-1 flex flex-col overflow-y-auto",
9847
9849
  children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9848
9850
  MonthView,
9849
9851
  {
@@ -9865,7 +9867,7 @@ function AppointmentCalendarView({
9865
9867
  var import_react14 = __toESM(require("react"));
9866
9868
  var import_lucide_react28 = require("lucide-react");
9867
9869
  var import_jsx_runtime48 = require("react/jsx-runtime");
9868
- var STATUS_CONFIG3 = {
9870
+ var STATUS_CONFIG2 = {
9869
9871
  pending: {
9870
9872
  variant: "warning",
9871
9873
  label: "Pending",
@@ -9919,7 +9921,7 @@ function AppointmentDetailSheet({
9919
9921
  const [confirmAction, setConfirmAction] = import_react14.default.useState(null);
9920
9922
  const [rescheduleOpen, setRescheduleOpen] = import_react14.default.useState(false);
9921
9923
  if (!appointment) return null;
9922
- const { variant, label, icon } = STATUS_CONFIG3[appointment.status];
9924
+ const { variant, label, icon } = STATUS_CONFIG2[appointment.status];
9923
9925
  const isCancelled = appointment.status === "cancelled";
9924
9926
  const isConfirmed = appointment.status === "confirmed";
9925
9927
  const fmt2 = appointment.meetingFormat;
@@ -12062,6 +12064,7 @@ var APPLICANT_TYPE_LABELS = {
12062
12064
  primary: "Main applicant",
12063
12065
  secondary: "Co-applicant"
12064
12066
  };
12067
+ var ACCOUNTS_PAGE_SIZE = 5;
12065
12068
  function toIsoDate(date) {
12066
12069
  return date.toISOString().slice(0, 10);
12067
12070
  }
@@ -12091,25 +12094,31 @@ function BankStatementGenerateDialog({
12091
12094
  const [toDate, setToDate] = (0, import_react21.useState)(() => presetToDateRange(90).to);
12092
12095
  const [applicantType, setApplicantType] = (0, import_react21.useState)("");
12093
12096
  const [selectedAccountIds, setSelectedAccountIds] = (0, import_react21.useState)([]);
12097
+ const [accountPage, setAccountPage] = (0, import_react21.useState)(1);
12094
12098
  (0, import_react21.useEffect)(() => {
12095
12099
  if (!open) return;
12096
12100
  const timer = setTimeout(() => {
12097
- setStatementName("Bank Statement 1");
12098
- setApplicantType("");
12099
- setSelectedAccountIds([]);
12100
12101
  const { from, to } = presetToDateRange(90);
12102
+ setStatementName("Bank Statement 1");
12101
12103
  setRangePreset(90);
12102
12104
  setFromDate(from);
12103
12105
  setToDate(to);
12106
+ setApplicantType("");
12107
+ setSelectedAccountIds([]);
12108
+ setAccountPage(1);
12104
12109
  }, 0);
12105
12110
  return () => clearTimeout(timer);
12106
12111
  }, [open]);
12107
12112
  const handleApplicantTypeChange = (type) => {
12108
12113
  setApplicantType(type);
12109
12114
  setSelectedAccountIds([]);
12115
+ setAccountPage(1);
12110
12116
  onApplicantTypeChange == null ? void 0 : onApplicantTypeChange(type);
12111
12117
  };
12112
- 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);
12113
12122
  setRangePreset(preset);
12114
12123
  if (preset !== "custom") {
12115
12124
  const { from, to } = presetToDateRange(preset);
@@ -12117,11 +12126,6 @@ function BankStatementGenerateDialog({
12117
12126
  setToDate(to);
12118
12127
  }
12119
12128
  };
12120
- const handlePresetChange = (val) => {
12121
- if (val.length === 0) return;
12122
- const raw = val[0];
12123
- applyPreset(raw === "custom" ? "custom" : Number(raw));
12124
- };
12125
12129
  const areAllSelected = bankAccounts.length > 0 && selectedAccountIds.length === bankAccounts.length;
12126
12130
  const isSomeSelected = selectedAccountIds.length > 0 && !areAllSelected;
12127
12131
  const handleToggleAccount = (id) => {
@@ -12130,12 +12134,13 @@ function BankStatementGenerateDialog({
12130
12134
  );
12131
12135
  };
12132
12136
  const handleToggleAll = () => {
12133
- if (areAllSelected) {
12134
- setSelectedAccountIds([]);
12135
- } else {
12136
- setSelectedAccountIds(bankAccounts.map((a) => a.id));
12137
- }
12137
+ setSelectedAccountIds(areAllSelected ? [] : bankAccounts.map((a) => a.id));
12138
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
+ );
12139
12144
  const periodLabel = (0, import_react21.useMemo)(() => {
12140
12145
  if (fromDate && toDate) {
12141
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")}`;
@@ -12228,10 +12233,8 @@ function BankStatementGenerateDialog({
12228
12233
  ]
12229
12234
  }
12230
12235
  ),
12231
- applicantType && /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "mt-1", children: [
12232
- 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" }) }),
12233
- !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" }),
12234
- !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: [
12235
12238
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(TableRow, { children: [
12236
12239
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { className: "w-10", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
12237
12240
  Checkbox,
@@ -12243,11 +12246,11 @@ function BankStatementGenerateDialog({
12243
12246
  }
12244
12247
  ) }),
12245
12248
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { children: "Account Name" }),
12246
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { children: "Account Number" }),
12247
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableHead, { children: "Period" }),
12248
- /* @__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" })
12249
12252
  ] }) }),
12250
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableBody, { children: bankAccounts.map((account) => {
12253
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TableBody, { children: pagedAccounts.map((account) => {
12251
12254
  var _a, _b;
12252
12255
  const isSelected = selectedAccountIds.includes(
12253
12256
  account.id
@@ -12287,8 +12290,33 @@ function BankStatementGenerateDialog({
12287
12290
  account.id
12288
12291
  );
12289
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
+ )
12290
12318
  ] })
12291
- ] })
12319
+ ] }) })
12292
12320
  ] }),
12293
12321
  /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(DialogFooter, { children: [
12294
12322
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Button, { variant: "ghost", onClick: onClose, children: "Cancel" }),
@@ -21954,7 +21982,7 @@ function ApplicantCardTab({
21954
21982
  ] });
21955
21983
  }
21956
21984
  var STATUS_OPTIONS = ["verified", "pending", "rejected"];
21957
- var STATUS_CONFIG4 = {
21985
+ var STATUS_CONFIG3 = {
21958
21986
  verified: {
21959
21987
  Icon: import_lucide_react56.CheckCircle2,
21960
21988
  label: "Verified",
@@ -21987,7 +22015,7 @@ function DocRow({
21987
22015
  label: statusLabel,
21988
22016
  iconCls,
21989
22017
  triggerCls
21990
- } = STATUS_CONFIG4[status];
22018
+ } = STATUS_CONFIG3[status];
21991
22019
  return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
21992
22020
  "div",
21993
22021
  {
@@ -22035,7 +22063,7 @@ function DocRow({
22035
22063
  }
22036
22064
  ),
22037
22065
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(SelectContent, { children: STATUS_OPTIONS.map((v) => {
22038
- const { Icon, label, iconCls: iconCls2 } = STATUS_CONFIG4[v];
22066
+ const { Icon, label, iconCls: iconCls2 } = STATUS_CONFIG3[v];
22039
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: [
22040
22068
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Icon, { className: cn("size-3.5", iconCls2) }),
22041
22069
  label
@@ -26434,7 +26462,7 @@ function IncomeWorkDetails({
26434
26462
  // src/components/ui/loan-application-badge.tsx
26435
26463
  var import_lucide_react66 = require("lucide-react");
26436
26464
  var import_jsx_runtime128 = require("react/jsx-runtime");
26437
- var STATUS_CONFIG5 = {
26465
+ var STATUS_CONFIG4 = {
26438
26466
  SENT: {
26439
26467
  label: "Sent Application",
26440
26468
  statusClassName: "border-info/40 bg-info/10 text-info-text",
@@ -26455,7 +26483,7 @@ function LoanApplicationBadge({
26455
26483
  status,
26456
26484
  className
26457
26485
  }) {
26458
- const { label, statusClassName, showCheck } = STATUS_CONFIG5[status];
26486
+ const { label, statusClassName, showCheck } = STATUS_CONFIG4[status];
26459
26487
  return /* @__PURE__ */ (0, import_jsx_runtime128.jsxs)(
26460
26488
  Badge,
26461
26489
  {
@@ -26631,10 +26659,107 @@ function ChevronRightIcon4({ className }) {
26631
26659
  );
26632
26660
  }
26633
26661
 
26634
- // src/components/ui/resource-center.tsx
26662
+ // src/components/ui/resource-center/resource-carousel.tsx
26635
26663
  var import_react43 = require("react");
26636
26664
  var import_lucide_react67 = require("lucide-react");
26637
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");
26638
26763
  function ResourceModal({
26639
26764
  open,
26640
26765
  onClose,
@@ -26643,17 +26768,17 @@ function ResourceModal({
26643
26768
  tags,
26644
26769
  attachments
26645
26770
  }) {
26646
- 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)(
26647
26772
  DialogContent,
26648
26773
  {
26649
26774
  size: "2xl",
26650
26775
  className: "flex flex-col gap-4 p-0 overflow-hidden",
26651
26776
  children: [
26652
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(DialogHeader, { className: "px-6 pt-6 pb-0", children: [
26653
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(DialogTitle, { className: "text-lg font-semibold", children: title }),
26654
- 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)) })
26655
26780
  ] }),
26656
- 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)(
26657
26782
  "iframe",
26658
26783
  {
26659
26784
  src: videoUrl,
@@ -26663,54 +26788,139 @@ function ResourceModal({
26663
26788
  allowFullScreen: true
26664
26789
  }
26665
26790
  ) }),
26666
- attachments && attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex flex-col gap-2 px-6 pb-6", children: [
26667
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Attachments" }),
26668
- /* @__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)(
26669
26794
  "a",
26670
26795
  {
26671
26796
  href: attachment.url,
26672
26797
  download: true,
26673
- 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",
26674
26799
  children: [
26675
- /* @__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" }),
26676
26801
  attachment.name
26677
26802
  ]
26678
26803
  },
26679
26804
  i
26680
26805
  )) })
26681
26806
  ] }),
26682
- (!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" })
26683
26808
  ]
26684
26809
  }
26685
26810
  ) });
26686
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");
26687
26897
  function ResourceVideoCard({ video }) {
26688
- const [modalOpen, setModalOpen] = (0, import_react43.useState)(false);
26689
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(import_jsx_runtime131.Fragment, { children: [
26690
- /* @__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)(
26691
26901
  "button",
26692
26902
  {
26693
26903
  type: "button",
26694
26904
  onClick: () => setModalOpen(true),
26695
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",
26696
26906
  children: [
26697
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "relative w-full overflow-hidden bg-muted aspect-video", children: [
26698
- 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)(
26699
26909
  "img",
26700
26910
  {
26701
26911
  src: video.thumbnailUrl,
26702
26912
  alt: video.title,
26703
26913
  className: "h-full w-full object-cover transition-transform duration-200 group-hover:scale-105"
26704
26914
  }
26705
- ) : /* @__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" }) }),
26706
- /* @__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" }) }) }),
26707
- 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 })
26708
26918
  ] }),
26709
- /* @__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 })
26710
26920
  ]
26711
26921
  }
26712
26922
  ),
26713
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26923
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26714
26924
  ResourceModal,
26715
26925
  {
26716
26926
  open: modalOpen,
@@ -26728,7 +26938,7 @@ function ResourceEmailTemplateCard({
26728
26938
  onClick
26729
26939
  }) {
26730
26940
  if (template.isAddTemplate) {
26731
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26941
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
26732
26942
  "button",
26733
26943
  {
26734
26944
  type: "button",
@@ -26736,25 +26946,25 @@ function ResourceEmailTemplateCard({
26736
26946
  className: cn(
26737
26947
  "flex w-full flex-col items-center justify-center gap-3",
26738
26948
  "border-2 border-dashed border-border bg-muted/40",
26739
- "aspect-[3/4] hover:border-primary hover:bg-muted/70 transition-colors",
26949
+ "aspect-video hover:border-primary hover:bg-muted/70 transition-colors",
26740
26950
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
26741
26951
  ),
26742
26952
  children: [
26743
- /* @__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: "+" }) }),
26744
- /* @__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" })
26745
26955
  ]
26746
26956
  }
26747
26957
  );
26748
26958
  }
26749
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26959
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
26750
26960
  "button",
26751
26961
  {
26752
26962
  type: "button",
26753
26963
  onClick,
26754
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",
26755
26965
  children: [
26756
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "relative w-full overflow-hidden border border-border bg-background aspect-[3/4]", children: [
26757
- 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)(
26758
26968
  "iframe",
26759
26969
  {
26760
26970
  srcDoc: template.htmlContent,
@@ -26768,12 +26978,12 @@ function ResourceEmailTemplateCard({
26768
26978
  },
26769
26979
  sandbox: "allow-same-origin"
26770
26980
  }
26771
- ) : /* @__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" }) }),
26772
- /* @__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" }) })
26773
26983
  ] }),
26774
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
26775
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-sm font-medium text-foreground leading-snug line-clamp-1", children: template.title }),
26776
- 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" })
26777
26987
  ] })
26778
26988
  ]
26779
26989
  }
@@ -26783,42 +26993,42 @@ function ResourceDocumentCard({
26783
26993
  document: document2,
26784
26994
  onClick
26785
26995
  }) {
26786
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
26787
- /* @__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)(
26788
26998
  "button",
26789
26999
  {
26790
27000
  type: "button",
26791
27001
  onClick,
26792
- 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",
26793
27003
  children: [
26794
- document2.pdfUrl ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
27004
+ document2.pdfUrl ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26795
27005
  "iframe",
26796
27006
  {
26797
27007
  src: document2.pdfUrl,
26798
27008
  title: document2.title,
26799
27009
  className: "h-full w-full pointer-events-none"
26800
27010
  }
26801
- ) : document2.thumbnailUrl ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
27011
+ ) : document2.thumbnailUrl ? /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26802
27012
  "img",
26803
27013
  {
26804
27014
  src: document2.thumbnailUrl,
26805
27015
  alt: document2.title,
26806
27016
  className: "h-full w-full object-cover"
26807
27017
  }
26808
- ) : /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex h-full w-full flex-col items-center justify-center gap-2", children: [
26809
- /* @__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" }) }),
26810
- /* @__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 })
26811
27021
  ] }),
26812
- /* @__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" })
26813
27023
  ]
26814
27024
  }
26815
27025
  ),
26816
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
26817
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex flex-col gap-1 min-w-0", children: [
26818
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-sm font-medium text-foreground leading-snug line-clamp-1", children: document2.title }),
26819
- 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)) })
26820
27030
  ] }),
26821
- document2.downloadUrl && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
27031
+ document2.downloadUrl && /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
26822
27032
  "a",
26823
27033
  {
26824
27034
  href: document2.downloadUrl,
@@ -26826,134 +27036,99 @@ function ResourceDocumentCard({
26826
27036
  onClick: (e) => e.stopPropagation(),
26827
27037
  className: "shrink-0",
26828
27038
  "aria-label": `Download ${document2.title}`,
26829
- 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" }) })
26830
27040
  }
26831
27041
  )
26832
27042
  ] })
26833
27043
  ] });
26834
27044
  }
26835
- function ResourceCarousel({
26836
- title,
26837
- items,
26838
- headerAction,
26839
- 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
26840
27065
  }) {
26841
- const scrollRef = (0, import_react43.useRef)(null);
26842
- function scrollLeft() {
26843
- var _a;
26844
- (_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);
26845
27069
  }
26846
- function scrollRight() {
26847
- var _a;
26848
- (_a = scrollRef.current) == null ? void 0 : _a.scrollBy({ left: 300, behavior: "smooth" });
27070
+ function handleClose() {
27071
+ setTemplateName("");
27072
+ onClose();
26849
27073
  }
26850
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: cn("flex flex-col gap-4", className), children: [
26851
- (title || headerAction) && /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
26852
- title && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("h2", { className: "text-lg font-semibold text-foreground", children: title }),
26853
- headerAction && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "shrink-0", children: headerAction })
26854
- ] }),
26855
- 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: [
26856
- /* @__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)(
26857
27106
  "button",
26858
27107
  {
26859
27108
  type: "button",
26860
- onClick: scrollLeft,
26861
- "aria-label": "Scroll left",
26862
27109
  className: cn(
26863
- "absolute left-0 top-1/2 z-10 -translate-x-1/2 -translate-y-1/2",
26864
- "flex size-9 items-center justify-center",
26865
- "border border-border bg-background shadow-sm",
26866
- "opacity-0 transition-opacity duration-200 group-hover:opacity-100",
26867
- "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"
26868
27112
  ),
26869
- children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.ChevronLeft, { className: "size-4 text-foreground" })
26870
- }
26871
- ),
26872
- /* @__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)(
26873
27118
  "div",
26874
27119
  {
26875
- ref: scrollRef,
26876
- className: "flex gap-4 overflow-x-auto scroll-smooth pb-2",
26877
- style: { scrollbarWidth: "none" },
26878
- children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "w-[220px] shrink-0", children: item }, i))
26879
- }
26880
- ),
26881
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26882
- "button",
26883
- {
26884
- type: "button",
26885
- onClick: scrollRight,
26886
- "aria-label": "Scroll right",
26887
- className: cn(
26888
- "absolute right-0 top-1/2 z-10 translate-x-1/2 -translate-y-1/2",
26889
- "flex size-9 items-center justify-center",
26890
- "border border-border bg-background shadow-sm",
26891
- "opacity-0 transition-opacity duration-200 group-hover:opacity-100",
26892
- "hover:bg-muted focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
26893
- ),
26894
- children: /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.ChevronRight, { className: "size-4 text-foreground" })
26895
- }
26896
- )
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" }) })
26897
27129
  ] })
26898
27130
  ] });
26899
27131
  }
26900
- function ResourceCenterHeader({
26901
- title,
26902
- description,
26903
- backgroundVideoUrl,
26904
- watchVideoUrl
26905
- }) {
26906
- const [watchModalOpen, setWatchModalOpen] = (0, import_react43.useState)(false);
26907
- return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(import_jsx_runtime131.Fragment, { children: [
26908
- /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26909
- "div",
26910
- {
26911
- className: cn(
26912
- "relative flex min-h-[400px] w-full items-center overflow-hidden bg-foreground"
26913
- ),
26914
- children: [
26915
- backgroundVideoUrl ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26916
- "video",
26917
- {
26918
- className: "absolute inset-0 h-full w-full object-cover opacity-60 z-[1]",
26919
- src: backgroundVideoUrl,
26920
- autoPlay: true,
26921
- muted: true,
26922
- loop: true,
26923
- playsInline: true
26924
- }
26925
- ) : /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "absolute inset-0 bg-foreground z-[1]" }),
26926
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "absolute inset-0 bg-black/40 z-[1]" }),
26927
- /* @__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: [
26928
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("h1", { className: "text-3xl font-bold text-background md:text-4xl", children: title }),
26929
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("p", { className: "text-base text-background/80 leading-relaxed", children: description }),
26930
- watchVideoUrl && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)(
26931
- Button,
26932
- {
26933
- variant: "outline",
26934
- className: "border-background text-background bg-transparent hover:bg-background/10 hover:text-background",
26935
- onClick: () => setWatchModalOpen(true),
26936
- children: [
26937
- /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_lucide_react67.Play, { className: "mr-2 size-4" }),
26938
- "Watch Now"
26939
- ]
26940
- }
26941
- ) })
26942
- ] })
26943
- ]
26944
- }
26945
- ),
26946
- watchVideoUrl && /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
26947
- ResourceModal,
26948
- {
26949
- open: watchModalOpen,
26950
- onClose: () => setWatchModalOpen(false),
26951
- title,
26952
- videoUrl: watchVideoUrl
26953
- }
26954
- )
26955
- ] });
26956
- }
26957
27132
  // Annotate the CommonJS export names for ESM import in node:
26958
27133
  0 && (module.exports = {
26959
27134
  AICollectedDataSection,
@@ -27246,6 +27421,7 @@ function ResourceCenterHeader({
27246
27421
  ResourceCarousel,
27247
27422
  ResourceCenterHeader,
27248
27423
  ResourceDocumentCard,
27424
+ ResourceEmailEditorDialog,
27249
27425
  ResourceEmailTemplateCard,
27250
27426
  ResourceModal,
27251
27427
  ResourceVideoCard,