@juv/codego-react-ui 3.5.21 → 3.6.1

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.d.ts CHANGED
@@ -3,6 +3,7 @@ import * as React from 'react';
3
3
  import React__default from 'react';
4
4
  import { AxiosRequestConfig } from 'axios';
5
5
  import { UseBoundStore, StoreApi } from 'zustand';
6
+ import CryptoJS from 'crypto-js';
6
7
 
7
8
  type AuthView = "login" | "register" | "resetPassword";
8
9
  interface AuthField {
@@ -810,26 +811,6 @@ interface BulletinServerPaginationProp {
810
811
  currentPage: number;
811
812
  goToPage: (page: number) => void;
812
813
  }
813
- interface UseServerBulletinOptions {
814
- url: string;
815
- params?: Record<string, string | number>;
816
- encrypt?: boolean;
817
- key?: string;
818
- decryptPayloadLog?: boolean;
819
- /** Map raw API row → BulletinItem */
820
- transform?: (row: any) => BulletinItem;
821
- }
822
- interface UseServerBulletinReturn {
823
- items: BulletinItem[];
824
- currentPage: number;
825
- pagination: ServerPagination | null;
826
- serverPagination: BulletinServerPaginationProp | null;
827
- loading: boolean;
828
- error: string | null;
829
- goToPage: (page: number) => void;
830
- reload: () => void;
831
- }
832
- declare function useServerBulletin({ url, params, encrypt, key, decryptPayloadLog, transform, }: UseServerBulletinOptions): UseServerBulletinReturn;
833
814
  interface BulletinPreviewProps {
834
815
  item: BulletinItem;
835
816
  onClose: () => void;
@@ -838,8 +819,12 @@ interface BulletinPreviewProps {
838
819
  onView?: (item: BulletinItem) => void;
839
820
  /** Custom actions to add to the preview header */
840
821
  customActions?: BulletinAction[];
822
+ /** Extra React elements rendered in the preview modal header's left area */
823
+ headerAction?: React.ReactNode;
824
+ /** Extra React elements rendered in the preview modal footer's action area */
825
+ footerAction?: React.ReactNode;
841
826
  }
842
- declare function BulletinPreview({ item, onClose, onEdit, onDelete, onView, customActions }: BulletinPreviewProps): React.ReactPortal;
827
+ declare function BulletinPreview({ item, onClose, onEdit, onDelete, onView, customActions, headerAction, footerAction }: BulletinPreviewProps): React.ReactPortal;
843
828
  interface BulletinEditField {
844
829
  key: keyof BulletinItem | string;
845
830
  label: string;
@@ -898,10 +883,16 @@ interface BulletinBoardProps {
898
883
  serverPagination?: BulletinServerPaginationProp | null;
899
884
  /** Fired when a post card is clicked (ignored when preview=true). */
900
885
  onItemClick?: (item: BulletinItem) => void;
886
+ /** Extra React elements rendered below the board content (above pagination). */
887
+ footerAction?: React.ReactNode;
888
+ /** Extra React elements rendered in the preview modal header's left area. */
889
+ headerPreviewAction?: React.ReactNode;
890
+ /** Extra React elements rendered in the preview modal footer's action area. */
891
+ footerPreviewAction?: (item: BulletinItem) => React.ReactNode;
901
892
  /** Additional CSS classes on the outer wrapper. */
902
893
  className?: string;
903
894
  }
904
- declare function BulletinBoard({ items, layout, columns, variant, searchable, filterable, categories: categoriesProp, title, headerAction, showHeader, emptyMessage, loading, loadingCount, onItemClick, onView, onEdit, onDelete, preview, editBaseUrl, editMethod, editIdKey, editFields, deleteBaseUrl, deleteIdKey, serverPagination, className, }: BulletinBoardProps): react_jsx_runtime.JSX.Element;
895
+ declare function BulletinBoard({ items, layout, columns, variant, searchable, filterable, categories: categoriesProp, title, headerAction, showHeader, emptyMessage, loading, loadingCount, onItemClick, onView, onEdit, onDelete, preview, editBaseUrl, editMethod, editIdKey, editFields, deleteBaseUrl, deleteIdKey, serverPagination, footerAction, headerPreviewAction, footerPreviewAction, className, }: BulletinBoardProps): react_jsx_runtime.JSX.Element;
905
896
 
906
897
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
907
898
  variant?: "primary" | "secondary" | "outline" | "ghost" | "link" | "danger" | "success" | "destructive";
@@ -978,6 +969,8 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
978
969
  confirmBeforeClickModalTitle?: string;
979
970
  confirmBeforeClickModalContent?: React.ReactNode;
980
971
  confirmBeforeClickFooterAction?: React.ReactNode;
972
+ onConfirm?: () => void;
973
+ onCancel?: () => void;
981
974
  href?: string;
982
975
  target?: "_blank" | "_self";
983
976
  as?: "button" | "a" | "div";
@@ -2561,4 +2554,29 @@ type StoreWrapper<T extends object> = {
2561
2554
  */
2562
2555
  declare function createStore<T extends object>(initialValue: T, sessionName: string, expireInterval?: number): StoreWrapper<T>;
2563
2556
 
2564
- export { Accordion, type AccordionItem, type AccordionProps, type AccordionVariant, type ActionField, type ActionFieldType, type AuthField, type AuthVariant, type AuthView, Authentication, type AuthenticationProps, AvatarStack, type AvatarStackProps, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, type BulletinAction, BulletinBoard, type BulletinBoardProps, type BulletinColumns, type BulletinEditField, type BulletinItem, type BulletinLayout, BulletinPreview, type BulletinPreviewProps, type BulletinPriority, type BulletinServerPaginationProp, type BulletinVariant, Button, type ButtonProps, COLOR_PALETTE, Calendar, CalendarDateRangePicker, type CalendarDateRangePickerProps, type CalendarDateRangeVariant, type CalendarEvent, type CalendarProps, type CalendarView, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChartDataPoint, ChartWidget, type ChartWidgetProps, Checkbox, type CheckboxProps, CircularProgress, type CircularProgressProps, type ClusterVariant, CodegoApiProvider, ColorPicker, type ColorPickerProps, type Column, Combobox, type ComboboxOption, type ComboboxProps, type CommandItem, CommandPalette, type CommandPaletteProps, ComposableWidget, type ComposableWidgetProps, type ConfirmVariant, ContextMenu, type ContextMenuItem, type ContextMenuProps, DataGrid, type DataGridColumn, type DataGridProps, DatePickerPopup, type DateRange, DateRangePicker, type DateRangePickerProps, type DefaultActionsConfig, DocsLayout, Drawer, type DrawerProps, type DrawerSide, Dropdown, DropdownItem, DropdownLabel, type DropdownProps, DropdownSeparator, EVENT_COLORS, type FileTypeValidation, FileUpload, type FileUploadProps, type FlexAlign, type FlexDirection, type FlexGap, FlexItem, type FlexItemProps, type FlexJustify, FlexLayout, type FlexLayoutProps, type FlexWrap, type FlyToOptions, type FormField, type FormFieldType, type GridAlign, type GridCols, type GridGap, GridItem, type GridItemProps, GridLayout, type GridLayoutProps, GroupNavigation, type GroupNavigationProps, type ImageEditorMode, type ImageEditorOptions, Input, type InputProps, KanbanBoard, type KanbanBoardProps, type KanbanCard, type KanbanColumn, Label, LeafletMap, type LeafletMapProps, LeftSidebar, type LeftSidebarProps, type MapLibreClusterVariant, MapLibreMap, type MapLibreMarker, type MapLibreProps, type MapLibreRoute, type MapLibreRouteType, type MapLibreStyle, type MapMarker, type MapRoute, type MarkerColor, type MetricItem, MetricRow, type MetricRowProps, Modal, ModalConfirmation, type ModalConfirmationProps, type ModalProps, ModalUnchange, type ModalUnchangeProps, ModalWithForms, type ModalWithFormsProps, type NavGroup, type NavItem, Navigation, type NavigationProps, NotificationBanner, type NotificationBannerProps, type NotificationItem, NotificationPanel, type NotificationPanelProps, type NotificationVariant, OtpInput, type OtpInputProps, Pagination, type PaginationProps, Panel, type PanelProps, PanelSettings, type PanelSettingsProps, type PanelSettingsTab, PanelSidebarGroup, PanelSidebarItem, Popover, type PopoverPlacement, type PopoverProps, Progress, type ProgressProps, type ProgressSize, type ProgressVariant, type PropRow, PropsTable, RadioGroup, type RadioGroupProps, type RadioOption, type RadioSize, type RadioVariant, RangeSlider, type RangeSliderProps, Repeater, type RepeaterProps, type RequestConfig, ResizablePanels, type ResizablePanelsProps, RichTextEditor, type RichTextEditorProps, RightSidebar, type RightSidebarProps, type RouteType, ScrollArea, type ScrollAreaProps, Section, SectionBlock, type SectionProps, type SectionVariant, Select, type SelectOption, type SelectProps, type SemanticColor, type ServerDataGridProp, type ServerPagination, type ServerPaginationLink, type ServerPaginationProp, type ServerTableResponse, Skeleton, Slider, type SliderProps, type SortDir, StatCard, type StatCardProps, type StatTrend, StatsWidget, type StatsWidgetProps, type Step, type StepStatus, Stepper, type StepperProps, type TabItem, type TabSize, type TabVariant, Table, TableOfContents, type TableProps, TableWidget, type TableWidgetProps, Tabs, type TabsProps, TagInput, type TagInputProps, Textarea, type TextareaProps, type ThemeColors, ThemeProvider, type ThemeSettings, Timeline, type TimelineItem, type TimelineProps, type TimelineVariant, type ToastItem, type ToastPosition, ToastProvider, type ToastProviderProps, type ToastVariant, type TocItem, TocProvider, ToggleSwitch, type ToggleSwitchProps, Tooltip, type TooltipProps, Topbar, type TopbarProps, type TreeNode, TreeView, type TreeViewProps, type TrendDir, type UseServerBulletinOptions, type UseServerBulletinReturn, type UseServerDataGridOptions, type UseServerDataGridReturn, type UseServerTableOptions, type UseServerTableReturn, Widget, type WidgetProps, Wizard, type WizardActionProps, type WizardLayout, type WizardProps, type WizardSize, type WizardStep, type WizardVariant, api, createStore, useServerBulletin, useServerDataGrid, useServerTable, useTheme, useToast, useToc };
2557
+ type LaravelEncryptedPayload = {
2558
+ iv: string;
2559
+ value: string;
2560
+ mac: string;
2561
+ tag?: string;
2562
+ };
2563
+ declare function getLaravelSecretKey(): string;
2564
+ declare function parseLaravelKey(secretKey: string): CryptoJS.lib.WordArray;
2565
+ declare function parseLaravelEncryptedPayload(payload: string): LaravelEncryptedPayload;
2566
+ declare function decryptLaravelPayload<T>(payload: string, secretKey?: string): T;
2567
+
2568
+ /**
2569
+ * Decrypt a Laravel-encrypted API response.
2570
+ *
2571
+ * Accepts either:
2572
+ * - a raw encrypted string (the full response body)
2573
+ * - an object with an `data` key holding the encrypted string
2574
+ *
2575
+ * @param response Raw encrypted string or `{ data: string }` object
2576
+ * @param key Optional Laravel APP_KEY (base64:… or raw). Falls back to VITE_LARAVEL_KEY.
2577
+ */
2578
+ declare function decryptResponse<T = unknown>(response: string | {
2579
+ data: string;
2580
+ }, key?: string): T;
2581
+
2582
+ export { Accordion, type AccordionItem, type AccordionProps, type AccordionVariant, type ActionField, type ActionFieldType, type AuthField, type AuthVariant, type AuthView, Authentication, type AuthenticationProps, AvatarStack, type AvatarStackProps, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, type BulletinAction, BulletinBoard, type BulletinBoardProps, type BulletinColumns, type BulletinEditField, type BulletinItem, type BulletinLayout, BulletinPreview, type BulletinPreviewProps, type BulletinPriority, type BulletinServerPaginationProp, type BulletinVariant, Button, type ButtonProps, COLOR_PALETTE, Calendar, CalendarDateRangePicker, type CalendarDateRangePickerProps, type CalendarDateRangeVariant, type CalendarEvent, type CalendarProps, type CalendarView, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChartDataPoint, ChartWidget, type ChartWidgetProps, Checkbox, type CheckboxProps, CircularProgress, type CircularProgressProps, type ClusterVariant, CodegoApiProvider, ColorPicker, type ColorPickerProps, type Column, Combobox, type ComboboxOption, type ComboboxProps, type CommandItem, CommandPalette, type CommandPaletteProps, ComposableWidget, type ComposableWidgetProps, type ConfirmVariant, ContextMenu, type ContextMenuItem, type ContextMenuProps, DataGrid, type DataGridColumn, type DataGridProps, DatePickerPopup, type DateRange, DateRangePicker, type DateRangePickerProps, type DefaultActionsConfig, DocsLayout, Drawer, type DrawerProps, type DrawerSide, Dropdown, DropdownItem, DropdownLabel, type DropdownProps, DropdownSeparator, EVENT_COLORS, type FileTypeValidation, FileUpload, type FileUploadProps, type FlexAlign, type FlexDirection, type FlexGap, FlexItem, type FlexItemProps, type FlexJustify, FlexLayout, type FlexLayoutProps, type FlexWrap, type FlyToOptions, type FormField, type FormFieldType, type GridAlign, type GridCols, type GridGap, GridItem, type GridItemProps, GridLayout, type GridLayoutProps, GroupNavigation, type GroupNavigationProps, type ImageEditorMode, type ImageEditorOptions, Input, type InputProps, KanbanBoard, type KanbanBoardProps, type KanbanCard, type KanbanColumn, Label, type LaravelEncryptedPayload, LeafletMap, type LeafletMapProps, LeftSidebar, type LeftSidebarProps, type MapLibreClusterVariant, MapLibreMap, type MapLibreMarker, type MapLibreProps, type MapLibreRoute, type MapLibreRouteType, type MapLibreStyle, type MapMarker, type MapRoute, type MarkerColor, type MetricItem, MetricRow, type MetricRowProps, Modal, ModalConfirmation, type ModalConfirmationProps, type ModalProps, ModalUnchange, type ModalUnchangeProps, ModalWithForms, type ModalWithFormsProps, type NavGroup, type NavItem, Navigation, type NavigationProps, NotificationBanner, type NotificationBannerProps, type NotificationItem, NotificationPanel, type NotificationPanelProps, type NotificationVariant, OtpInput, type OtpInputProps, Pagination, type PaginationProps, Panel, type PanelProps, PanelSettings, type PanelSettingsProps, type PanelSettingsTab, PanelSidebarGroup, PanelSidebarItem, Popover, type PopoverPlacement, type PopoverProps, Progress, type ProgressProps, type ProgressSize, type ProgressVariant, type PropRow, PropsTable, RadioGroup, type RadioGroupProps, type RadioOption, type RadioSize, type RadioVariant, RangeSlider, type RangeSliderProps, Repeater, type RepeaterProps, type RequestConfig, ResizablePanels, type ResizablePanelsProps, RichTextEditor, type RichTextEditorProps, RightSidebar, type RightSidebarProps, type RouteType, ScrollArea, type ScrollAreaProps, Section, SectionBlock, type SectionProps, type SectionVariant, Select, type SelectOption, type SelectProps, type SemanticColor, type ServerDataGridProp, type ServerPagination, type ServerPaginationLink, type ServerPaginationProp, type ServerTableResponse, Skeleton, Slider, type SliderProps, type SortDir, StatCard, type StatCardProps, type StatTrend, StatsWidget, type StatsWidgetProps, type Step, type StepStatus, Stepper, type StepperProps, type TabItem, type TabSize, type TabVariant, Table, TableOfContents, type TableProps, TableWidget, type TableWidgetProps, Tabs, type TabsProps, TagInput, type TagInputProps, Textarea, type TextareaProps, type ThemeColors, ThemeProvider, type ThemeSettings, Timeline, type TimelineItem, type TimelineProps, type TimelineVariant, type ToastItem, type ToastPosition, ToastProvider, type ToastProviderProps, type ToastVariant, type TocItem, TocProvider, ToggleSwitch, type ToggleSwitchProps, Tooltip, type TooltipProps, Topbar, type TopbarProps, type TreeNode, TreeView, type TreeViewProps, type TrendDir, type UseServerDataGridOptions, type UseServerDataGridReturn, type UseServerTableOptions, type UseServerTableReturn, Widget, type WidgetProps, Wizard, type WizardActionProps, type WizardLayout, type WizardProps, type WizardSize, type WizardStep, type WizardVariant, api, createStore, decryptLaravelPayload, decryptResponse, getLaravelSecretKey, parseLaravelEncryptedPayload, parseLaravelKey, useServerDataGrid, useServerTable, useTheme, useToast, useToc };
@@ -53730,7 +53730,11 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
53730
53730
  Wizard: () => Wizard,
53731
53731
  api: () => api,
53732
53732
  createStore: () => createStore2,
53733
- useServerBulletin: () => useServerBulletin,
53733
+ decryptLaravelPayload: () => decryptLaravelPayload,
53734
+ decryptResponse: () => decryptResponse,
53735
+ getLaravelSecretKey: () => getLaravelSecretKey,
53736
+ parseLaravelEncryptedPayload: () => parseLaravelEncryptedPayload,
53737
+ parseLaravelKey: () => parseLaravelKey,
53734
53738
  useServerDataGrid: () => useServerDataGrid,
53735
53739
  useServerTable: () => useServerTable,
53736
53740
  useTheme: () => useTheme,
@@ -60730,6 +60734,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
60730
60734
 
60731
60735
  // src/components/ui/button.tsx
60732
60736
  var React = __toESM(require_react(), 1);
60737
+ var ReactDOM2 = __toESM(require_react_dom(), 1);
60733
60738
  var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
60734
60739
  var Button = React.forwardRef(
60735
60740
  ({
@@ -60808,6 +60813,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
60808
60813
  confirmBeforeClickModalTitle,
60809
60814
  confirmBeforeClickModalContent,
60810
60815
  confirmBeforeClickFooterAction,
60816
+ onConfirm,
60817
+ onCancel,
60811
60818
  href,
60812
60819
  target,
60813
60820
  as = "button",
@@ -60903,11 +60910,13 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
60903
60910
  };
60904
60911
  function handleConfirmProceed() {
60905
60912
  setConfirmOpen(false);
60913
+ onConfirm?.();
60906
60914
  onClick?.(pendingEvent.current ?? void 0);
60907
60915
  pendingEvent.current = null;
60908
60916
  }
60909
60917
  function handleConfirmCancel() {
60910
60918
  setConfirmOpen(false);
60919
+ onCancel?.();
60911
60920
  pendingEvent.current = null;
60912
60921
  }
60913
60922
  const buttonContent = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
@@ -60935,46 +60944,49 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
60935
60944
  tabIndex,
60936
60945
  "data-testid": testID
60937
60946
  };
60938
- const confirmModal = confirmBeforeClick && confirmOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
60939
- "div",
60940
- {
60941
- className: "fixed inset-0 z-50 flex items-center justify-center",
60942
- onClick: handleConfirmCancel,
60943
- children: [
60944
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm" }),
60945
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
60946
- "div",
60947
- {
60948
- className: "relative z-10 w-full max-w-sm rounded-2xl border border-border bg-card p-6 shadow-2xl",
60949
- onClick: (e) => e.stopPropagation(),
60950
- children: [
60951
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-base font-semibold text-foreground mb-2", children: confirmBeforeClickModalTitle ?? "Are you sure?" }),
60952
- confirmBeforeClickModalContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-sm text-muted-foreground mb-5", children: confirmBeforeClickModalContent }),
60953
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex justify-end gap-2 mt-4", children: confirmBeforeClickFooterAction ?? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
60954
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
60955
- "button",
60956
- {
60957
- type: "button",
60958
- onClick: handleConfirmCancel,
60959
- className: "inline-flex items-center justify-center rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-accent transition-colors",
60960
- children: "Cancel"
60961
- }
60962
- ),
60963
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
60964
- "button",
60965
- {
60966
- type: "button",
60967
- onClick: handleConfirmProceed,
60968
- className: "inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary-hover transition-colors",
60969
- children: "Proceed"
60970
- }
60971
- )
60972
- ] }) })
60973
- ]
60974
- }
60975
- )
60976
- ]
60977
- }
60947
+ const confirmModal = confirmBeforeClick && confirmOpen ? ReactDOM2.createPortal(
60948
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
60949
+ "div",
60950
+ {
60951
+ className: "fixed inset-0 z-[9999] flex items-center justify-center",
60952
+ onClick: handleConfirmCancel,
60953
+ children: [
60954
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm" }),
60955
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
60956
+ "div",
60957
+ {
60958
+ className: "relative z-10 w-full max-w-sm rounded-2xl border border-border bg-card p-6 shadow-2xl",
60959
+ onClick: (e) => e.stopPropagation(),
60960
+ children: [
60961
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-base font-semibold text-foreground mb-2", children: confirmBeforeClickModalTitle ?? "Are you sure?" }),
60962
+ confirmBeforeClickModalContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-sm text-muted-foreground mb-5", children: confirmBeforeClickModalContent }),
60963
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex justify-end gap-2 mt-4", children: confirmBeforeClickFooterAction ?? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
60964
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
60965
+ "button",
60966
+ {
60967
+ type: "button",
60968
+ onClick: handleConfirmCancel,
60969
+ className: "inline-flex items-center justify-center rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-accent transition-colors",
60970
+ children: "Cancel"
60971
+ }
60972
+ ),
60973
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
60974
+ "button",
60975
+ {
60976
+ type: "button",
60977
+ onClick: handleConfirmProceed,
60978
+ className: "inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary-hover transition-colors",
60979
+ children: "Proceed"
60980
+ }
60981
+ )
60982
+ ] }) })
60983
+ ]
60984
+ }
60985
+ )
60986
+ ]
60987
+ }
60988
+ ),
60989
+ document.body
60978
60990
  ) : null;
