@prediktif/ui 0.1.22 → 0.1.23

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.mts CHANGED
@@ -3,6 +3,7 @@ import { ReactNode, ComponentProps } from 'react';
3
3
  import * as _tanstack_react_table from '@tanstack/react-table';
4
4
  import { RowData, Table, ColumnDef, ColumnFiltersState, Row, SortingState, ColumnVisibilityState } from '@tanstack/react-table';
5
5
  export { ColumnDef, ColumnFiltersState, ColumnVisibilityState, FilterFn, Row, RowData, SortingState, Table, flexRender, useTable } from '@tanstack/react-table';
6
+ import { z } from 'zod';
6
7
  import * as class_variance_authority_types from 'class-variance-authority/types';
7
8
  import { Button as Button$1 } from '@base-ui/react/button';
8
9
  import { VariantProps } from 'class-variance-authority';
@@ -334,6 +335,24 @@ interface HeaderTitleProps {
334
335
  }
335
336
  declare const HeaderTitle: react.NamedExoticComponent<HeaderTitleProps>;
336
337
 
338
+ type GoogleIconProps = ComponentProps<"svg">;
339
+ declare function GoogleIcon({ className, ...props }: GoogleIconProps): react.JSX.Element;
340
+
341
+ declare const loginSchema: z.ZodObject<{
342
+ email: z.ZodPipe<z.ZodString, z.ZodEmail>;
343
+ password: z.ZodString;
344
+ }, z.core.$strip>;
345
+ type LoginValues = z.infer<typeof loginSchema>;
346
+ type LoginSubmitResult = {
347
+ error?: string;
348
+ } | undefined;
349
+ interface LoginServerProps {
350
+ onSubmit?: (values: LoginValues) => Promise<LoginSubmitResult> | LoginSubmitResult;
351
+ onGoogleSignIn?: () => Promise<void> | void;
352
+ isSubmitting?: boolean;
353
+ }
354
+ declare function LoginServer({ onSubmit, onGoogleSignIn, isSubmitting: externalIsSubmitting, }: LoginServerProps): react.JSX.Element;
355
+
337
356
  declare const buttonVariants: (props?: ({
338
357
  variant?: "default" | "outline" | "secondary" | "ghost" | "destructive" | "link" | null | undefined;
339
358
  size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
@@ -353,4 +372,4 @@ interface StateEmptyProps {
353
372
  }
354
373
  declare const StateEmpty: react.NamedExoticComponent<StateEmptyProps>;
355
374
 
356
- export { AppSidebar, type AppSidebarProps, AvatarUser, type AvatarUserProps, type ColumnMetaCustom, DataTable, DataTableContentBody, type DataTableContentBodyProps, DataTableContentHeader, type DataTableContentHeaderProps, type DataTableFeatures, DataTableFooterEntries, type DataTableFooterEntriesProps, DataTableFooterPagination, type DataTableFooterPaginationProps, DataTableHeaderAdd, type DataTableHeaderAddProps, DataTableHeaderDownload, type DataTableHeaderDownloadProps, DataTableHeaderFilter, type DataTableHeaderFilterProps, DataTableHeaderRefresh, DataTableHeaderSearch, type DataTableHeaderSearchProps, DataTableHeaderSort, type DataTableHeaderSortProps, DataTableHeaderToggle, type DataTableHeaderToggleProps, type DataTableProps, EmailLabel, type EmailLabelProps, EmailVerified, type EmailVerifiedProps, type FilterSelectOption, type FilterVariant, type HeaderTabItem, HeaderTabs, type HeaderTabsProps, HeaderTitle, type HeaderTitleProps, JoinedLabel, type JoinedLabelProps, type NavItem, type OrganizationItem, type RowActionItem, RowActions, type RowActionsProps, StateEmpty, type StateEmptyProps, UserRole, type UserRoleProps, UserStatus, type UserStatusProps, exportToCSV, exportToPDF, exportToXLSX, features, getTableExportData, printTable, smartFilterFn };
375
+ export { AppSidebar, type AppSidebarProps, AvatarUser, type AvatarUserProps, type ColumnMetaCustom, DataTable, DataTableContentBody, type DataTableContentBodyProps, DataTableContentHeader, type DataTableContentHeaderProps, type DataTableFeatures, DataTableFooterEntries, type DataTableFooterEntriesProps, DataTableFooterPagination, type DataTableFooterPaginationProps, DataTableHeaderAdd, type DataTableHeaderAddProps, DataTableHeaderDownload, type DataTableHeaderDownloadProps, DataTableHeaderFilter, type DataTableHeaderFilterProps, DataTableHeaderRefresh, DataTableHeaderSearch, type DataTableHeaderSearchProps, DataTableHeaderSort, type DataTableHeaderSortProps, DataTableHeaderToggle, type DataTableHeaderToggleProps, type DataTableProps, EmailLabel, type EmailLabelProps, EmailVerified, type EmailVerifiedProps, type FilterSelectOption, type FilterVariant, GoogleIcon, type GoogleIconProps, type HeaderTabItem, HeaderTabs, type HeaderTabsProps, HeaderTitle, type HeaderTitleProps, JoinedLabel, type JoinedLabelProps, LoginServer, type LoginServerProps, type LoginSubmitResult, type LoginValues, type NavItem, type OrganizationItem, type RowActionItem, RowActions, type RowActionsProps, StateEmpty, type StateEmptyProps, UserRole, type UserRoleProps, UserStatus, type UserStatusProps, exportToCSV, exportToPDF, exportToXLSX, features, getTableExportData, loginSchema, printTable, smartFilterFn };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { ReactNode, ComponentProps } from 'react';
3
3
  import * as _tanstack_react_table from '@tanstack/react-table';
4
4
  import { RowData, Table, ColumnDef, ColumnFiltersState, Row, SortingState, ColumnVisibilityState } from '@tanstack/react-table';
5
5
  export { ColumnDef, ColumnFiltersState, ColumnVisibilityState, FilterFn, Row, RowData, SortingState, Table, flexRender, useTable } from '@tanstack/react-table';
6
+ import { z } from 'zod';
6
7
  import * as class_variance_authority_types from 'class-variance-authority/types';
7
8
  import { Button as Button$1 } from '@base-ui/react/button';
8
9
  import { VariantProps } from 'class-variance-authority';
@@ -334,6 +335,24 @@ interface HeaderTitleProps {
334
335
  }
335
336
  declare const HeaderTitle: react.NamedExoticComponent<HeaderTitleProps>;
336
337
 
338
+ type GoogleIconProps = ComponentProps<"svg">;
339
+ declare function GoogleIcon({ className, ...props }: GoogleIconProps): react.JSX.Element;
340
+
341
+ declare const loginSchema: z.ZodObject<{
342
+ email: z.ZodPipe<z.ZodString, z.ZodEmail>;
343
+ password: z.ZodString;
344
+ }, z.core.$strip>;
345
+ type LoginValues = z.infer<typeof loginSchema>;
346
+ type LoginSubmitResult = {
347
+ error?: string;
348
+ } | undefined;
349
+ interface LoginServerProps {
350
+ onSubmit?: (values: LoginValues) => Promise<LoginSubmitResult> | LoginSubmitResult;
351
+ onGoogleSignIn?: () => Promise<void> | void;
352
+ isSubmitting?: boolean;
353
+ }
354
+ declare function LoginServer({ onSubmit, onGoogleSignIn, isSubmitting: externalIsSubmitting, }: LoginServerProps): react.JSX.Element;
355
+
337
356
  declare const buttonVariants: (props?: ({
338
357
  variant?: "default" | "outline" | "secondary" | "ghost" | "destructive" | "link" | null | undefined;
339
358
  size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
@@ -353,4 +372,4 @@ interface StateEmptyProps {
353
372
  }
354
373
  declare const StateEmpty: react.NamedExoticComponent<StateEmptyProps>;
355
374
 
356
- export { AppSidebar, type AppSidebarProps, AvatarUser, type AvatarUserProps, type ColumnMetaCustom, DataTable, DataTableContentBody, type DataTableContentBodyProps, DataTableContentHeader, type DataTableContentHeaderProps, type DataTableFeatures, DataTableFooterEntries, type DataTableFooterEntriesProps, DataTableFooterPagination, type DataTableFooterPaginationProps, DataTableHeaderAdd, type DataTableHeaderAddProps, DataTableHeaderDownload, type DataTableHeaderDownloadProps, DataTableHeaderFilter, type DataTableHeaderFilterProps, DataTableHeaderRefresh, DataTableHeaderSearch, type DataTableHeaderSearchProps, DataTableHeaderSort, type DataTableHeaderSortProps, DataTableHeaderToggle, type DataTableHeaderToggleProps, type DataTableProps, EmailLabel, type EmailLabelProps, EmailVerified, type EmailVerifiedProps, type FilterSelectOption, type FilterVariant, type HeaderTabItem, HeaderTabs, type HeaderTabsProps, HeaderTitle, type HeaderTitleProps, JoinedLabel, type JoinedLabelProps, type NavItem, type OrganizationItem, type RowActionItem, RowActions, type RowActionsProps, StateEmpty, type StateEmptyProps, UserRole, type UserRoleProps, UserStatus, type UserStatusProps, exportToCSV, exportToPDF, exportToXLSX, features, getTableExportData, printTable, smartFilterFn };
375
+ export { AppSidebar, type AppSidebarProps, AvatarUser, type AvatarUserProps, type ColumnMetaCustom, DataTable, DataTableContentBody, type DataTableContentBodyProps, DataTableContentHeader, type DataTableContentHeaderProps, type DataTableFeatures, DataTableFooterEntries, type DataTableFooterEntriesProps, DataTableFooterPagination, type DataTableFooterPaginationProps, DataTableHeaderAdd, type DataTableHeaderAddProps, DataTableHeaderDownload, type DataTableHeaderDownloadProps, DataTableHeaderFilter, type DataTableHeaderFilterProps, DataTableHeaderRefresh, DataTableHeaderSearch, type DataTableHeaderSearchProps, DataTableHeaderSort, type DataTableHeaderSortProps, DataTableHeaderToggle, type DataTableHeaderToggleProps, type DataTableProps, EmailLabel, type EmailLabelProps, EmailVerified, type EmailVerifiedProps, type FilterSelectOption, type FilterVariant, GoogleIcon, type GoogleIconProps, type HeaderTabItem, HeaderTabs, type HeaderTabsProps, HeaderTitle, type HeaderTitleProps, JoinedLabel, type JoinedLabelProps, LoginServer, type LoginServerProps, type LoginSubmitResult, type LoginValues, type NavItem, type OrganizationItem, type RowActionItem, RowActions, type RowActionsProps, StateEmpty, type StateEmptyProps, UserRole, type UserRoleProps, UserStatus, type UserStatusProps, exportToCSV, exportToPDF, exportToXLSX, features, getTableExportData, loginSchema, printTable, smartFilterFn };
package/dist/index.js CHANGED
@@ -76,9 +76,11 @@ __export(index_exports, {
76
76
  DataTableHeaderToggle: () => DataTableHeaderToggle,
77
77
  EmailLabel: () => EmailLabel,
78
78
  EmailVerified: () => EmailVerified,
79
+ GoogleIcon: () => GoogleIcon,
79
80
  HeaderTabs: () => HeaderTabs,
80
81
  HeaderTitle: () => HeaderTitle,
81
82
  JoinedLabel: () => JoinedLabel,
83
+ LoginServer: () => LoginServer,
82
84
  RowActions: () => RowActions,
83
85
  StateEmpty: () => StateEmpty,
84
86
  UserRole: () => UserRole,
@@ -89,6 +91,7 @@ __export(index_exports, {
89
91
  features: () => features,
90
92
  flexRender: () => import_react_table4.flexRender,
91
93
  getTableExportData: () => getTableExportData,
94
+ loginSchema: () => loginSchema,
92
95
  printTable: () => printTable,
93
96
  smartFilterFn: () => smartFilterFn,
94
97
  useTable: () => import_react_table4.useTable
@@ -3671,6 +3674,513 @@ var HeaderTitle = (0, import_react14.memo)(function HeaderTitle2({
3671
3674
  children
3672
3675
  ] });
3673
3676
  });
3677
+
3678
+ // src/components/composed/icons/google.tsx
3679
+ var import_jsx_runtime41 = require("react/jsx-runtime");
3680
+ function GoogleIcon(_a) {
3681
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3682
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
3683
+ "svg",
3684
+ __spreadProps(__spreadValues({
3685
+ role: "img",
3686
+ viewBox: "0 0 24 24",
3687
+ "aria-label": "Google logo",
3688
+ className,
3689
+ xmlns: "http://www.w3.org/2000/svg"
3690
+ }, props), {
3691
+ children: [
3692
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3693
+ "path",
3694
+ {
3695
+ fill: "#4285F4",
3696
+ d: "M23.745 12.27c0-.7-.06-1.4-.19-2.07H12v4.51h6.6c-.29 1.52-1.14 2.82-2.4 3.68v3.05h3.88c2.27-2.09 3.665-5.17 3.665-9.17z"
3697
+ }
3698
+ ),
3699
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3700
+ "path",
3701
+ {
3702
+ fill: "#34A853",
3703
+ d: "M12 24c3.24 0 5.95-1.08 7.93-2.91l-3.88-3.05c-1.08.72-2.45 1.16-4.05 1.16-3.12 0-5.77-2.1-6.72-4.93H1.24v3.15C3.26 21.36 7.33 24 12 24z"
3704
+ }
3705
+ ),
3706
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3707
+ "path",
3708
+ {
3709
+ fill: "#FBBC05",
3710
+ d: "M5.28 14.27c-.25-.72-.38-1.49-.38-2.27s.13-1.55.38-2.27V6.58H1.24C.45 8.16 0 9.97 0 12s.45 3.84 1.24 5.42l4.04-3.15z"
3711
+ }
3712
+ ),
3713
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
3714
+ "path",
3715
+ {
3716
+ fill: "#EA4335",
3717
+ d: "M12 4.75c1.77 0 3.35.61 4.6 1.8l3.42-3.42C17.95 1.19 15.24 0 12 0 7.33 0 3.26 2.64 1.24 6.58l4.04 3.15c.95-2.83 3.6-4.98 6.72-4.98z"
3718
+ }
3719
+ )
3720
+ ]
3721
+ })
3722
+ );
3723
+ }
3724
+
3725
+ // src/components/composed/login-server.tsx
3726
+ var import_zod = require("@hookform/resolvers/zod");
3727
+ var import_cn24 = require("cn");
3728
+ var import_lucide_react23 = require("lucide-react");
3729
+ var import_link3 = __toESM(require("next/link"));
3730
+ var import_react16 = require("react");
3731
+ var import_react_hook_form = require("react-hook-form");
3732
+ var import_zod2 = require("zod");
3733
+
3734
+ // src/components/ui/card.tsx
3735
+ var import_cn20 = require("cn");
3736
+ var import_jsx_runtime42 = require("react/jsx-runtime");
3737
+ function Card(_a) {
3738
+ var _b = _a, {
3739
+ className,
3740
+ size = "default"
3741
+ } = _b, props = __objRest(_b, [
3742
+ "className",
3743
+ "size"
3744
+ ]);
3745
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3746
+ "div",
3747
+ __spreadValues({
3748
+ "data-slot": "card",
3749
+ "data-size": size,
3750
+ className: (0, import_cn20.cn)(
3751
+ "group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-lg bg-card py-(--card-spacing) text-xs/relaxed text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg",
3752
+ className
3753
+ )
3754
+ }, props)
3755
+ );
3756
+ }
3757
+ function CardHeader(_a) {
3758
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3759
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3760
+ "div",
3761
+ __spreadValues({
3762
+ "data-slot": "card-header",
3763
+ className: (0, import_cn20.cn)(
3764
+ "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-lg px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",
3765
+ className
3766
+ )
3767
+ }, props)
3768
+ );
3769
+ }
3770
+ function CardTitle(_a) {
3771
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3772
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3773
+ "div",
3774
+ __spreadValues({
3775
+ "data-slot": "card-title",
3776
+ className: (0, import_cn20.cn)("font-heading text-sm font-medium", className)
3777
+ }, props)
3778
+ );
3779
+ }
3780
+ function CardDescription(_a) {
3781
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3782
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3783
+ "div",
3784
+ __spreadValues({
3785
+ "data-slot": "card-description",
3786
+ className: (0, import_cn20.cn)("text-xs/relaxed text-muted-foreground", className)
3787
+ }, props)
3788
+ );
3789
+ }
3790
+ function CardContent(_a) {
3791
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3792
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3793
+ "div",
3794
+ __spreadValues({
3795
+ "data-slot": "card-content",
3796
+ className: (0, import_cn20.cn)("px-(--card-spacing)", className)
3797
+ }, props)
3798
+ );
3799
+ }
3800
+
3801
+ // src/components/ui/field.tsx
3802
+ var import_class_variance_authority6 = require("class-variance-authority");
3803
+ var import_cn22 = require("cn");
3804
+ var import_react15 = require("react");
3805
+
3806
+ // src/components/ui/label.tsx
3807
+ var import_cn21 = require("cn");
3808
+ var import_jsx_runtime43 = require("react/jsx-runtime");
3809
+ function Label(_a) {
3810
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3811
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3812
+ "label",
3813
+ __spreadValues({
3814
+ "data-slot": "label",
3815
+ className: (0, import_cn21.cn)(
3816
+ "flex items-center gap-2 text-xs/relaxed leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
3817
+ className
3818
+ )
3819
+ }, props)
3820
+ );
3821
+ }
3822
+
3823
+ // src/components/ui/field.tsx
3824
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3825
+ function FieldGroup(_a) {
3826
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3827
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3828
+ "div",
3829
+ __spreadValues({
3830
+ "data-slot": "field-group",
3831
+ className: (0, import_cn22.cn)(
3832
+ "group/field-group @container/field-group flex w-full flex-col gap-4 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",
3833
+ className
3834
+ )
3835
+ }, props)
3836
+ );
3837
+ }
3838
+ var fieldVariants = (0, import_class_variance_authority6.cva)(
3839
+ "group/field flex w-full gap-2 data-[invalid=true]:text-destructive",
3840
+ {
3841
+ variants: {
3842
+ orientation: {
3843
+ vertical: "flex-col *:w-full [&>.sr-only]:w-auto",
3844
+ horizontal: "flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
3845
+ responsive: "flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px"
3846
+ }
3847
+ },
3848
+ defaultVariants: {
3849
+ orientation: "vertical"
3850
+ }
3851
+ }
3852
+ );
3853
+ function Field(_a) {
3854
+ var _b = _a, {
3855
+ className,
3856
+ orientation = "vertical"
3857
+ } = _b, props = __objRest(_b, [
3858
+ "className",
3859
+ "orientation"
3860
+ ]);
3861
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3862
+ "div",
3863
+ __spreadValues({
3864
+ role: "group",
3865
+ "data-slot": "field",
3866
+ "data-orientation": orientation,
3867
+ className: (0, import_cn22.cn)(fieldVariants({ orientation }), className)
3868
+ }, props)
3869
+ );
3870
+ }
3871
+ function FieldLabel(_a) {
3872
+ var _b = _a, {
3873
+ className
3874
+ } = _b, props = __objRest(_b, [
3875
+ "className"
3876
+ ]);
3877
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3878
+ Label,
3879
+ __spreadValues({
3880
+ "data-slot": "field-label",
3881
+ className: (0, import_cn22.cn)(
3882
+ "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-input/40 has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-2 has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/30 *:data-[slot=field]:p-2 dark:has-data-checked:bg-primary/10",
3883
+ "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
3884
+ className
3885
+ )
3886
+ }, props)
3887
+ );
3888
+ }
3889
+ function FieldDescription(_a) {
3890
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3891
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3892
+ "p",
3893
+ __spreadValues({
3894
+ "data-slot": "field-description",
3895
+ className: (0, import_cn22.cn)(
3896
+ "text-left text-xs/relaxed leading-normal font-normal text-muted-foreground group-has-data-horizontal/field:text-balance [[data-variant=legend]+&]:-mt-1.5",
3897
+ "last:mt-0 nth-last-2:-mt-1",
3898
+ "[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
3899
+ className
3900
+ )
3901
+ }, props)
3902
+ );
3903
+ }
3904
+ function FieldSeparator(_a) {
3905
+ var _b = _a, {
3906
+ children,
3907
+ className
3908
+ } = _b, props = __objRest(_b, [
3909
+ "children",
3910
+ "className"
3911
+ ]);
3912
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
3913
+ "div",
3914
+ __spreadProps(__spreadValues({
3915
+ "data-slot": "field-separator",
3916
+ "data-content": !!children,
3917
+ className: (0, import_cn22.cn)(
3918
+ "relative -my-2 h-5 text-xs/relaxed group-data-[variant=outline]/field-group:-mb-2",
3919
+ className
3920
+ )
3921
+ }, props), {
3922
+ children: [
3923
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Separator, { className: "absolute inset-0 top-1/2" }),
3924
+ children && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3925
+ "span",
3926
+ {
3927
+ className: "relative mx-auto block w-fit bg-background px-2 text-muted-foreground",
3928
+ "data-slot": "field-separator-content",
3929
+ children
3930
+ }
3931
+ )
3932
+ ]
3933
+ })
3934
+ );
3935
+ }
3936
+ function FieldError(_a) {
3937
+ var _b = _a, {
3938
+ className,
3939
+ children,
3940
+ errors
3941
+ } = _b, props = __objRest(_b, [
3942
+ "className",
3943
+ "children",
3944
+ "errors"
3945
+ ]);
3946
+ const content = (0, import_react15.useMemo)(() => {
3947
+ var _a2;
3948
+ if (children) {
3949
+ return children;
3950
+ }
3951
+ if (!(errors == null ? void 0 : errors.length)) {
3952
+ return null;
3953
+ }
3954
+ const uniqueErrors = [
3955
+ ...new Map(errors.map((error) => [error == null ? void 0 : error.message, error])).values()
3956
+ ];
3957
+ if ((uniqueErrors == null ? void 0 : uniqueErrors.length) === 1) {
3958
+ return (_a2 = uniqueErrors[0]) == null ? void 0 : _a2.message;
3959
+ }
3960
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("ul", { className: "ml-4 flex list-disc flex-col gap-1", children: uniqueErrors.map(
3961
+ (error, index) => (error == null ? void 0 : error.message) && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("li", { children: error.message }, index)
3962
+ ) });
3963
+ }, [children, errors]);
3964
+ if (!content) {
3965
+ return null;
3966
+ }
3967
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3968
+ "div",
3969
+ __spreadProps(__spreadValues({
3970
+ role: "alert",
3971
+ "data-slot": "field-error",
3972
+ className: (0, import_cn22.cn)("text-xs/relaxed font-normal text-destructive", className)
3973
+ }, props), {
3974
+ children: content
3975
+ })
3976
+ );
3977
+ }
3978
+
3979
+ // src/components/ui/toast.tsx
3980
+ var import_toast = require("@base-ui/react/toast");
3981
+ var import_cn23 = require("cn");
3982
+ var import_lucide_react22 = require("lucide-react");
3983
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3984
+ var toast = import_toast.Toast.createToastManager();
3985
+ var createToastManager = import_toast.Toast.createToastManager;
3986
+ var useToastManager = import_toast.Toast.useToastManager;
3987
+
3988
+ // src/components/composed/login-server.tsx
3989
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3990
+ var loginSchema = import_zod2.z.object({
3991
+ email: import_zod2.z.string().trim().toLowerCase().min(1, "Email is required").max(254, "Email is too long").pipe(import_zod2.z.email("Invalid email format")),
3992
+ password: import_zod2.z.string().min(1, "Password is required").min(8, "Password must be at least 8 characters").max(128, "Password must not exceed 128 characters")
3993
+ });
3994
+ function LoginServer({
3995
+ onSubmit,
3996
+ onGoogleSignIn,
3997
+ isSubmitting: externalIsSubmitting
3998
+ }) {
3999
+ const [isRedirecting, setIsRedirecting] = (0, import_react16.useState)(false);
4000
+ const [isGoogleLoading, setIsGoogleLoading] = (0, import_react16.useState)(false);
4001
+ const form = (0, import_react_hook_form.useForm)({
4002
+ resolver: (0, import_zod.zodResolver)(loginSchema),
4003
+ defaultValues: {
4004
+ email: "",
4005
+ password: ""
4006
+ }
4007
+ });
4008
+ const isPending = externalIsSubmitting != null ? externalIsSubmitting : form.formState.isSubmitting || isRedirecting || isGoogleLoading;
4009
+ const handleFormSubmit = async (values) => {
4010
+ try {
4011
+ if (!onSubmit) {
4012
+ toast.add({
4013
+ description: "Login action handler is not configured."
4014
+ });
4015
+ return;
4016
+ }
4017
+ const res = await onSubmit(values);
4018
+ if (res && typeof res === "object" && "error" in res && typeof res.error === "string" && res.error) {
4019
+ setIsRedirecting(false);
4020
+ toast.add({ description: res.error });
4021
+ return;
4022
+ }
4023
+ setIsRedirecting(true);
4024
+ } catch (e) {
4025
+ setIsRedirecting(false);
4026
+ toast.add({ description: "Unable to process your login request." });
4027
+ }
4028
+ };
4029
+ const handleGoogleSignIn = async () => {
4030
+ if (isPending) return;
4031
+ if (!onGoogleSignIn) {
4032
+ toast.add({
4033
+ description: "Google Sign-In is not currently available."
4034
+ });
4035
+ return;
4036
+ }
4037
+ try {
4038
+ setIsGoogleLoading(true);
4039
+ await onGoogleSignIn();
4040
+ } catch (e) {
4041
+ setIsGoogleLoading(false);
4042
+ toast.add({ description: "Google Sign-In failed to initialize." });
4043
+ }
4044
+ };
4045
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex min-h-svh flex-col items-center justify-center gap-6 bg-muted p-6 md:p-10", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex w-full max-w-sm flex-col gap-6", children: [
4046
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2 self-center font-medium", children: [
4047
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex size-6 items-center justify-center rounded-md bg-primary text-primary-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react23.GalleryVerticalEndIcon, { className: "size-4" }) }),
4048
+ "Prediktif"
4049
+ ] }),
4050
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-col gap-6", children: [
4051
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(Card, { children: [
4052
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(CardHeader, { className: "text-center", children: [
4053
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(CardTitle, { children: "Welcome back" }),
4054
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(CardDescription, { children: "Login with your Google account" })
4055
+ ] }),
4056
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("form", { onSubmit: form.handleSubmit(handleFormSubmit), noValidate: true, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(FieldGroup, { children: [
4057
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
4058
+ Button,
4059
+ {
4060
+ type: "button",
4061
+ variant: "outline",
4062
+ disabled: isPending,
4063
+ onClick: handleGoogleSignIn,
4064
+ children: [
4065
+ isGoogleLoading ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4066
+ import_lucide_react23.LoaderCircleIcon,
4067
+ {
4068
+ className: "animate-spin",
4069
+ "data-icon": "inline-start"
4070
+ }
4071
+ ) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(GoogleIcon, { className: "size-4 shrink-0" }),
4072
+ "Login with Google"
4073
+ ]
4074
+ }
4075
+ ) }),
4076
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldSeparator, { className: "*:data-[slot=field-separator-content]:bg-card", children: "Or continue with" }),
4077
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4078
+ import_react_hook_form.Controller,
4079
+ {
4080
+ name: "email",
4081
+ control: form.control,
4082
+ render: ({ field, fieldState }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(Field, { "data-invalid": fieldState.invalid, children: [
4083
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldLabel, { htmlFor: field.name, children: "Email" }),
4084
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4085
+ Input,
4086
+ __spreadProps(__spreadValues({}, field), {
4087
+ id: field.name,
4088
+ "aria-invalid": fieldState.invalid,
4089
+ disabled: isPending,
4090
+ placeholder: "m@example.com",
4091
+ type: "email",
4092
+ autoComplete: "email"
4093
+ })
4094
+ ),
4095
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldDescription, { children: "Enter the email address associated with your account." }),
4096
+ fieldState.invalid && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldError, { errors: [fieldState.error] })
4097
+ ] })
4098
+ }
4099
+ ),
4100
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4101
+ import_react_hook_form.Controller,
4102
+ {
4103
+ name: "password",
4104
+ control: form.control,
4105
+ render: ({ field, fieldState }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(Field, { "data-invalid": fieldState.invalid, children: [
4106
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center", children: [
4107
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldLabel, { htmlFor: field.name, children: "Password" }),
4108
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4109
+ import_link3.default,
4110
+ {
4111
+ href: "/forgot-password",
4112
+ className: "ml-auto inline-block underline-offset-4 hover:underline",
4113
+ children: "Forgot your password?"
4114
+ }
4115
+ )
4116
+ ] }),
4117
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4118
+ Input,
4119
+ __spreadProps(__spreadValues({}, field), {
4120
+ id: field.name,
4121
+ "aria-invalid": fieldState.invalid,
4122
+ disabled: isPending,
4123
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
4124
+ type: "password",
4125
+ autoComplete: "current-password"
4126
+ })
4127
+ ),
4128
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldDescription, { children: "Enter your account password." }),
4129
+ fieldState.invalid && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldError, { errors: [fieldState.error] })
4130
+ ] })
4131
+ }
4132
+ ),
4133
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(Field, { children: [
4134
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
4135
+ Button,
4136
+ {
4137
+ type: "submit",
4138
+ disabled: isPending,
4139
+ className: "w-full",
4140
+ children: [
4141
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4142
+ import_lucide_react23.LoaderCircleIcon,
4143
+ {
4144
+ className: (0, import_cn24.cn)(
4145
+ "animate-spin",
4146
+ isPending && !isGoogleLoading ? "block" : "hidden"
4147
+ ),
4148
+ "data-icon": "inline-start"
4149
+ }
4150
+ ),
4151
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4152
+ import_lucide_react23.LogInIcon,
4153
+ {
4154
+ className: (0, import_cn24.cn)(
4155
+ !isPending || isGoogleLoading ? "block" : "hidden"
4156
+ ),
4157
+ "data-icon": "inline-start"
4158
+ }
4159
+ ),
4160
+ isRedirecting ? "Redirecting to application..." : form.formState.isSubmitting ? "Signing in..." : "Login"
4161
+ ]
4162
+ }
4163
+ ),
4164
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(FieldDescription, { className: "text-center", children: [
4165
+ "Don't have an account?",
4166
+ " ",
4167
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_link3.default, { href: "/register", children: "Sign up" })
4168
+ ] })
4169
+ ] })
4170
+ ] }) }) })
4171
+ ] }),
4172
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(FieldDescription, { className: "px-6 text-center", children: [
4173
+ "By clicking continue, you agree to our",
4174
+ " ",
4175
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_link3.default, { href: "/terms", children: "Terms of Service" }),
4176
+ " and",
4177
+ " ",
4178
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_link3.default, { href: "/privacy", children: "Privacy Policy" }),
4179
+ "."
4180
+ ] })
4181
+ ] })
4182
+ ] }) });
4183
+ }
3674
4184
  // Annotate the CommonJS export names for ESM import in node:
