braid-ui 1.0.11 → 1.0.14

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.
package/dist/index.cjs CHANGED
@@ -5810,14 +5810,16 @@ function DatePicker({
5810
5810
  buttonClassName,
5811
5811
  calendarClassName,
5812
5812
  align = "start",
5813
- disabledDates
5813
+ disabledDates,
5814
+ label,
5815
+ wrapperClassName
5814
5816
  }) {
5815
5817
  const [open, setOpen] = React15__namespace.useState(false);
5816
5818
  const handleSelect = (selectedDate) => {
5817
5819
  onDateChange?.(selectedDate);
5818
5820
  setOpen(false);
5819
5821
  };
5820
- return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
5822
+ const picker = /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
5821
5823
  /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
5822
5824
  Button,
5823
5825
  {
@@ -5846,6 +5848,13 @@ function DatePicker({
5846
5848
  }
5847
5849
  ) })
5848
5850
  ] });
5851
+ if (label) {
5852
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2", wrapperClassName), children: [
5853
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: label }),
5854
+ picker
5855
+ ] });
5856
+ }
5857
+ return picker;
5849
5858
  }
5850
5859
  function DataTable({
5851
5860
  columns: columns2,
@@ -6097,30 +6106,26 @@ var StatementView = ({
6097
6106
  onChange: (e) => onAccountNumberChange(e.target.value)
6098
6107
  }
6099
6108
  ),
6100
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
6101
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Start Date" }),
6102
- /* @__PURE__ */ jsxRuntime.jsx(
6103
- DatePicker,
6104
- {
6105
- date: startDate,
6106
- onDateChange: onStartDateChange,
6107
- placeholder: "Select start date",
6108
- buttonClassName: "w-full"
6109
- }
6110
- )
6111
- ] }),
6112
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
6113
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "End Date" }),
6114
- /* @__PURE__ */ jsxRuntime.jsx(
6115
- DatePicker,
6116
- {
6117
- date: endDate,
6118
- onDateChange: onEndDateChange,
6119
- placeholder: "Select end date",
6120
- buttonClassName: "w-full"
6121
- }
6122
- )
6123
- ] })
6109
+ /* @__PURE__ */ jsxRuntime.jsx(
6110
+ DatePicker,
6111
+ {
6112
+ label: "Start Date",
6113
+ date: startDate,
6114
+ onDateChange: onStartDateChange,
6115
+ placeholder: "Select start date",
6116
+ buttonClassName: "w-full"
6117
+ }
6118
+ ),
6119
+ /* @__PURE__ */ jsxRuntime.jsx(
6120
+ DatePicker,
6121
+ {
6122
+ label: "End Date",
6123
+ date: endDate,
6124
+ onDateChange: onEndDateChange,
6125
+ placeholder: "Select end date",
6126
+ buttonClassName: "w-full"
6127
+ }
6128
+ )
6124
6129
  ] }),
6125
6130
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(
6126
6131
  Button,
@@ -11108,6 +11113,65 @@ var NotFound = () => {
11108
11113
  ] }) });
11109
11114
  };
11110
11115
  var NotFound_default = NotFound;
11116
+
11117
+ // src/lib/utils/csv-utils.ts
11118
+ function escapeCsvValue(value) {
11119
+ const stringValue = String(value);
11120
+ if (stringValue.includes(",") || stringValue.includes('"') || stringValue.includes("\n")) {
11121
+ return `"${stringValue.replace(/"/g, '""')}"`;
11122
+ }
11123
+ return stringValue;
11124
+ }
11125
+ function generateStatementCSV(header, transactions) {
11126
+ const lines = [];
11127
+ lines.push("Statement Information");
11128
+ if (header.account) {
11129
+ lines.push(`Account,${escapeCsvValue(header.account)}`);
11130
+ }
11131
+ if (header.productId) {
11132
+ lines.push(`Product ID,${escapeCsvValue(header.productId)}`);
11133
+ }
11134
+ if (header.programId) {
11135
+ lines.push(`Program ID,${escapeCsvValue(header.programId)}`);
11136
+ }
11137
+ if (header.startDate) {
11138
+ lines.push(`Start Date,${escapeCsvValue(header.startDate)}`);
11139
+ }
11140
+ if (header.endDate) {
11141
+ lines.push(`End Date,${escapeCsvValue(header.endDate)}`);
11142
+ }
11143
+ if (header.startingBalance) {
11144
+ lines.push(`Starting Balance,${escapeCsvValue(header.startingBalance)}`);
11145
+ }
11146
+ if (header.endingBalance) {
11147
+ lines.push(`Ending Balance,${escapeCsvValue(header.endingBalance)}`);
11148
+ }
11149
+ lines.push("");
11150
+ lines.push("Transaction Summary");
11151
+ lines.push("Transaction Type,Direction,Amount,Count");
11152
+ transactions.forEach((transaction) => {
11153
+ const row = [
11154
+ escapeCsvValue(transaction.transactionType),
11155
+ escapeCsvValue(transaction.direction),
11156
+ escapeCsvValue(transaction.amount),
11157
+ escapeCsvValue(transaction.count)
11158
+ ].join(",");
11159
+ lines.push(row);
11160
+ });
11161
+ return lines.join("\n");
11162
+ }
11163
+ function downloadCSV(content, filename) {
11164
+ const blob = new Blob([content], { type: "text/csv;charset=utf-8;" });
11165
+ const url = URL.createObjectURL(blob);
11166
+ const link = document.createElement("a");
11167
+ link.href = url;
11168
+ link.download = filename;
11169
+ link.style.display = "none";
11170
+ document.body.appendChild(link);
11171
+ link.click();
11172
+ document.body.removeChild(link);
11173
+ URL.revokeObjectURL(url);
11174
+ }
11111
11175
  function Statement() {
11112
11176
  const [statementType, setStatementType] = React15.useState("root");
11113
11177
  const [selectedProgram, setSelectedProgram] = React15.useState("");
@@ -11230,7 +11294,38 @@ function Statement() {
11230
11294
  return false;
11231
11295
  };
11232
11296
  const handleDownloadCSV = () => {
11233
- console.log("Downloading CSV...");
11297
+ if (!statementHeader || !statementTransactions.length) {
11298
+ toast({
11299
+ title: "No statement data",
11300
+ description: "Please generate a statement before downloading",
11301
+ variant: "destructive"
11302
+ });
11303
+ return;
11304
+ }
11305
+ try {
11306
+ const csvContent = generateStatementCSV(statementHeader, statementTransactions);
11307
+ const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
11308
+ let filenamePart = statementType;
11309
+ if (statementType === "program" && selectedProgram) {
11310
+ filenamePart = `program_${selectedProgram}`;
11311
+ } else if (statementType === "product" && selectedProduct) {
11312
+ filenamePart = `product_${selectedProduct}`;
11313
+ } else if (statementType === "account" && accountNumber) {
11314
+ filenamePart = `account_${accountNumber}`;
11315
+ }
11316
+ const filename = `statement_${filenamePart}_${dateStr}.csv`;
11317
+ downloadCSV(csvContent, filename);
11318
+ toast({
11319
+ title: "Download started",
11320
+ description: "Your statement CSV is being downloaded"
11321
+ });
11322
+ } catch (error) {
11323
+ toast({
11324
+ title: "Download failed",
11325
+ description: error instanceof Error ? error.message : "Failed to download CSV",
11326
+ variant: "destructive"
11327
+ });
11328
+ }
11234
11329
  };
11235
11330
  const handlePrintPDF = () => {
11236
11331
  console.log("Printing PDF...");