60979
60991
  if (Element2 === "a") {
60980
60992
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
@@ -64733,66 +64745,6 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
64733
64745
  // src/components/ui/bulletin-board.tsx
64734
64746
  var React8 = __toESM(require_react(), 1);
64735
64747
  var import_react_dom = __toESM(require_react_dom(), 1);
64736
-
64737
- // src/components/tools/decryptPayload.ts
64738
- var import_crypto_js = __toESM(require_crypto_js(), 1);
64739
- function getLaravelSecretKey() {
64740
- const viteKey = (() => {
64741
- try {
64742
- return new Function("return import.meta.env")();
64743
- } catch {
64744
- return void 0;
64745
- }
64746
- })()?.VITE_LARAVEL_KEY;
64747
- const legacyKey = globalThis?.process?.env?.REACT_APP_LARAVEL_KEY;
64748
- const windowKey = globalThis?.__LARAVEL_KEY__;
64749
- const key = viteKey || legacyKey || windowKey;
64750
- if (!key) {
64751
- throw new Error("Missing Laravel decryption key. Set VITE_LARAVEL_KEY in your .env or inject window.__LARAVEL_KEY__ via Blade.");
64752
- }
64753
- return key;
64754
- }
64755
- function parseLaravelKey(secretKey) {
64756
- if (secretKey.startsWith("base64:")) {
64757
- return import_crypto_js.default.enc.Base64.parse(secretKey.slice("base64:".length));
64758
- }
64759
- return import_crypto_js.default.enc.Utf8.parse(secretKey);
64760
- }
64761
- function parseLaravelEncryptedPayload(payload) {
64762
- let jsonStr = payload;
64763
- try {
64764
- jsonStr = atob(payload);
64765
- } catch {
64766
- }
64767
- return JSON.parse(jsonStr);
64768
- }
64769
- function decryptLaravelPayload(payload, secretKey) {
64770
- const resolvedKey = secretKey ?? getLaravelSecretKey();
64771
- const parsed = parseLaravelEncryptedPayload(payload);
64772
- if (parsed.tag) {
64773
- throw new Error("Unsupported Laravel cipher (AEAD tag present). Expected AES-*-CBC payload.");
64774
- }
64775
- const key = parseLaravelKey(resolvedKey);
64776
- const expectedMac = import_crypto_js.default.HmacSHA256(parsed.iv + parsed.value, key).toString(import_crypto_js.default.enc.Hex);
64777
- if (expectedMac !== parsed.mac) {
64778
- throw new Error("Invalid payload MAC (wrong key or tampered payload).");
64779
- }
64780
- const iv = import_crypto_js.default.enc.Base64.parse(parsed.iv);
64781
- const ciphertext = import_crypto_js.default.enc.Base64.parse(parsed.value);
64782
- const cipherParams = import_crypto_js.default.lib.CipherParams.create({ ciphertext });
64783
- const decrypted = import_crypto_js.default.AES.decrypt(cipherParams, key, {
64784
- iv,
64785
- mode: import_crypto_js.default.mode.CBC,
64786
- padding: import_crypto_js.default.pad.Pkcs7
64787
- });
64788
- const plaintext = decrypted.toString(import_crypto_js.default.enc.Utf8);
64789
- if (!plaintext) {
64790
- throw new Error("Decryption produced empty plaintext (wrong key/cipher).");
64791
- }
64792
- return JSON.parse(plaintext);
64793
- }
64794
-
64795
- // src/components/ui/bulletin-board.tsx
64796
64748
  var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
64797
64749
  var PRIORITY_CONFIG = {
64798
64750
  urgent: { label: "Urgent", icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CircleAlert, { className: "h-3 w-3" }), badge: "error" },
@@ -64822,82 +64774,13 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
64822
64774
  }
