@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/tsup.config.ts CHANGED
@@ -185,7 +185,7 @@ export default defineConfig((options) => ({
185
185
  "src/components/ui/loan-entry-shell.tsx",
186
186
  "src/components/ui/loan-wizard-shell.tsx",
187
187
  "src/components/ui/loan-application-badge.tsx",
188
- "src/components/ui/resource-center.tsx",
188
+ "src/components/ui/resource-center/index.tsx",
189
189
  ],
190
190
  format: ["cjs", "esm"],
191
191
  // Types are served directly from src/*.tsx via package.json exports — DTS disabled
@@ -1,438 +0,0 @@
1
- import {
2
- Tabs,
3
- TabsContent,
4
- TabsList,
5
- TabsTrigger
6
- } from "./chunk-WE4YKBDE.mjs";
7
- import {
8
- Separator
9
- } from "./chunk-2GIYVERS.mjs";
10
- import {
11
- Avatar,
12
- AvatarFallback
13
- } from "./chunk-H6NQTIF4.mjs";
14
- import {
15
- Badge
16
- } from "./chunk-X6RC5UWB.mjs";
17
- import {
18
- formatWeekdayShort
19
- } from "./chunk-LHWJQNLG.mjs";
20
- import {
21
- Button
22
- } from "./chunk-NOOEKOWY.mjs";
23
-
24
- // src/components/ui/appointment-calendar-view.tsx
25
- import {
26
- Check,
27
- ChevronLeft,
28
- ChevronRight,
29
- RefreshCw,
30
- X,
31
- CalendarClock
32
- } from "lucide-react";
33
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
34
- var STATUS_COLORS = {
35
- pending: "border-l-warning bg-warning/5",
36
- confirmed: "border-l-success bg-success/5",
37
- cancelled: "border-l-destructive bg-destructive/5",
38
- rescheduled: "border-l-info bg-info/5"
39
- };
40
- var STATUS_CONFIG = {
41
- pending: {
42
- variant: "warning",
43
- label: "Pending",
44
- icon: /* @__PURE__ */ jsx(CalendarClock, { size: 12 })
45
- },
46
- confirmed: {
47
- variant: "success",
48
- label: "Confirmed",
49
- icon: /* @__PURE__ */ jsx(Check, { size: 12 })
50
- },
51
- cancelled: {
52
- variant: "destructive",
53
- label: "Cancelled",
54
- icon: /* @__PURE__ */ jsx(X, { size: 12 })
55
- },
56
- rescheduled: {
57
- variant: "info",
58
- label: "Rescheduled",
59
- icon: /* @__PURE__ */ jsx(RefreshCw, { size: 12 })
60
- }
61
- };
62
- function formatHour(h) {
63
- if (h === 12) return "12 PM";
64
- return h < 12 ? `${h} AM` : `${h - 12} PM`;
65
- }
66
- function getHourFromTime(time) {
67
- const match = time.match(/^(\d+):/);
68
- if (!match) return 0;
69
- const h = parseInt(match[1], 10);
70
- return time.includes("PM") && h !== 12 ? h + 12 : h;
71
- }
72
- var DEFAULT_HOURS = [9, 10, 11, 12, 13, 14, 15, 16, 17];
73
- function DayView({
74
- appointments,
75
- date,
76
- today,
77
- hours,
78
- onSelectAppointment
79
- }) {
80
- const d = /* @__PURE__ */ new Date(date + "T00:00:00");
81
- const dayLabel = formatWeekdayShort(d);
82
- const dayShort = d.getDate();
83
- const isToday = date === today;
84
- const dayApts = appointments.filter((a) => a.date === date);
85
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
86
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[48px_1fr] border-b border-border", children: [
87
- /* @__PURE__ */ jsx("div", { className: "border-r border-border" }),
88
- /* @__PURE__ */ jsxs(
89
- "div",
90
- {
91
- className: `flex flex-col items-center gap-1 py-3 ${isToday ? "bg-primary/5" : ""}`,
92
- children: [
93
- /* @__PURE__ */ jsx(
94
- "span",
95
- {
96
- className: `text-xs font-medium tracking-wide ${isToday ? "font-semibold text-primary" : "text-muted-foreground"}`,
97
- children: dayLabel
98
- }
99
- ),
100
- /* @__PURE__ */ jsx(
101
- "span",
102
- {
103
- className: `flex h-10 w-10 items-center justify-center text-xl font-semibold ${isToday ? "bg-primary text-primary-foreground" : ""}`,
104
- children: dayShort
105
- }
106
- )
107
- ]
108
- }
109
- )
110
- ] }),
111
- hours.map((hour) => {
112
- const aptsAtHour = dayApts.filter(
113
- (a) => getHourFromTime(a.timeStart) === hour
114
- );
115
- return /* @__PURE__ */ jsxs(
116
- "div",
117
- {
118
- className: "grid min-h-[60px] grid-cols-[48px_1fr] border-b border-border/40 last:border-b-0",
119
- children: [
120
- /* @__PURE__ */ jsx(
121
- "div",
122
- {
123
- className: `flex items-start justify-end border-r border-border pr-2 pt-1 ${isToday ? "bg-primary/5" : ""}`,
124
- children: /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: formatHour(hour) })
125
- }
126
- ),
127
- /* @__PURE__ */ jsx(
128
- "div",
129
- {
130
- className: `flex flex-col gap-1.5 p-1.5 ${isToday ? "bg-primary/5" : ""}`,
131
- children: aptsAtHour.map((apt) => /* @__PURE__ */ jsxs(
132
- Button,
133
- {
134
- type: "button",
135
- variant: "ghost",
136
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
137
- 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]}`,
138
- children: [
139
- /* @__PURE__ */ jsx(Avatar, { className: "h-7 w-7 shrink-0", children: /* @__PURE__ */ jsx(AvatarFallback, { className: "text-xs", children: apt.clientAvatarInitials }) }),
140
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
141
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: apt.clientName }),
142
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
143
- apt.timeStart,
144
- " \u2013 ",
145
- apt.timeEnd
146
- ] })
147
- ] }),
148
- /* @__PURE__ */ jsx(Badge, { variant: STATUS_CONFIG[apt.status].variant, children: STATUS_CONFIG[apt.status].label })
149
- ]
150
- },
151
- apt.id
152
- ))
153
- }
154
- )
155
- ]
156
- },
157
- hour
158
- );
159
- })
160
- ] });
161
- }
162
- function WeekView({
163
- appointments,
164
- weekDays,
165
- today,
166
- hours,
167
- onSelectAppointment
168
- }) {
169
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col overflow-x-auto", children: [
170
- /* @__PURE__ */ jsxs(
171
- "div",
172
- {
173
- className: "grid border-b border-border",
174
- style: { gridTemplateColumns: `48px repeat(${weekDays.length}, 1fr)` },
175
- children: [
176
- /* @__PURE__ */ jsx("div", { className: "border-r border-border" }),
177
- weekDays.map((day) => /* @__PURE__ */ jsxs(
178
- "div",
179
- {
180
- className: `flex flex-col items-center border-r border-border py-2 last:border-r-0 ${day.date === today ? "bg-primary/5" : ""}`,
181
- children: [
182
- /* @__PURE__ */ jsx(
183
- "span",
184
- {
185
- className: `text-xs font-medium ${day.date === today ? "font-semibold text-primary" : "text-muted-foreground"}`,
186
- children: day.label
187
- }
188
- ),
189
- /* @__PURE__ */ jsx(
190
- "span",
191
- {
192
- className: `text-sm font-semibold ${day.date === today ? "text-primary" : ""}`,
193
- children: day.short
194
- }
195
- )
196
- ]
197
- },
198
- day.date
199
- ))
200
- ]
201
- }
202
- ),
203
- hours.map((hour) => /* @__PURE__ */ jsxs(
204
- "div",
205
- {
206
- className: "grid border-b border-border/40 last:border-b-0",
207
- style: {
208
- gridTemplateColumns: `48px repeat(${weekDays.length}, 1fr)`
209
- },
210
- children: [
211
- /* @__PURE__ */ jsx("div", { className: "flex items-start justify-end border-r border-border pr-2 pt-1", children: /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: formatHour(hour) }) }),
212
- weekDays.map((day) => {
213
- const aptsAtCell = appointments.filter(
214
- (a) => a.date === day.date && getHourFromTime(a.timeStart) === hour
215
- );
216
- return /* @__PURE__ */ jsx(
217
- "div",
218
- {
219
- className: `min-h-[44px] overflow-hidden border-r border-border/40 p-0.5 last:border-r-0 ${day.date === today ? "bg-primary/5" : ""}`,
220
- children: aptsAtCell.map((apt) => /* @__PURE__ */ jsxs(
221
- Button,
222
- {
223
- type: "button",
224
- variant: "ghost",
225
- 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]}`,
226
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
227
- children: [
228
- apt.timeStart,
229
- " ",
230
- apt.clientName
231
- ]
232
- },
233
- apt.id
234
- ))
235
- },
236
- day.date
237
- );
238
- })
239
- ]
240
- },
241
- hour
242
- ))
243
- ] });
244
- }
245
- var MONTH_DAY_HEADERS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
246
- function generateMonthGrid(year, month) {
247
- const firstDay = new Date(year, month, 1);
248
- const lastDay = new Date(year, month + 1, 0);
249
- const startDow = firstDay.getDay();
250
- const grid = [];
251
- let week = Array.from({ length: startDow }, () => null);
252
- for (let day = 1; day <= lastDay.getDate(); day++) {
253
- week.push(new Date(year, month, day));
254
- if (week.length === 7) {
255
- grid.push(week);
256
- week = [];
257
- }
258
- }
259
- if (week.length > 0) {
260
- while (week.length < 7) week.push(null);
261
- grid.push(week);
262
- }
263
- return grid;
264
- }
265
- function MonthView({
266
- appointments,
267
- viewDate,
268
- today,
269
- onSelectAppointment
270
- }) {
271
- const vd = /* @__PURE__ */ new Date(viewDate + "T00:00:00");
272
- const grid = generateMonthGrid(vd.getFullYear(), vd.getMonth());
273
- const toIso = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
274
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
275
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 border-b border-border", children: MONTH_DAY_HEADERS.map((d) => /* @__PURE__ */ jsx(
276
- "div",
277
- {
278
- className: "flex items-center justify-center border-r border-border/40 py-2 last:border-r-0",
279
- children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: d })
280
- },
281
- d
282
- )) }),
283
- grid.map((week, wi) => /* @__PURE__ */ jsx(
284
- "div",
285
- {
286
- className: "grid grid-cols-7 border-b border-border last:border-b-0",
287
- children: week.map((day, di) => {
288
- const iso = day ? toIso(day) : null;
289
- const dayApts = iso ? appointments.filter((a) => a.date === iso) : [];
290
- const isToday = iso === today;
291
- return /* @__PURE__ */ jsx(
292
- "div",
293
- {
294
- className: `min-h-[80px] border-r border-border/40 p-1 last:border-r-0 ${!day ? "bg-muted/20" : ""} ${isToday ? "bg-primary/5" : ""}`,
295
- children: day && /* @__PURE__ */ jsxs(Fragment, { children: [
296
- /* @__PURE__ */ jsx(
297
- "div",
298
- {
299
- className: `mb-1 flex h-6 w-6 items-center justify-center text-xs font-semibold ${isToday ? "bg-primary text-primary-foreground" : "text-foreground"}`,
300
- children: day.getDate()
301
- }
302
- ),
303
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
304
- dayApts.slice(0, 2).map((apt) => /* @__PURE__ */ jsxs(
305
- Button,
306
- {
307
- type: "button",
308
- variant: "ghost",
309
- onClick: () => onSelectAppointment == null ? void 0 : onSelectAppointment(apt),
310
- 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]}`,
311
- children: [
312
- apt.timeStart,
313
- " ",
314
- apt.clientName
315
- ]
316
- },
317
- apt.id
318
- )),
319
- dayApts.length > 2 && /* @__PURE__ */ jsxs("p", { className: "px-1 text-[10px] text-muted-foreground", children: [
320
- "+",
321
- dayApts.length - 2,
322
- " more"
323
- ] })
324
- ] })
325
- ] })
326
- },
327
- di
328
- );
329
- })
330
- },
331
- wi
332
- ))
333
- ] });
334
- }
335
- function AppointmentCalendarView({
336
- appointments,
337
- today,
338
- periodLabel,
339
- weekDays,
340
- hours = DEFAULT_HOURS,
341
- viewDate,
342
- dayViewDate,
343
- defaultView = "week",
344
- onPrev,
345
- onNext,
346
- onToday,
347
- onViewChange,
348
- onSelectAppointment,
349
- toolbarActions
350
- }) {
351
- var _a;
352
- const effectiveViewDate = (_a = viewDate != null ? viewDate : dayViewDate) != null ? _a : today;
353
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col border border-border bg-card", children: [
354
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4 px-4 py-3", children: [
355
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
356
- /* @__PURE__ */ jsx(
357
- Button,
358
- {
359
- variant: "outline",
360
- size: "sm",
361
- className: "gap-1",
362
- onClick: onPrev,
363
- children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" })
364
- }
365
- ),
366
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: periodLabel }),
367
- /* @__PURE__ */ jsx(
368
- Button,
369
- {
370
- variant: "outline",
371
- size: "sm",
372
- className: "gap-1",
373
- onClick: onNext,
374
- children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" })
375
- }
376
- ),
377
- /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: onToday, children: "Today" })
378
- ] }),
379
- toolbarActions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: toolbarActions })
380
- ] }),
381
- /* @__PURE__ */ jsx(Separator, {}),
382
- /* @__PURE__ */ jsxs(
383
- Tabs,
384
- {
385
- defaultValue: defaultView,
386
- onValueChange: (v) => onViewChange == null ? void 0 : onViewChange(v),
387
- className: "flex flex-col",
388
- children: [
389
- /* @__PURE__ */ jsx("div", { className: "px-4 pt-3", children: /* @__PURE__ */ jsxs(TabsList, { children: [
390
- /* @__PURE__ */ jsx(TabsTrigger, { value: "day", children: "Day" }),
391
- /* @__PURE__ */ jsx(TabsTrigger, { value: "week", children: "Week" }),
392
- /* @__PURE__ */ jsx(TabsTrigger, { value: "month", children: "Month" })
393
- ] }) }),
394
- /* @__PURE__ */ jsx(TabsContent, { value: "day", className: "mt-0 max-h-[75vh] overflow-y-auto", children: /* @__PURE__ */ jsx(
395
- DayView,
396
- {
397
- appointments,
398
- date: effectiveViewDate,
399
- today,
400
- hours,
401
- onSelectAppointment
402
- }
403
- ) }),
404
- /* @__PURE__ */ jsx(TabsContent, { value: "week", className: "mt-0 max-h-[75vh] overflow-y-auto", children: /* @__PURE__ */ jsx(
405
- WeekView,
406
- {
407
- appointments,
408
- weekDays,
409
- today,
410
- hours,
411
- onSelectAppointment
412
- }
413
- ) }),
414
- /* @__PURE__ */ jsx(
415
- TabsContent,
416
- {
417
- value: "month",
418
- className: "mt-0 max-h-[75vh] overflow-y-auto",
419
- children: /* @__PURE__ */ jsx(
420
- MonthView,
421
- {
422
- appointments,
423
- viewDate: effectiveViewDate,
424
- today,
425
- onSelectAppointment
426
- }
427
- )
428
- }
429
- )
430
- ]
431
- }
432
- )
433
- ] });
434
- }
435
-
436
- export {
437
- AppointmentCalendarView
438
- };