3675
4185
  0 && (module.exports = {
3676
4186
  AppSidebar,
@@ -3689,9 +4199,11 @@ var HeaderTitle = (0, import_react14.memo)(function HeaderTitle2({
3689
4199
  DataTableHeaderToggle,
3690
4200
  EmailLabel,
3691
4201
  EmailVerified,
4202
+ GoogleIcon,
3692
4203
  HeaderTabs,
3693
4204
  HeaderTitle,
3694
4205
  JoinedLabel,
4206
+ LoginServer,
3695
4207
  RowActions,
3696
4208
  StateEmpty,
3697
4209
  UserRole,
@@ -3702,6 +4214,7 @@ var HeaderTitle = (0, import_react14.memo)(function HeaderTitle2({
3702
4214
  features,
3703
4215
  flexRender,
3704
4216
  getTableExportData,
4217
+ loginSchema,
3705
4218
  printTable,
3706
4219
  smartFilterFn,
3707
4220
  useTable
package/dist/index.mjs CHANGED
@@ -3644,6 +3644,524 @@ var HeaderTitle = memo10(function HeaderTitle2({
3644
3644
  children
3645
3645
  ] });
3646
3646
  });
3647
+
3648
+ // src/components/composed/icons/google.tsx
3649
+ import { jsx as jsx41, jsxs as jsxs27 } from "react/jsx-runtime";
3650
+ function GoogleIcon(_a) {
3651
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3652
+ return /* @__PURE__ */ jsxs27(
3653
+ "svg",
3654
+ __spreadProps(__spreadValues({
3655
+ role: "img",
3656
+ viewBox: "0 0 24 24",
3657
+ "aria-label": "Google logo",
3658
+ className,
3659
+ xmlns: "http://www.w3.org/2000/svg"
3660
+ }, props), {
3661
+ children: [
3662
+ /* @__PURE__ */ jsx41(
3663
+ "path",
3664
+ {
3665
+ fill: "#4285F4",
3666
+ d: "M23.745 12.27c0-.7-.06-1.4-.19-2.07H12v4.51h6.6c-.29 1.52-1.14 2.82-2.4 3.68v3.05h3.88c2.27-2.09 3.665-5.17 3.665-9.17z"
3667
+ }
3668
+ ),
3669
+ /* @__PURE__ */ jsx41(
3670
+ "path",
3671
+ {
3672
+ fill: "#34A853",
3673
+ d: "M12 24c3.24 0 5.95-1.08 7.93-2.91l-3.88-3.05c-1.08.72-2.45 1.16-4.05 1.16-3.12 0-5.77-2.1-6.72-4.93H1.24v3.15C3.26 21.36 7.33 24 12 24z"
3674
+ }
3675
+ ),
3676
+ /* @__PURE__ */ jsx41(
3677
+ "path",
3678
+ {
3679
+ fill: "#FBBC05",
3680
+ d: "M5.28 14.27c-.25-.72-.38-1.49-.38-2.27s.13-1.55.38-2.27V6.58H1.24C.45 8.16 0 9.97 0 12s.45 3.84 1.24 5.42l4.04-3.15z"
3681
+ }
3682
+ ),
3683
+ /* @__PURE__ */ jsx41(
3684
+ "path",
3685
+ {
3686
+ fill: "#EA4335",
3687
+ d: "M12 4.75c1.77 0 3.35.61 4.6 1.8l3.42-3.42C17.95 1.19 15.24 0 12 0 7.33 0 3.26 2.64 1.24 6.58l4.04 3.15c.95-2.83 3.6-4.98 6.72-4.98z"
3688
+ }
3689
+ )
3690
+ ]
3691
+ })
3692
+ );
3693
+ }
3694
+
3695
+ // src/components/composed/login-server.tsx
3696
+ import { zodResolver } from "@hookform/resolvers/zod";
3697
+ import { cn as cn24 } from "cn";
3698
+ import {
3699
+ GalleryVerticalEndIcon,
3700
+ LoaderCircleIcon,
3701
+ LogInIcon
3702
+ } from "lucide-react";
3703
+ import Link3 from "next/link";
3704
+ import { useState as useState6 } from "react";
3705
+ import { Controller, useForm } from "react-hook-form";
3706
+ import { z } from "zod";
3707
+
3708
+ // src/components/ui/card.tsx
3709
+ import { cn as cn20 } from "cn";
3710
+ import { jsx as jsx42 } from "react/jsx-runtime";
3711
+ function Card(_a) {
3712
+ var _b = _a, {
3713
+ className,
3714
+ size = "default"
3715
+ } = _b, props = __objRest(_b, [
3716
+ "className",
3717
+ "size"
3718
+ ]);
3719
+ return /* @__PURE__ */ jsx42(
3720
+ "div",
3721
+ __spreadValues({
3722
+ "data-slot": "card",
3723
+ "data-size": size,
3724
+ className: cn20(
3725
+ "group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-lg bg-card py-(--card-spacing) text-xs/relaxed text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg",
3726
+ className
3727
+ )
3728
+ }, props)
3729
+ );
3730
+ }
3731
+ function CardHeader(_a) {
3732
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3733
+ return /* @__PURE__ */ jsx42(
3734
+ "div",
3735
+ __spreadValues({
3736
+ "data-slot": "card-header",
3737
+ className: cn20(
3738
+ "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-lg px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",
3739
+ className
3740
+ )
3741
+ }, props)
3742
+ );
3743
+ }
3744
+ function CardTitle(_a) {
3745
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3746
+ return /* @__PURE__ */ jsx42(
3747
+ "div",
3748
+ __spreadValues({
3749
+ "data-slot": "card-title",
3750
+ className: cn20("font-heading text-sm font-medium", className)
3751
+ }, props)
3752
+ );
3753
+ }
3754
+ function CardDescription(_a) {
3755
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3756
+ return /* @__PURE__ */ jsx42(
3757
+ "div",
3758
+ __spreadValues({
3759
+ "data-slot": "card-description",
3760
+ className: cn20("text-xs/relaxed text-muted-foreground", className)
3761
+ }, props)
3762
+ );
3763
+ }
3764
+ function CardContent(_a) {
3765
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3766
+ return /* @__PURE__ */ jsx42(
3767
+ "div",
3768
+ __spreadValues({
3769
+ "data-slot": "card-content",
3770
+ className: cn20("px-(--card-spacing)", className)
3771
+ }, props)
3772
+ );
3773
+ }
3774
+
3775
+ // src/components/ui/field.tsx
3776
+ import { cva as cva6 } from "class-variance-authority";
3777
+ import { cn as cn22 } from "cn";
3778
+ import { useMemo as useMemo4 } from "react";
3779
+
3780
+ // src/components/ui/label.tsx
3781
+ import { cn as cn21 } from "cn";
3782
+ import { jsx as jsx43 } from "react/jsx-runtime";
3783
+ function Label(_a) {
3784
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3785
+ return /* @__PURE__ */ jsx43(
3786
+ "label",
3787
+ __spreadValues({
3788
+ "data-slot": "label",
3789
+ className: cn21(
3790
+ "flex items-center gap-2 text-xs/relaxed leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
3791
+ className
3792
+ )
3793
+ }, props)
3794
+ );
3795
+ }
3796
+
3797
+ // src/components/ui/field.tsx
3798
+ import { jsx as jsx44, jsxs as jsxs28 } from "react/jsx-runtime";
3799
+ function FieldGroup(_a) {
3800
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3801
+ return /* @__PURE__ */ jsx44(
3802
+ "div",
3803
+ __spreadValues({
3804
+ "data-slot": "field-group",
3805
+ className: cn22(
3806
+ "group/field-group @container/field-group flex w-full flex-col gap-4 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",
3807
+ className
3808
+ )
3809
+ }, props)
3810
+ );
3811
+ }
3812
+ var fieldVariants = cva6(
3813
+ "group/field flex w-full gap-2 data-[invalid=true]:text-destructive",
3814
+ {
3815
+ variants: {
3816
+ orientation: {
3817
+ vertical: "flex-col *:w-full [&>.sr-only]:w-auto",
3818
+ horizontal: "flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
3819
+ responsive: "flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px"
3820
+ }
3821
+ },
3822
+ defaultVariants: {
3823
+ orientation: "vertical"
3824
+ }
3825
+ }
3826
+ );
3827
+ function Field(_a) {
3828
+ var _b = _a, {
3829
+ className,
3830
+ orientation = "vertical"
3831
+ } = _b, props = __objRest(_b, [
3832
+ "className",
3833
+ "orientation"
3834
+ ]);
3835
+ return /* @__PURE__ */ jsx44(
3836
+ "div",
3837
+ __spreadValues({
3838
+ role: "group",
3839
+ "data-slot": "field",
3840
+ "data-orientation": orientation,
3841
+ className: cn22(fieldVariants({ orientation }), className)
3842
+ }, props)
3843
+ );
3844
+ }
3845
+ function FieldLabel(_a) {
3846
+ var _b = _a, {
3847
+ className
3848
+ } = _b, props = __objRest(_b, [
3849
+ "className"
3850
+ ]);
3851
+ return /* @__PURE__ */ jsx44(
3852
+ Label,
3853
+ __spreadValues({
3854
+ "data-slot": "field-label",
3855
+ className: cn22(
3856
+ "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-input/40 has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-2 has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/30 *:data-[slot=field]:p-2 dark:has-data-checked:bg-primary/10",
3857
+ "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
3858
+ className
3859
+ )
3860
+ }, props)
3861
+ );
3862
+ }
3863
+ function FieldDescription(_a) {
3864
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3865
+ return /* @__PURE__ */ jsx44(
3866
+ "p",
3867
+ __spreadValues({
3868
+ "data-slot": "field-description",
3869
+ className: cn22(
3870
+ "text-left text-xs/relaxed leading-normal font-normal text-muted-foreground group-has-data-horizontal/field:text-balance [[data-variant=legend]+&]:-mt-1.5",
3871
+ "last:mt-0 nth-last-2:-mt-1",
3872
+ "[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
3873
+ className
3874
+ )
3875
+ }, props)
3876
+ );
3877
+ }
3878
+ function FieldSeparator(_a) {
3879
+ var _b = _a, {
3880
+ children,
3881
+ className
3882
+ } = _b, props = __objRest(_b, [
3883
+ "children",
3884
+ "className"
3885
+ ]);
3886
+ return /* @__PURE__ */ jsxs28(
3887
+ "div",
3888
+ __spreadProps(__spreadValues({
3889
+ "data-slot": "field-separator",
3890
+ "data-content": !!children,
3891
+ className: cn22(
3892
+ "relative -my-2 h-5 text-xs/relaxed group-data-[variant=outline]/field-group:-mb-2",
3893
+ className
3894
+ )
3895
+ }, props), {
3896
+ children: [
3897
+ /* @__PURE__ */ jsx44(Separator, { className: "absolute inset-0 top-1/2" }),
3898
+ children && /* @__PURE__ */ jsx44(
3899
+ "span",
3900
+ {
3901
+ className: "relative mx-auto block w-fit bg-background px-2 text-muted-foreground",
3902
+ "data-slot": "field-separator-content",
3903
+ children
3904
+ }
3905
+ )
3906
+ ]
3907
+ })
3908
+ );
3909
+ }
3910
+ function FieldError(_a) {
3911
+ var _b = _a, {
3912
+ className,
3913
+ children,
3914
+ errors
3915
+ } = _b, props = __objRest(_b, [
3916
+ "className",
3917
+ "children",
3918
+ "errors"
3919
+ ]);
3920
+ const content = useMemo4(() => {
3921
+ var _a2;
3922
+ if (children) {
3923
+ return children;
3924
+ }
3925
+ if (!(errors == null ? void 0 : errors.length)) {
3926
+ return null;
3927
+ }
3928
+ const uniqueErrors = [
3929
+ ...new Map(errors.map((error) => [error == null ? void 0 : error.message, error])).values()
3930
+ ];
3931
+ if ((uniqueErrors == null ? void 0 : uniqueErrors.length) === 1) {
3932
+ return (_a2 = uniqueErrors[0]) == null ? void 0 : _a2.message;
3933
+ }
3934
+ return /* @__PURE__ */ jsx44("ul", { className: "ml-4 flex list-disc flex-col gap-1", children: uniqueErrors.map(
3935
+ (error, index) => (error == null ? void 0 : error.message) && /* @__PURE__ */ jsx44("li", { children: error.message }, index)
3936
+ ) });
3937
+ }, [children, errors]);
3938
+ if (!content) {
3939
+ return null;
3940
+ }
3941
+ return /* @__PURE__ */ jsx44(
3942
+ "div",
3943
+ __spreadProps(__spreadValues({
3944
+ role: "alert",
3945
+ "data-slot": "field-error",
3946
+ className: cn22("text-xs/relaxed font-normal text-destructive", className)
3947
+ }, props), {
3948
+ children: content
3949
+ })
3950
+ );
3951
+ }
3952
+
3953
+ // src/components/ui/toast.tsx
3954
+ import { Toast as ToastPrimitive } from "@base-ui/react/toast";
3955
+ import { cn as cn23 } from "cn";
3956
+ import {
3957
+ CircleCheckIcon,
3958
+ InfoIcon,
3959
+ Loader2Icon,
3960
+ OctagonXIcon,
3961
+ TriangleAlertIcon,
3962
+ XIcon as XIcon3
3963
+ } from "lucide-react";
3964
+ import { jsx as jsx45, jsxs as jsxs29 } from "react/jsx-runtime";
3965
+ var toast = ToastPrimitive.createToastManager();
3966
+ var createToastManager = ToastPrimitive.createToastManager;
3967
+ var useToastManager = ToastPrimitive.useToastManager;
3968
+
3969
+ // src/components/composed/login-server.tsx
3970
+ import { jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
3971
+ var loginSchema = z.object({
3972
+ email: z.string().trim().toLowerCase().min(1, "Email is required").max(254, "Email is too long").pipe(z.email("Invalid email format")),
3973
+ password: z.string().min(1, "Password is required").min(8, "Password must be at least 8 characters").max(128, "Password must not exceed 128 characters")
3974
+ });
3975
+ function LoginServer({
3976
+ onSubmit,
3977
+ onGoogleSignIn,
3978
+ isSubmitting: externalIsSubmitting
3979
+ }) {
3980
+ const [isRedirecting, setIsRedirecting] = useState6(false);
3981
+ const [isGoogleLoading, setIsGoogleLoading] = useState6(false);
3982
+ const form = useForm({
3983
+ resolver: zodResolver(loginSchema),
3984
+ defaultValues: {
3985
+ email: "",
3986
+ password: ""
3987
+ }
3988
+ });
3989
+ const isPending = externalIsSubmitting != null ? externalIsSubmitting : form.formState.isSubmitting || isRedirecting || isGoogleLoading;
3990
+ const handleFormSubmit = async (values) => {
3991
+ try {
3992
+ if (!onSubmit) {
3993
+ toast.add({
3994
+ description: "Login action handler is not configured."
3995
+ });
3996
+ return;
3997
+ }
3998
+ const res = await onSubmit(values);
3999
+ if (res && typeof res === "object" && "error" in res && typeof res.error === "string" && res.error) {
4000
+ setIsRedirecting(false);
4001
+ toast.add({ description: res.error });
4002
+ return;
4003
+ }
4004
+ setIsRedirecting(true);
4005
+ } catch (e) {
4006
+ setIsRedirecting(false);
4007
+ toast.add({ description: "Unable to process your login request." });
4008
+ }
4009
+ };
4010
+ const handleGoogleSignIn = async () => {
4011
+ if (isPending) return;
4012
+ if (!onGoogleSignIn) {
4013
+ toast.add({
4014
+ description: "Google Sign-In is not currently available."
4015
+ });
4016
+ return;
4017
+ }
4018
+ try {
4019
+ setIsGoogleLoading(true);
4020
+ await onGoogleSignIn();
4021
+ } catch (e) {
4022
+ setIsGoogleLoading(false);
4023
+ toast.add({ description: "Google Sign-In failed to initialize." });
4024
+ }
4025
+ };
4026
+ return /* @__PURE__ */ jsx46("div", { className: "flex min-h-svh flex-col items-center justify-center gap-6 bg-muted p-6 md:p-10", children: /* @__PURE__ */ jsxs30("div", { className: "flex w-full max-w-sm flex-col gap-6", children: [
4027
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2 self-center font-medium", children: [
4028
+ /* @__PURE__ */ jsx46("div", { className: "flex size-6 items-center justify-center rounded-md bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx46(GalleryVerticalEndIcon, { className: "size-4" }) }),
4029
+ "Prediktif"
4030
+ ] }),
4031
+ /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-6", children: [
4032
+ /* @__PURE__ */ jsxs30(Card, { children: [
4033
+ /* @__PURE__ */ jsxs30(CardHeader, { className: "text-center", children: [
4034
+ /* @__PURE__ */ jsx46(CardTitle, { children: "Welcome back" }),
4035
+ /* @__PURE__ */ jsx46(CardDescription, { children: "Login with your Google account" })
4036
+ ] }),
4037
+ /* @__PURE__ */ jsx46(CardContent, { children: /* @__PURE__ */ jsx46("form", { onSubmit: form.handleSubmit(handleFormSubmit), noValidate: true, children: /* @__PURE__ */ jsxs30(FieldGroup, { children: [
4038
+ /* @__PURE__ */ jsx46(Field, { children: /* @__PURE__ */ jsxs30(
4039
+ Button,
4040
+ {
4041
+ type: "button",
4042
+ variant: "outline",
4043
+ disabled: isPending,
4044
+ onClick: handleGoogleSignIn,
4045
+ children: [
4046
+ isGoogleLoading ? /* @__PURE__ */ jsx46(
4047
+ LoaderCircleIcon,
4048
+ {
4049
+ className: "animate-spin",
4050
+ "data-icon": "inline-start"
4051
+ }
4052
+ ) : /* @__PURE__ */ jsx46(GoogleIcon, { className: "size-4 shrink-0" }),
4053
+ "Login with Google"
4054
+ ]
4055
+ }
4056
+ ) }),
4057
+ /* @__PURE__ */ jsx46(FieldSeparator, { className: "*:data-[slot=field-separator-content]:bg-card", children: "Or continue with" }),
4058
+ /* @__PURE__ */ jsx46(
4059
+ Controller,
4060
+ {
4061
+ name: "email",
4062
+ control: form.control,
4063
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsxs30(Field, { "data-invalid": fieldState.invalid, children: [
4064
+ /* @__PURE__ */ jsx46(FieldLabel, { htmlFor: field.name, children: "Email" }),
4065
+ /* @__PURE__ */ jsx46(
4066
+ Input,
4067
+ __spreadProps(__spreadValues({}, field), {
4068
+ id: field.name,
4069
+ "aria-invalid": fieldState.invalid,
4070
+ disabled: isPending,
4071
+ placeholder: "m@example.com",
4072
+ type: "email",
4073
+ autoComplete: "email"
4074
+ })
4075
+ ),
4076
+ /* @__PURE__ */ jsx46(FieldDescription, { children: "Enter the email address associated with your account." }),
4077
+ fieldState.invalid && /* @__PURE__ */ jsx46(FieldError, { errors: [fieldState.error] })
4078
+ ] })
4079
+ }
4080
+ ),
4081
+ /* @__PURE__ */ jsx46(
4082
+ Controller,
4083
+ {
4084
+ name: "password",
4085
+ control: form.control,
4086
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsxs30(Field, { "data-invalid": fieldState.invalid, children: [
4087
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center", children: [
4088
+ /* @__PURE__ */ jsx46(FieldLabel, { htmlFor: field.name, children: "Password" }),
4089
+ /* @__PURE__ */ jsx46(
4090
+ Link3,
4091
+ {
4092
+ href: "/forgot-password",
4093
+ className: "ml-auto inline-block underline-offset-4 hover:underline",
4094
+ children: "Forgot your password?"
4095
+ }
4096
+ )
4097
+ ] }),
4098
+ /* @__PURE__ */ jsx46(
4099
+ Input,
4100
+ __spreadProps(__spreadValues({}, field), {
4101
+ id: field.name,
4102
+ "aria-invalid": fieldState.invalid,
4103
+ disabled: isPending,
4104
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
4105
+ type: "password",
4106
+ autoComplete: "current-password"
4107
+ })
4108
+ ),
4109
+ /* @__PURE__ */ jsx46(FieldDescription, { children: "Enter your account password." }),
4110
+ fieldState.invalid && /* @__PURE__ */ jsx46(FieldError, { errors: [fieldState.error] })
4111
+ ] })
4112
+ }
4113
+ ),
4114
+ /* @__PURE__ */ jsxs30(Field, { children: [
4115
+ /* @__PURE__ */ jsxs30(
4116
+ Button,
4117
+ {
4118
+ type: "submit",
4119
+ disabled: isPending,
4120
+ className: "w-full",
4121
+ children: [
4122
+ /* @__PURE__ */ jsx46(
4123
+ LoaderCircleIcon,
4124
+ {
4125
+ className: cn24(
4126
+ "animate-spin",
4127
+ isPending && !isGoogleLoading ? "block" : "hidden"
4128
+ ),
4129
+ "data-icon": "inline-start"
4130
+ }
4131
+ ),
4132
+ /* @__PURE__ */ jsx46(
4133
+ LogInIcon,
4134
+ {
4135
+ className: cn24(
4136
+ !isPending || isGoogleLoading ? "block" : "hidden"
4137
+ ),
4138
+ "data-icon": "inline-start"
4139
+ }
4140
+ ),
4141
+ isRedirecting ? "Redirecting to application..." : form.formState.isSubmitting ? "Signing in..." : "Login"
4142
+ ]
4143
+ }
4144
+ ),
4145
+ /* @__PURE__ */ jsxs30(FieldDescription, { className: "text-center", children: [
4146
+ "Don't have an account?",
4147
+ " ",
4148
+ /* @__PURE__ */ jsx46(Link3, { href: "/register", children: "Sign up" })
4149
+ ] })
4150
+ ] })
4151
+ ] }) }) })
4152
+ ] }),
4153
+ /* @__PURE__ */ jsxs30(FieldDescription, { className: "px-6 text-center", children: [
4154
+ "By clicking continue, you agree to our",
4155
+ " ",
4156
+ /* @__PURE__ */ jsx46(Link3, { href: "/terms", children: "Terms of Service" }),
4157
+ " and",
4158
+ " ",
4159
+ /* @__PURE__ */ jsx46(Link3, { href: "/privacy", children: "Privacy Policy" }),
4160
+ "."
4161
+ ] })
4162
+ ] })
4163
+ ] }) });
4164
+ }
3647
4165
  export {
3648
4166
  AppSidebar,
3649
4167
  AvatarUser,
@@ -3661,9 +4179,11 @@ export {
3661
4179
  DataTableHeaderToggle,
3662
4180
  EmailLabel,
3663
4181
  EmailVerified,
4182
+ GoogleIcon,
3664
4183
  HeaderTabs,
3665
4184
  HeaderTitle,
3666
4185
  JoinedLabel,
4186
+ LoginServer,
3667
4187
  RowActions,
3668
4188
  StateEmpty,
3669
4189
  UserRole,
@@ -3674,6 +4194,7 @@ export {
3674
4194
  features,
3675
4195
  flexRender3 as flexRender,
3676
4196
  getTableExportData,
4197
+ loginSchema,
3677
4198
  printTable,
3678
4199
  smartFilterFn,
3679
4200
  useTable
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prediktif/ui",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -31,6 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@base-ui/react": "^1.8.0",
34
+ "@hookform/resolvers": "^5.9.1",
34
35
  "@radix-ui/react-use-controllable-state": "^1.2.6",
35
36
  "@rive-app/react-webgl2": "^4.34.2",
36
37
  "@shadcn/react": "^0.3.1",
@@ -59,6 +60,7 @@
59
60
  "react": "19.2.8",
60
61
  "react-day-picker": "^10.0.1",
61
62
  "react-dom": "19.2.8",
63
+ "react-hook-form": "^7.88.0",
62
64
  "react-jsx-parser": "^2.4.1",
63
65
  "react-resizable-panels": "^4.12.4",
64
66
  "recharts": "3.8.0",
@@ -68,7 +70,8 @@
68
70
  "tokenlens": "^1.3.1",
69
71
  "tw-animate-css": "^1.4.0",
70
72
  "use-stick-to-bottom": "^1.1.6",
71
- "xlsx": "^0.18.5"
73
+ "xlsx": "^0.18.5",
74
+ "zod": "^4.6.5"
72
75
  },
73
76
  "devDependencies": {
74
77
  "@biomejs/biome": "2.4.2",