64823
64775
  return null;
64824
64776
  }
64825
- function useServerBulletin({
64826
- url: url2,
64827
- params,
64828
- encrypt,
64829
- key,
64830
- decryptPayloadLog,
64831
- transform
64832
- }) {
64833
- const [items, setItems] = React8.useState([]);
64834
- const [currentPage, setCurrentPage] = React8.useState(1);
64835
- const [pagination, setPagination] = React8.useState(null);
64836
- const [loading, setLoading] = React8.useState(false);
64837
- const [error, setError] = React8.useState(null);
64838
- const [tick, setTick] = React8.useState(0);
64839
- React8.useEffect(() => {
64840
- let cancelled = false;
64841
- setLoading(true);
64842
- setError(null);
64843
- axios_default.get(url2, { params: { ...params, page: currentPage } }).then(({ data: res }) => {
64844
- if (cancelled) return;
64845
- let payload;
64846
- try {
64847
- payload = encrypt ? decryptLaravelPayload(res, key) : res;
64848
- } catch (decryptErr) {
64849
- console.error("[useServerBulletin] decryption failed:", decryptErr?.message ?? decryptErr);
64850
- if (!cancelled) setError(decryptErr?.message ?? "Decryption failed");
64851
- return;
64852
- }
64853
- if (encrypt && decryptPayloadLog) console.log("[useServerBulletin] decrypted:", payload);
64854
- const rows = Array.isArray(payload) ? payload : payload.data ?? [];
64855
- setItems(transform ? rows.map(transform) : rows);
64856
- if (!Array.isArray(payload)) {
64857
- const rawTotal = payload.total;
64858
- const rawPerPage = payload.per_page;
64859
- const rawLastPage = payload.last_page;
64860
- const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
64861
- const pg = payload.pagination ?? {
64862
- first_page_url: payload.first_page_url ?? `${url2}?page=1`,
64863
- last_page_url: payload.last_page_url ?? `${url2}?page=${lastPage}`,
64864
- last_page: lastPage,
64865
- next_page_url: payload.next_page_url !== void 0 ? payload.next_page_url : currentPage < lastPage ? `${url2}?page=${currentPage + 1}` : null,
64866
- prev_page_url: payload.prev_page_url !== void 0 ? payload.prev_page_url : currentPage > 1 ? `${url2}?page=${currentPage - 1}` : null,
64867
- per_page: rawPerPage,
64868
- total: rawTotal,
64869
- links: payload.links ?? []
64870
- };
64871
- setPagination(pg);
64872
- }
64873
- }).catch((err) => {
64874
- if (cancelled) return;
64875
- setError(err?.response?.data?.message ?? err.message ?? "Request failed");
64876
- }).finally(() => {
64877
- if (!cancelled) setLoading(false);
64878
- });
64879
- return () => {
64880
- cancelled = true;
64881
- };
64882
- }, [url2, currentPage, tick, JSON.stringify(params), encrypt, decryptPayloadLog]);
64883
- return {
64884
- items,
64885
- currentPage,
64886
- pagination,
64887
- serverPagination: pagination ? { pagination, currentPage, goToPage: (p) => setCurrentPage(p) } : null,
64888
- loading,
64889
- error,
64890
- goToPage: (p) => setCurrentPage(p),
64891
- reload: () => setTick((t) => t + 1)
64892
- };
64893
- }
64894
- function BulletinPreview({ item, onClose, onEdit, onDelete, onView, customActions }) {
64777
+ function BulletinPreview({ item, onClose, onEdit, onDelete, onView, customActions, headerAction, footerAction }) {
64895
64778
  const priority = item.priority ? PRIORITY_CONFIG[item.priority] : null;
64896
64779
  return (0, import_react_dom.createPortal)(
64897
64780
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
64898
64781
  "div",
64899
64782
  {
64900
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
64783
+ className: "fixed inset-0 z-50 flex glass items-center justify-center p-4",
64901
64784
  style: { background: "rgba(0,0,0,0.55)" },
64902
64785
  onMouseDown: (e) => {
64903
64786
  if (e.target === e.currentTarget) onClose();
@@ -64910,7 +64793,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
64910
64793
  " Pinned"
64911
64794
  ] }),
64912
64795
  priority && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Badge, { variant: priority.badge, size: "sm", icon: priority.icon ?? void 0, children: priority.label }),
64913
- item.category && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Badge, { variant: "outline", size: "sm", children: item.category })
64796
+ item.category && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Badge, { variant: "outline", size: "sm", children: item.category }),
64797
+ headerAction
64914
64798
  ] }),
64915
64799
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
64916
64800
  onEdit && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
@@ -65009,6 +64893,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
65009
64893
  ] })
65010
64894
  ] }) }),
65011
64895
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2", children: [
64896
+ footerAction,
65012
64897
  onEdit && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
65013
64898
  "button",
65014
64899
  {
@@ -65403,6 +65288,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
65403
65288
  deleteBaseUrl,
65404
65289
  deleteIdKey = "id",
65405
65290
  serverPagination,
65291
+ footerAction,
65292
+ headerPreviewAction,
65293
+ footerPreviewAction,
65406
65294
  className
65407
65295
  }) {
65408
65296
  const [previewItem, setPreviewItem] = React8.useState(null);
@@ -65487,6 +65375,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
65487
65375
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Pin, { className: "h-8 w-8 opacity-20" }),
65488
65376
  emptyMessage
65489
65377
  ] }) : layout === "list" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-col gap-3", children: filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BulletinCard, { item, variant, layout: "list", onClick: handleCardClick }, item.id)) }) : layout === "masonry" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn("gap-4", COLS_CLASS[columns]), style: { display: "grid", gridTemplateRows: "masonry" }, children: filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BulletinCard, { item, variant, layout: "masonry", onClick: handleCardClick }, item.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn("grid gap-4", COLS_CLASS[columns]), children: filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BulletinCard, { item, variant, layout: "grid", onClick: handleCardClick }, item.id)) }),
65378
+ footerAction && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: footerAction }),
65490
65379
  serverPagination && (() => {
65491
65380
  const { pagination, currentPage: cp, goToPage } = serverPagination;
65492
65381
  const totalPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
@@ -65563,7 +65452,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
65563
65452
  setDeleteItem(item);
65564
65453
  } : onDelete ? (item) => {
65565
65454
  onDelete(item);
65566
- } : void 0
65455
+ } : void 0,
65456
+ footerAction: footerPreviewAction ? footerPreviewAction(previewItem) : void 0,
65457
+ headerAction: headerPreviewAction
65567
65458
  }
65568
65459
  ),
65569
65460
  editItem && editBaseUrl && editFields && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
@@ -67033,6 +66924,64 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
67033
66924
  var React29 = __toESM(require_react(), 1);
67034
66925
  var import_react_dom3 = __toESM(require_react_dom(), 1);
67035
66926
 
66927
+ // src/components/tools/decryptPayload.ts
66928
+ var import_crypto_js = __toESM(require_crypto_js(), 1);
66929
+ function getLaravelSecretKey() {
66930
+ const viteKey = (() => {
66931
+ try {
66932
+ return new Function("return import.meta.env")();
66933
+ } catch {
66934
+ return void 0;
66935
+ }
66936
+ })()?.VITE_LARAVEL_KEY;
66937
+ const legacyKey = globalThis?.process?.env?.REACT_APP_LARAVEL_KEY;
66938
+ const windowKey = globalThis?.__LARAVEL_KEY__;
66939
+ const key = viteKey || legacyKey || windowKey;
66940
+ if (!key) {
66941
+ throw new Error("Missing Laravel decryption key. Set VITE_LARAVEL_KEY in your .env or inject window.__LARAVEL_KEY__ via Blade.");
66942
+ }
66943
+ return key;
66944
+ }
66945
+ function parseLaravelKey(secretKey) {
66946
+ if (secretKey.startsWith("base64:")) {
66947
+ return import_crypto_js.default.enc.Base64.parse(secretKey.slice("base64:".length));
66948
+ }
66949
+ return import_crypto_js.default.enc.Utf8.parse(secretKey);
66950
+ }
66951
+ function parseLaravelEncryptedPayload(payload) {
66952
+ let jsonStr = payload;
66953
+ try {
66954
+ jsonStr = atob(payload);
66955
+ } catch {
66956
+ }
66957
+ return JSON.parse(jsonStr);
66958
+ }
66959
+ function decryptLaravelPayload(payload, secretKey) {
66960
+ const resolvedKey = secretKey ?? getLaravelSecretKey();
66961
+ const parsed = parseLaravelEncryptedPayload(payload);
66962
+ if (parsed.tag) {
66963
+ throw new Error("Unsupported Laravel cipher (AEAD tag present). Expected AES-*-CBC payload.");
66964
+ }
66965
+ const key = parseLaravelKey(resolvedKey);
66966
+ const expectedMac = import_crypto_js.default.HmacSHA256(parsed.iv + parsed.value, key).toString(import_crypto_js.default.enc.Hex);
66967
+ if (expectedMac !== parsed.mac) {
66968
+ throw new Error("Invalid payload MAC (wrong key or tampered payload).");
66969
+ }
66970
+ const iv = import_crypto_js.default.enc.Base64.parse(parsed.iv);
66971
+ const ciphertext = import_crypto_js.default.enc.Base64.parse(parsed.value);
66972
+ const cipherParams = import_crypto_js.default.lib.CipherParams.create({ ciphertext });
66973
+ const decrypted = import_crypto_js.default.AES.decrypt(cipherParams, key, {
66974
+ iv,
66975
+ mode: import_crypto_js.default.mode.CBC,
66976
+ padding: import_crypto_js.default.pad.Pkcs7
66977
+ });
66978
+ const plaintext = decrypted.toString(import_crypto_js.default.enc.Utf8);
66979
+ if (!plaintext) {
66980
+ throw new Error("Decryption produced empty plaintext (wrong key/cipher).");
66981
+ }
66982
+ return JSON.parse(plaintext);
66983
+ }
66984
+
67036
66985
  // src/components/ui/pagination.tsx
67037
66986
  var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
67038
66987
  function range(start, end) {
@@ -69964,7 +69913,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
69964
69913
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
69965
69914
  "div",
69966
69915
  {
69967
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
69916
+ className: "fixed inset-0 z-50 flex glass items-center justify-center p-4",
69968
69917
  style: { background: "rgba(0,0,0,0.5)" },
69969
69918
  onMouseDown: (e) => {
69970
69919
  if (e.target === e.currentTarget) onClose();
@@ -74739,7 +74688,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
74739
74688
 
74740
74689
  // src/components/ui/tooltip.tsx
74741
74690
  var React40 = __toESM(require_react(), 1);
74742
- var ReactDOM2 = __toESM(require_react_dom(), 1);
74691
+ var ReactDOM3 = __toESM(require_react_dom(), 1);
74743
74692
  var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
74744
74693
  function Tooltip({
74745
74694
  content,
@@ -74794,7 +74743,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
74794
74743
  onBlur: () => setVisible(false),
74795
74744
  children: [
74796
74745
  children,
74797
- visible && ReactDOM2.createPortal(
74746
+ visible && ReactDOM3.createPortal(
74798
74747
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
74799
74748
  "div",
74800
74749
  {
@@ -77626,6 +77575,12 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
77626
77575
  };
77627
77576
  return { store, getStore };
77628
77577
  }
77578
+
77579
+ // src/core/decryption/decode.ts
77580
+ function decryptResponse(response, key) {
77581
+ const payload = typeof response === "string" ? response : response.data;
77582
+ return decryptLaravelPayload(payload, key);
77583
+ }
77629
77584
  return __toCommonJS(index_exports);
77630
77585
  })();
77631
77586
  /*! Bundled license information: