@hex-core/components 1.8.0 → 1.9.0

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.js CHANGED
@@ -9753,6 +9753,1034 @@ function SpacedRepetition({
9753
9753
  );
9754
9754
  }
9755
9755
 
9756
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, Arc, AspectRatio, Attachment, AudioPlayer, AudioWaveform, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Canvas, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chord, Citation, Cloze, Cluster, CodeBlock, CodeBlockCopy2 as CodeBlockCopy, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ColorPicker, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CompareTable, Composer, Container, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuTrigger, DataTable, DatePicker, Deck, Dendrogram, Diagram, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuTrigger, Dropzone, Empty, ErrorState, FileTree, Flashcard, Flowchart, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Funnel, Gantt, Grid, HoverCard, HoverCardContent, HoverCardTrigger, ImageOcclusion, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label, Loading, LoadingIndicator, Markdown, Matrix, Menubar, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarSeparator, MenubarShortcut, MenubarTrigger, Message, MessageActions, MessageList, MindMap, MultiCombobox, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, OrgChart, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, Pyramid, Quiz, RadioGroup, RadioGroupItem, Reasoning, ResizableHandle, ResizablePanel, ResizablePanelGroup, Sankey, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Sequence, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarItem, SidebarProvider, SidebarTrigger, Skeleton, Slider, SpacedRepetition, Spacer, SpeechRecognition, Stack, Stepper, Suggestion, Sunburst, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, Terminal, Textarea, TimeAxis, TimePicker, Timeline, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCall, Toolbar, ToolbarButton, ToolbarLink, ToolbarSeparator, ToolbarToggleGroup, ToolbarToggleItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Tree, TreeMap, Venn, alertVariants, attachmentVariants, badgeVariants, buttonVariants, clusterVariants, cn, containerVariants, emptyVariants, errorStateVariants, formatHslTriplet, gridVariants, hexToHslTriplet, hslToRgb, hslTripletToHex, loadingIndicatorVariants, loadingVariants, messageVariants, navigationMenuTriggerStyle, parseHslTriplet, rgbToHsl, spacerVariants, stackVariants, tagVariants, toggleVariants, toolbarVariants, useFormField, useSidebar };
9756
+ // src/blocks/_shared/auth-adapter.ts
9757
+ var wait = (ms) => new Promise((r) => setTimeout(r, ms));
9758
+ var mockAuthAdapter = {
9759
+ async signInWithPassword() {
9760
+ await wait(400);
9761
+ return { ok: true, redirect: "/app" };
9762
+ },
9763
+ async signUpWithPassword() {
9764
+ await wait(400);
9765
+ return { ok: true, redirect: "/verify-email" };
9766
+ },
9767
+ async signInWithSocial({ provider }) {
9768
+ await wait(400);
9769
+ return { ok: true, redirect: `/oauth/${provider}/callback` };
9770
+ },
9771
+ async sendMagicLink() {
9772
+ await wait(400);
9773
+ return { ok: true };
9774
+ },
9775
+ async verifyOtp() {
9776
+ await wait(400);
9777
+ return { ok: true, redirect: "/app" };
9778
+ },
9779
+ async requestPasswordReset() {
9780
+ await wait(400);
9781
+ return { ok: true };
9782
+ },
9783
+ async resetPassword() {
9784
+ await wait(400);
9785
+ return { ok: true, redirect: "/sign-in" };
9786
+ },
9787
+ async registerPasskey() {
9788
+ await wait(400);
9789
+ return { ok: true };
9790
+ },
9791
+ async signInWithPasskey() {
9792
+ await wait(400);
9793
+ return { ok: true, redirect: "/app" };
9794
+ },
9795
+ async resendMagicLink() {
9796
+ await wait(400);
9797
+ return { ok: true };
9798
+ },
9799
+ async resendOtp() {
9800
+ await wait(400);
9801
+ return { ok: true };
9802
+ }
9803
+ };
9804
+ function AuthSignInSplit({
9805
+ adapter,
9806
+ socialProviders,
9807
+ brand,
9808
+ marketing,
9809
+ signUpHref = "/sign-up",
9810
+ forgotPasswordHref = "/forgot-password",
9811
+ className,
9812
+ onSuccess
9813
+ }) {
9814
+ const [email, setEmail] = React44.useState("");
9815
+ const [password, setPassword] = React44.useState("");
9816
+ const [remember, setRemember] = React44.useState(false);
9817
+ const [submitting, setSubmitting] = React44.useState(null);
9818
+ const [error, setError] = React44.useState(null);
9819
+ const isBusy = submitting !== null;
9820
+ async function handleSubmit(e) {
9821
+ e.preventDefault();
9822
+ if (!adapter.signInWithPassword) {
9823
+ console.warn(
9824
+ "[AuthSignInSplit] adapter.signInWithPassword is not implemented \u2014 wire it up before exposing the form."
9825
+ );
9826
+ setError({ code: "unimplemented", message: "Sign-in is currently unavailable. Please try again later." });
9827
+ return;
9828
+ }
9829
+ setError(null);
9830
+ setSubmitting("password");
9831
+ try {
9832
+ const result = await adapter.signInWithPassword({ email, password, remember });
9833
+ if (!result.ok) {
9834
+ setError(result.error ?? { code: "unknown", message: "Sign-in failed." });
9835
+ return;
9836
+ }
9837
+ onSuccess?.(result.redirect);
9838
+ } finally {
9839
+ setSubmitting(null);
9840
+ }
9841
+ }
9842
+ async function handleSocial(provider) {
9843
+ if (!adapter.signInWithSocial) {
9844
+ console.warn(
9845
+ `[AuthSignInSplit] adapter.signInWithSocial is not implemented but a ${provider} button is rendered \u2014 drop the entry from socialProviders or wire the method.`
9846
+ );
9847
+ setError({
9848
+ code: "unimplemented",
9849
+ message: "This sign-in option is currently unavailable. Please try a different method."
9850
+ });
9851
+ return;
9852
+ }
9853
+ setError(null);
9854
+ setSubmitting(provider);
9855
+ try {
9856
+ const result = await adapter.signInWithSocial({ provider });
9857
+ if (!result.ok) {
9858
+ setError(result.error ?? { code: "social-failed", message: "Sign-in failed." });
9859
+ return;
9860
+ }
9861
+ onSuccess?.(result.redirect);
9862
+ } finally {
9863
+ setSubmitting(null);
9864
+ }
9865
+ }
9866
+ return /* @__PURE__ */ jsxs("div", { className: cn("grid min-h-svh lg:grid-cols-2", className), children: [
9867
+ /* @__PURE__ */ jsxs(
9868
+ "aside",
9869
+ {
9870
+ "aria-hidden": "true",
9871
+ className: "hidden flex-col justify-between bg-muted/40 p-10 lg:flex",
9872
+ children: [
9873
+ /* @__PURE__ */ jsx("div", { children: brand }),
9874
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: marketing })
9875
+ ]
9876
+ }
9877
+ ),
9878
+ /* @__PURE__ */ jsx("main", { className: "flex items-center justify-center p-6 sm:p-10", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-6", children: [
9879
+ /* @__PURE__ */ jsxs("header", { className: "space-y-2 text-center lg:text-left", children: [
9880
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: "Welcome back" }),
9881
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Sign in to your account to continue." })
9882
+ ] }),
9883
+ error ? /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
9884
+ /* @__PURE__ */ jsx(AlertTitle, { children: "Sign-in failed" }),
9885
+ /* @__PURE__ */ jsx(AlertDescription, { children: error.message })
9886
+ ] }) : null,
9887
+ socialProviders && socialProviders.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
9888
+ /* @__PURE__ */ jsx("div", { className: "grid gap-2", children: socialProviders.map((p) => /* @__PURE__ */ jsxs(
9889
+ Button,
9890
+ {
9891
+ type: "button",
9892
+ variant: "outline",
9893
+ onClick: () => handleSocial(p.provider),
9894
+ disabled: isBusy,
9895
+ loading: submitting === p.provider,
9896
+ className: "w-full justify-center gap-2",
9897
+ children: [
9898
+ p.icon,
9899
+ /* @__PURE__ */ jsxs("span", { children: [
9900
+ "Continue with ",
9901
+ p.label
9902
+ ] })
9903
+ ]
9904
+ },
9905
+ p.provider
9906
+ )) }),
9907
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
9908
+ /* @__PURE__ */ jsx(Separator, {}),
9909
+ /* @__PURE__ */ jsx("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-background px-2 text-xs uppercase text-muted-foreground", children: "or" })
9910
+ ] })
9911
+ ] }) : null,
9912
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
9913
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
9914
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-sign-in-email", children: "Email" }),
9915
+ /* @__PURE__ */ jsx(
9916
+ Input,
9917
+ {
9918
+ id: "auth-sign-in-email",
9919
+ type: "email",
9920
+ autoComplete: "email",
9921
+ required: true,
9922
+ value: email,
9923
+ onChange: (e) => setEmail(e.target.value),
9924
+ disabled: isBusy
9925
+ }
9926
+ )
9927
+ ] }),
9928
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
9929
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
9930
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-sign-in-password", children: "Password" }),
9931
+ /* @__PURE__ */ jsx(
9932
+ "a",
9933
+ {
9934
+ href: forgotPasswordHref,
9935
+ className: "text-xs text-muted-foreground transition-all duration-200 ease-out hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded",
9936
+ children: "Forgot?"
9937
+ }
9938
+ )
9939
+ ] }),
9940
+ /* @__PURE__ */ jsx(
9941
+ Input,
9942
+ {
9943
+ id: "auth-sign-in-password",
9944
+ type: "password",
9945
+ autoComplete: "current-password",
9946
+ required: true,
9947
+ value: password,
9948
+ onChange: (e) => setPassword(e.target.value),
9949
+ disabled: isBusy
9950
+ }
9951
+ )
9952
+ ] }),
9953
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9954
+ /* @__PURE__ */ jsx(
9955
+ Checkbox,
9956
+ {
9957
+ id: "auth-sign-in-remember",
9958
+ checked: remember,
9959
+ onCheckedChange: (v) => setRemember(v === true),
9960
+ disabled: isBusy
9961
+ }
9962
+ ),
9963
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-sign-in-remember", className: "text-sm font-normal", children: "Remember me on this device" })
9964
+ ] }),
9965
+ /* @__PURE__ */ jsx(
9966
+ Button,
9967
+ {
9968
+ type: "submit",
9969
+ className: "w-full",
9970
+ disabled: isBusy,
9971
+ loading: submitting === "password",
9972
+ children: submitting === "password" ? "Signing in" : "Sign in"
9973
+ }
9974
+ )
9975
+ ] }),
9976
+ /* @__PURE__ */ jsxs("p", { className: "text-center text-sm text-muted-foreground lg:text-left", children: [
9977
+ "Don\u2019t have an account?",
9978
+ " ",
9979
+ /* @__PURE__ */ jsx(
9980
+ "a",
9981
+ {
9982
+ href: signUpHref,
9983
+ className: "font-medium text-foreground underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded",
9984
+ children: "Sign up"
9985
+ }
9986
+ )
9987
+ ] })
9988
+ ] }) })
9989
+ ] });
9990
+ }
9991
+ var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
9992
+ function AuthSignUpCard({
9993
+ adapter,
9994
+ socialProviders,
9995
+ signInHref = "/sign-in",
9996
+ termsHref = "/terms",
9997
+ privacyHref = "/privacy",
9998
+ passwordMinLength = 8,
9999
+ className,
10000
+ onSuccess
10001
+ }) {
10002
+ const [name, setName] = React44.useState("");
10003
+ const [email, setEmail] = React44.useState("");
10004
+ const [password, setPassword] = React44.useState("");
10005
+ const [confirmPassword, setConfirmPassword] = React44.useState("");
10006
+ const [acceptTerms, setAcceptTerms] = React44.useState(false);
10007
+ const [submitting, setSubmitting] = React44.useState(null);
10008
+ const [error, setError] = React44.useState(null);
10009
+ const isBusy = submitting !== null;
10010
+ function validate() {
10011
+ if (!EMAIL_REGEX.test(email)) {
10012
+ return { code: "invalid_email", message: "Enter a valid email address." };
10013
+ }
10014
+ if (password.length < passwordMinLength) {
10015
+ return {
10016
+ code: "password_too_short",
10017
+ message: `Password must be at least ${passwordMinLength} characters.`
10018
+ };
10019
+ }
10020
+ if (password !== confirmPassword) {
10021
+ return { code: "password_mismatch", message: "Passwords don't match." };
10022
+ }
10023
+ if (!acceptTerms) {
10024
+ return {
10025
+ code: "terms_required",
10026
+ message: "Please accept the terms of service to continue."
10027
+ };
10028
+ }
10029
+ return null;
10030
+ }
10031
+ async function handleSubmit(e) {
10032
+ e.preventDefault();
10033
+ const validation = validate();
10034
+ if (validation) {
10035
+ setError(validation);
10036
+ return;
10037
+ }
10038
+ if (!adapter.signUpWithPassword) {
10039
+ console.warn(
10040
+ "[AuthSignUpCard] adapter.signUpWithPassword is not implemented \u2014 wire it up before exposing the form."
10041
+ );
10042
+ setError({
10043
+ code: "unimplemented",
10044
+ message: "Sign-up is currently unavailable. Please try again later."
10045
+ });
10046
+ return;
10047
+ }
10048
+ setError(null);
10049
+ setSubmitting("password");
10050
+ try {
10051
+ const result = await adapter.signUpWithPassword({
10052
+ email,
10053
+ password,
10054
+ name: name.trim().length > 0 ? name.trim() : void 0
10055
+ });
10056
+ if (!result.ok) {
10057
+ setError(result.error ?? { code: "unknown", message: "Sign-up failed." });
10058
+ return;
10059
+ }
10060
+ onSuccess?.(result.redirect);
10061
+ } finally {
10062
+ setSubmitting(null);
10063
+ }
10064
+ }
10065
+ async function handleSocial(provider) {
10066
+ if (!adapter.signInWithSocial) {
10067
+ console.warn(
10068
+ `[AuthSignUpCard] adapter.signInWithSocial is not implemented but a ${provider} button is rendered \u2014 drop the entry from socialProviders or wire the method.`
10069
+ );
10070
+ setError({
10071
+ code: "unimplemented",
10072
+ message: "This sign-up option is currently unavailable. Please try a different method."
10073
+ });
10074
+ return;
10075
+ }
10076
+ setError(null);
10077
+ setSubmitting(provider);
10078
+ try {
10079
+ const result = await adapter.signInWithSocial({ provider });
10080
+ if (!result.ok) {
10081
+ setError(result.error ?? { code: "social-failed", message: "Sign-up failed." });
10082
+ return;
10083
+ }
10084
+ onSuccess?.(result.redirect);
10085
+ } finally {
10086
+ setSubmitting(null);
10087
+ }
10088
+ }
10089
+ return /* @__PURE__ */ jsx("div", { className: cn("flex min-h-svh items-center justify-center p-6 sm:p-10", className), children: /* @__PURE__ */ jsxs(Card, { className: "w-full max-w-md", children: [
10090
+ /* @__PURE__ */ jsxs(CardHeader, { className: "space-y-2 text-center", children: [
10091
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-2xl", children: "Create your account" }),
10092
+ /* @__PURE__ */ jsx(CardDescription, { children: "Get started in seconds \u2014 no credit card required." })
10093
+ ] }),
10094
+ /* @__PURE__ */ jsxs(CardContent, { className: "space-y-6", children: [
10095
+ error ? /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
10096
+ /* @__PURE__ */ jsx(AlertTitle, { children: "Couldn\u2019t create account" }),
10097
+ /* @__PURE__ */ jsx(AlertDescription, { children: error.message })
10098
+ ] }) : null,
10099
+ socialProviders && socialProviders.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
10100
+ /* @__PURE__ */ jsx("div", { className: "grid gap-2", children: socialProviders.map((p) => /* @__PURE__ */ jsxs(
10101
+ Button,
10102
+ {
10103
+ type: "button",
10104
+ variant: "outline",
10105
+ onClick: () => handleSocial(p.provider),
10106
+ disabled: isBusy,
10107
+ loading: submitting === p.provider,
10108
+ className: "w-full justify-center gap-2",
10109
+ children: [
10110
+ p.icon,
10111
+ /* @__PURE__ */ jsxs("span", { children: [
10112
+ "Continue with ",
10113
+ p.label
10114
+ ] })
10115
+ ]
10116
+ },
10117
+ p.provider
10118
+ )) }),
10119
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
10120
+ /* @__PURE__ */ jsx(Separator, {}),
10121
+ /* @__PURE__ */ jsx("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-card px-2 text-xs uppercase text-muted-foreground", children: "or sign up with email" })
10122
+ ] })
10123
+ ] }) : null,
10124
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
10125
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
10126
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "auth-sign-up-name", children: [
10127
+ "Full name ",
10128
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "(optional)" })
10129
+ ] }),
10130
+ /* @__PURE__ */ jsx(
10131
+ Input,
10132
+ {
10133
+ id: "auth-sign-up-name",
10134
+ type: "text",
10135
+ autoComplete: "name",
10136
+ value: name,
10137
+ onChange: (e) => setName(e.target.value),
10138
+ disabled: isBusy
10139
+ }
10140
+ )
10141
+ ] }),
10142
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
10143
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-sign-up-email", children: "Email" }),
10144
+ /* @__PURE__ */ jsx(
10145
+ Input,
10146
+ {
10147
+ id: "auth-sign-up-email",
10148
+ type: "email",
10149
+ autoComplete: "email",
10150
+ required: true,
10151
+ value: email,
10152
+ onChange: (e) => setEmail(e.target.value),
10153
+ disabled: isBusy
10154
+ }
10155
+ )
10156
+ ] }),
10157
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
10158
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-sign-up-password", children: "Password" }),
10159
+ /* @__PURE__ */ jsx(
10160
+ Input,
10161
+ {
10162
+ id: "auth-sign-up-password",
10163
+ type: "password",
10164
+ autoComplete: "new-password",
10165
+ required: true,
10166
+ minLength: passwordMinLength,
10167
+ value: password,
10168
+ onChange: (e) => setPassword(e.target.value),
10169
+ disabled: isBusy,
10170
+ "aria-describedby": "auth-sign-up-password-hint"
10171
+ }
10172
+ ),
10173
+ /* @__PURE__ */ jsxs(
10174
+ "p",
10175
+ {
10176
+ id: "auth-sign-up-password-hint",
10177
+ className: "text-xs text-muted-foreground",
10178
+ children: [
10179
+ "At least ",
10180
+ passwordMinLength,
10181
+ " characters."
10182
+ ]
10183
+ }
10184
+ )
10185
+ ] }),
10186
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
10187
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-sign-up-confirm", children: "Confirm password" }),
10188
+ /* @__PURE__ */ jsx(
10189
+ Input,
10190
+ {
10191
+ id: "auth-sign-up-confirm",
10192
+ type: "password",
10193
+ autoComplete: "new-password",
10194
+ required: true,
10195
+ value: confirmPassword,
10196
+ onChange: (e) => setConfirmPassword(e.target.value),
10197
+ disabled: isBusy
10198
+ }
10199
+ )
10200
+ ] }),
10201
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
10202
+ /* @__PURE__ */ jsx(
10203
+ Checkbox,
10204
+ {
10205
+ id: "auth-sign-up-terms",
10206
+ checked: acceptTerms,
10207
+ onCheckedChange: (v) => setAcceptTerms(v === true),
10208
+ disabled: isBusy,
10209
+ className: "mt-0.5"
10210
+ }
10211
+ ),
10212
+ /* @__PURE__ */ jsxs(
10213
+ Label,
10214
+ {
10215
+ htmlFor: "auth-sign-up-terms",
10216
+ className: "text-sm font-normal leading-snug",
10217
+ children: [
10218
+ "I agree to the",
10219
+ " ",
10220
+ /* @__PURE__ */ jsx(
10221
+ "a",
10222
+ {
10223
+ href: termsHref,
10224
+ className: "font-medium text-foreground underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded",
10225
+ children: "Terms of Service"
10226
+ }
10227
+ ),
10228
+ " ",
10229
+ "and",
10230
+ " ",
10231
+ /* @__PURE__ */ jsx(
10232
+ "a",
10233
+ {
10234
+ href: privacyHref,
10235
+ className: "font-medium text-foreground underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded",
10236
+ children: "Privacy Policy"
10237
+ }
10238
+ ),
10239
+ "."
10240
+ ]
10241
+ }
10242
+ )
10243
+ ] }),
10244
+ /* @__PURE__ */ jsx(
10245
+ Button,
10246
+ {
10247
+ type: "submit",
10248
+ className: "w-full",
10249
+ disabled: isBusy,
10250
+ loading: submitting === "password",
10251
+ children: submitting === "password" ? "Creating account" : "Create account"
10252
+ }
10253
+ )
10254
+ ] })
10255
+ ] }),
10256
+ /* @__PURE__ */ jsxs(CardFooter, { className: "justify-center text-sm text-muted-foreground", children: [
10257
+ "Already have an account?",
10258
+ " ",
10259
+ /* @__PURE__ */ jsx(
10260
+ "a",
10261
+ {
10262
+ href: signInHref,
10263
+ className: "ml-1 font-medium text-foreground underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded",
10264
+ children: "Sign in"
10265
+ }
10266
+ )
10267
+ ] })
10268
+ ] }) });
10269
+ }
10270
+ var EMAIL_REGEX2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
10271
+ var MailIcon = () => /* @__PURE__ */ jsxs(
10272
+ "svg",
10273
+ {
10274
+ xmlns: "http://www.w3.org/2000/svg",
10275
+ viewBox: "0 0 24 24",
10276
+ fill: "none",
10277
+ stroke: "currentColor",
10278
+ strokeWidth: 2,
10279
+ strokeLinecap: "round",
10280
+ strokeLinejoin: "round",
10281
+ "aria-hidden": "true",
10282
+ children: [
10283
+ /* @__PURE__ */ jsx("rect", { width: 20, height: 16, x: 2, y: 4, rx: 2 }),
10284
+ /* @__PURE__ */ jsx("path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" })
10285
+ ]
10286
+ }
10287
+ );
10288
+ function AuthForgotPassword({
10289
+ adapter,
10290
+ signInHref = "/sign-in",
10291
+ className,
10292
+ onSuccess
10293
+ }) {
10294
+ const [email, setEmail] = React44.useState("");
10295
+ const [submitting, setSubmitting] = React44.useState(false);
10296
+ const [error, setError] = React44.useState(null);
10297
+ const [submittedEmail, setSubmittedEmail] = React44.useState(null);
10298
+ async function handleSubmit(e) {
10299
+ e.preventDefault();
10300
+ if (!EMAIL_REGEX2.test(email)) {
10301
+ setError({ code: "invalid_email", message: "Enter a valid email address." });
10302
+ return;
10303
+ }
10304
+ if (!adapter.requestPasswordReset) {
10305
+ console.warn(
10306
+ "[AuthForgotPassword] adapter.requestPasswordReset is not implemented \u2014 wire it up before exposing the form."
10307
+ );
10308
+ setError({
10309
+ code: "unimplemented",
10310
+ message: "Password reset is currently unavailable. Please try again later."
10311
+ });
10312
+ return;
10313
+ }
10314
+ setError(null);
10315
+ setSubmitting(true);
10316
+ try {
10317
+ const result = await adapter.requestPasswordReset({ email });
10318
+ if (!result.ok) {
10319
+ setError(result.error ?? { code: "unknown", message: "Couldn't send reset link." });
10320
+ return;
10321
+ }
10322
+ setSubmittedEmail(email);
10323
+ onSuccess?.();
10324
+ } finally {
10325
+ setSubmitting(false);
10326
+ }
10327
+ }
10328
+ if (submittedEmail) {
10329
+ return /* @__PURE__ */ jsx(
10330
+ "div",
10331
+ {
10332
+ className: cn(
10333
+ "flex min-h-svh items-center justify-center p-6 sm:p-10",
10334
+ className
10335
+ ),
10336
+ children: /* @__PURE__ */ jsx("div", { className: "w-full max-w-sm", children: /* @__PURE__ */ jsx(
10337
+ Empty,
10338
+ {
10339
+ icon: /* @__PURE__ */ jsx(MailIcon, {}),
10340
+ title: "Check your inbox",
10341
+ description: /* @__PURE__ */ jsxs(Fragment, { children: [
10342
+ "We sent a password-reset link to",
10343
+ " ",
10344
+ /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: submittedEmail }),
10345
+ ". The link expires in 60 minutes."
10346
+ ] }),
10347
+ action: /* @__PURE__ */ jsx(Button, { variant: "outline", asChild: true, children: /* @__PURE__ */ jsx("a", { href: signInHref, children: "Back to sign in" }) })
10348
+ }
10349
+ ) })
10350
+ }
10351
+ );
10352
+ }
10353
+ return /* @__PURE__ */ jsx("div", { className: cn("flex min-h-svh items-center justify-center p-6 sm:p-10", className), children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-6", children: [
10354
+ /* @__PURE__ */ jsxs("header", { className: "space-y-2 text-center", children: [
10355
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: "Reset your password" }),
10356
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Enter your email and we\u2019ll send you a link to set a new password." })
10357
+ ] }),
10358
+ error ? /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
10359
+ /* @__PURE__ */ jsx(AlertTitle, { children: "Couldn\u2019t send reset link" }),
10360
+ /* @__PURE__ */ jsx(AlertDescription, { children: error.message })
10361
+ ] }) : null,
10362
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
10363
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
10364
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-forgot-email", children: "Email" }),
10365
+ /* @__PURE__ */ jsx(
10366
+ Input,
10367
+ {
10368
+ id: "auth-forgot-email",
10369
+ type: "email",
10370
+ autoComplete: "email",
10371
+ required: true,
10372
+ value: email,
10373
+ onChange: (e) => setEmail(e.target.value),
10374
+ disabled: submitting
10375
+ }
10376
+ )
10377
+ ] }),
10378
+ /* @__PURE__ */ jsx(
10379
+ Button,
10380
+ {
10381
+ type: "submit",
10382
+ className: "w-full",
10383
+ disabled: submitting,
10384
+ loading: submitting,
10385
+ children: submitting ? "Sending link" : "Send reset link"
10386
+ }
10387
+ )
10388
+ ] }),
10389
+ /* @__PURE__ */ jsxs("p", { className: "text-center text-sm text-muted-foreground", children: [
10390
+ "Remembered your password?",
10391
+ " ",
10392
+ /* @__PURE__ */ jsx(
10393
+ "a",
10394
+ {
10395
+ href: signInHref,
10396
+ className: "font-medium text-foreground underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded",
10397
+ children: "Sign in"
10398
+ }
10399
+ )
10400
+ ] })
10401
+ ] }) });
10402
+ }
10403
+ function AuthResetPassword({
10404
+ adapter,
10405
+ token,
10406
+ signInHref = "/sign-in",
10407
+ passwordMinLength = 8,
10408
+ className,
10409
+ onSuccess
10410
+ }) {
10411
+ const [password, setPassword] = React44.useState("");
10412
+ const [confirmPassword, setConfirmPassword] = React44.useState("");
10413
+ const [submitting, setSubmitting] = React44.useState(false);
10414
+ const [error, setError] = React44.useState(null);
10415
+ function validate() {
10416
+ if (password.length < passwordMinLength) {
10417
+ return {
10418
+ code: "password_too_short",
10419
+ message: `Password must be at least ${passwordMinLength} characters.`
10420
+ };
10421
+ }
10422
+ if (password !== confirmPassword) {
10423
+ return { code: "password_mismatch", message: "Passwords don't match." };
10424
+ }
10425
+ if (token.length === 0) {
10426
+ return {
10427
+ code: "missing_token",
10428
+ message: "This reset link is invalid or expired. Request a new one."
10429
+ };
10430
+ }
10431
+ return null;
10432
+ }
10433
+ async function handleSubmit(e) {
10434
+ e.preventDefault();
10435
+ const validation = validate();
10436
+ if (validation) {
10437
+ setError(validation);
10438
+ return;
10439
+ }
10440
+ if (!adapter.resetPassword) {
10441
+ console.warn(
10442
+ "[AuthResetPassword] adapter.resetPassword is not implemented \u2014 wire it up before exposing the form."
10443
+ );
10444
+ setError({
10445
+ code: "unimplemented",
10446
+ message: "Password reset is currently unavailable. Please try again later."
10447
+ });
10448
+ return;
10449
+ }
10450
+ setError(null);
10451
+ setSubmitting(true);
10452
+ try {
10453
+ const result = await adapter.resetPassword({ token, password });
10454
+ if (!result.ok) {
10455
+ setError(result.error ?? { code: "unknown", message: "Couldn't update password." });
10456
+ return;
10457
+ }
10458
+ onSuccess?.(result.redirect);
10459
+ } finally {
10460
+ setSubmitting(false);
10461
+ }
10462
+ }
10463
+ return /* @__PURE__ */ jsx("div", { className: cn("flex min-h-svh items-center justify-center p-6 sm:p-10", className), children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-6", children: [
10464
+ /* @__PURE__ */ jsxs("header", { className: "space-y-2 text-center", children: [
10465
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: "Set a new password" }),
10466
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Choose a strong password. You\u2019ll be signed in automatically once it\u2019s saved." })
10467
+ ] }),
10468
+ error ? /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
10469
+ /* @__PURE__ */ jsx(AlertTitle, { children: "Couldn\u2019t update password" }),
10470
+ /* @__PURE__ */ jsx(AlertDescription, { children: error.message })
10471
+ ] }) : null,
10472
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
10473
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
10474
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-reset-password", children: "New password" }),
10475
+ /* @__PURE__ */ jsx(
10476
+ Input,
10477
+ {
10478
+ id: "auth-reset-password",
10479
+ type: "password",
10480
+ autoComplete: "new-password",
10481
+ required: true,
10482
+ minLength: passwordMinLength,
10483
+ value: password,
10484
+ onChange: (e) => setPassword(e.target.value),
10485
+ disabled: submitting,
10486
+ "aria-describedby": "auth-reset-password-hint"
10487
+ }
10488
+ ),
10489
+ /* @__PURE__ */ jsxs(
10490
+ "p",
10491
+ {
10492
+ id: "auth-reset-password-hint",
10493
+ className: "text-xs text-muted-foreground",
10494
+ children: [
10495
+ "At least ",
10496
+ passwordMinLength,
10497
+ " characters."
10498
+ ]
10499
+ }
10500
+ )
10501
+ ] }),
10502
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
10503
+ /* @__PURE__ */ jsx(Label, { htmlFor: "auth-reset-confirm", children: "Confirm new password" }),
10504
+ /* @__PURE__ */ jsx(
10505
+ Input,
10506
+ {
10507
+ id: "auth-reset-confirm",
10508
+ type: "password",
10509
+ autoComplete: "new-password",
10510
+ required: true,
10511
+ value: confirmPassword,
10512
+ onChange: (e) => setConfirmPassword(e.target.value),
10513
+ disabled: submitting
10514
+ }
10515
+ )
10516
+ ] }),
10517
+ /* @__PURE__ */ jsx(
10518
+ Button,
10519
+ {
10520
+ type: "submit",
10521
+ className: "w-full",
10522
+ disabled: submitting,
10523
+ loading: submitting,
10524
+ children: submitting ? "Saving" : "Save new password"
10525
+ }
10526
+ )
10527
+ ] }),
10528
+ /* @__PURE__ */ jsx("p", { className: "text-center text-sm text-muted-foreground", children: /* @__PURE__ */ jsx(
10529
+ "a",
10530
+ {
10531
+ href: signInHref,
10532
+ className: "font-medium text-foreground underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded",
10533
+ children: "Back to sign in"
10534
+ }
10535
+ ) })
10536
+ ] }) });
10537
+ }
10538
+ var MailIcon2 = () => /* @__PURE__ */ jsxs(
10539
+ "svg",
10540
+ {
10541
+ xmlns: "http://www.w3.org/2000/svg",
10542
+ viewBox: "0 0 24 24",
10543
+ fill: "none",
10544
+ stroke: "currentColor",
10545
+ strokeWidth: 2,
10546
+ strokeLinecap: "round",
10547
+ strokeLinejoin: "round",
10548
+ "aria-hidden": "true",
10549
+ children: [
10550
+ /* @__PURE__ */ jsx("rect", { width: 20, height: 16, x: 2, y: 4, rx: 2 }),
10551
+ /* @__PURE__ */ jsx("path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" })
10552
+ ]
10553
+ }
10554
+ );
10555
+ function AuthVerifyEmail({
10556
+ adapter,
10557
+ email,
10558
+ resendCooldownSeconds = 30,
10559
+ signInHref = "/sign-in",
10560
+ className
10561
+ }) {
10562
+ const [resending, setResending] = React44.useState(false);
10563
+ const [cooldownLeft, setCooldownLeft] = React44.useState(0);
10564
+ const [error, setError] = React44.useState(null);
10565
+ const [confirmation, setConfirmation] = React44.useState(null);
10566
+ React44.useEffect(() => {
10567
+ if (cooldownLeft <= 0) return;
10568
+ const timer = setTimeout(() => setCooldownLeft((s) => s - 1), 1e3);
10569
+ return () => clearTimeout(timer);
10570
+ }, [cooldownLeft]);
10571
+ const canResend = Boolean(adapter.resendMagicLink) && Boolean(email);
10572
+ async function handleResend() {
10573
+ if (!email) return;
10574
+ if (!adapter.resendMagicLink) {
10575
+ console.warn(
10576
+ "[AuthVerifyEmail] adapter.resendMagicLink is not implemented \u2014 hide the resend button or wire the method."
10577
+ );
10578
+ setError({
10579
+ code: "unimplemented",
10580
+ message: "Resending is currently unavailable. Please try again later."
10581
+ });
10582
+ return;
10583
+ }
10584
+ setError(null);
10585
+ setConfirmation(null);
10586
+ setResending(true);
10587
+ try {
10588
+ const result = await adapter.resendMagicLink({ email });
10589
+ if (!result.ok) {
10590
+ setError(result.error ?? { code: "unknown", message: "Couldn't resend the link." });
10591
+ return;
10592
+ }
10593
+ setConfirmation("We sent another link. It may take a minute to arrive.");
10594
+ setCooldownLeft(resendCooldownSeconds);
10595
+ } finally {
10596
+ setResending(false);
10597
+ }
10598
+ }
10599
+ const description = email ? /* @__PURE__ */ jsxs(Fragment, { children: [
10600
+ "We sent a verification link to",
10601
+ " ",
10602
+ /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: email }),
10603
+ ". Click the link to activate your account. Links expire in 60 minutes."
10604
+ ] }) : /* @__PURE__ */ jsx(Fragment, { children: "Click the link in the verification email we just sent to activate your account. Links expire in 60 minutes." });
10605
+ const cooldownLabel = cooldownLeft > 0 ? `Resend available in ${cooldownLeft}s` : "Resend email";
10606
+ return /* @__PURE__ */ jsx("div", { className: cn("flex min-h-svh items-center justify-center p-6 sm:p-10", className), children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-4", children: [
10607
+ error ? /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
10608
+ /* @__PURE__ */ jsx(AlertTitle, { children: "Couldn\u2019t resend the link" }),
10609
+ /* @__PURE__ */ jsx(AlertDescription, { children: error.message })
10610
+ ] }) : null,
10611
+ confirmation ? (
10612
+ // `role="status"` + `aria-live="polite"` overrides the Alert
10613
+ // component's default `role="alert"` so the resend confirmation
10614
+ // is announced politely rather than interrupting the screen
10615
+ // reader (the action succeeded — it's not urgent).
10616
+ /* @__PURE__ */ jsxs(Alert, { role: "status", "aria-live": "polite", children: [
10617
+ /* @__PURE__ */ jsx(AlertTitle, { children: "Link resent" }),
10618
+ /* @__PURE__ */ jsx(AlertDescription, { children: confirmation })
10619
+ ] })
10620
+ ) : null,
10621
+ /* @__PURE__ */ jsx(
10622
+ Empty,
10623
+ {
10624
+ icon: /* @__PURE__ */ jsx(MailIcon2, {}),
10625
+ title: "Check your inbox",
10626
+ description,
10627
+ action: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-2", children: [
10628
+ canResend ? /* @__PURE__ */ jsx(
10629
+ Button,
10630
+ {
10631
+ type: "button",
10632
+ variant: "outline",
10633
+ onClick: handleResend,
10634
+ disabled: resending || cooldownLeft > 0,
10635
+ loading: resending,
10636
+ children: cooldownLabel
10637
+ }
10638
+ ) : null,
10639
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", asChild: true, children: /* @__PURE__ */ jsx("a", { href: signInHref, children: "Back to sign in" }) })
10640
+ ] })
10641
+ }
10642
+ )
10643
+ ] }) });
10644
+ }
10645
+ var HEADINGS = {
10646
+ "sign-in": {
10647
+ title: "Enter your sign-in code",
10648
+ description: "We sent a 6-digit code to your email or phone. Enter it below to sign in."
10649
+ },
10650
+ "verify-email": {
10651
+ title: "Verify your email",
10652
+ description: "Enter the 6-digit code we sent to confirm your email address."
10653
+ },
10654
+ mfa: {
10655
+ title: "Two-factor authentication",
10656
+ description: "Enter the 6-digit code from your authenticator app."
10657
+ }
10658
+ };
10659
+ function AuthVerifyOtp({
10660
+ adapter,
10661
+ intent,
10662
+ length = 6,
10663
+ resendCooldownSeconds = 30,
10664
+ className,
10665
+ onSuccess
10666
+ }) {
10667
+ const [code, setCode] = React44.useState("");
10668
+ const [submitting, setSubmitting] = React44.useState(false);
10669
+ const [resending, setResending] = React44.useState(false);
10670
+ const [cooldownLeft, setCooldownLeft] = React44.useState(0);
10671
+ const [error, setError] = React44.useState(null);
10672
+ const lastSubmittedRef = React44.useRef("");
10673
+ React44.useEffect(() => {
10674
+ if (cooldownLeft <= 0) return;
10675
+ const timer = setTimeout(() => setCooldownLeft((s) => s - 1), 1e3);
10676
+ return () => clearTimeout(timer);
10677
+ }, [cooldownLeft]);
10678
+ const handleSubmit = React44.useCallback(
10679
+ async (codeToSubmit) => {
10680
+ if (!adapter.verifyOtp) {
10681
+ console.warn(
10682
+ "[AuthVerifyOtp] adapter.verifyOtp is not implemented \u2014 wire it up before exposing the form."
10683
+ );
10684
+ setError({
10685
+ code: "unimplemented",
10686
+ message: "Verification is currently unavailable. Please try again later."
10687
+ });
10688
+ return;
10689
+ }
10690
+ setError(null);
10691
+ setSubmitting(true);
10692
+ try {
10693
+ const result = await adapter.verifyOtp({ code: codeToSubmit, intent });
10694
+ if (!result.ok) {
10695
+ setError(
10696
+ result.error ?? { code: "unknown", message: "Couldn't verify code." }
10697
+ );
10698
+ setCode("");
10699
+ lastSubmittedRef.current = "";
10700
+ return;
10701
+ }
10702
+ onSuccess?.(result.redirect);
10703
+ } finally {
10704
+ setSubmitting(false);
10705
+ }
10706
+ },
10707
+ [adapter, intent, onSuccess]
10708
+ );
10709
+ React44.useEffect(() => {
10710
+ if (code.length !== length) return;
10711
+ if (submitting) return;
10712
+ if (lastSubmittedRef.current === code) return;
10713
+ lastSubmittedRef.current = code;
10714
+ void handleSubmit(code);
10715
+ }, [code, length, submitting, handleSubmit]);
10716
+ async function handleResend() {
10717
+ if (!adapter.resendOtp) {
10718
+ console.warn(
10719
+ "[AuthVerifyOtp] adapter.resendOtp is not implemented \u2014 hide the resend button or wire the method."
10720
+ );
10721
+ setError({
10722
+ code: "unimplemented",
10723
+ message: "Resending is currently unavailable. Please try again later."
10724
+ });
10725
+ return;
10726
+ }
10727
+ setError(null);
10728
+ setResending(true);
10729
+ try {
10730
+ const result = await adapter.resendOtp({ intent });
10731
+ if (!result.ok) {
10732
+ setError(result.error ?? { code: "unknown", message: "Couldn't resend code." });
10733
+ return;
10734
+ }
10735
+ setCooldownLeft(resendCooldownSeconds);
10736
+ setCode("");
10737
+ } finally {
10738
+ setResending(false);
10739
+ }
10740
+ }
10741
+ const heading = HEADINGS[intent];
10742
+ const slots = React44.useMemo(
10743
+ () => Array.from({ length }, (_, i) => i),
10744
+ [length]
10745
+ );
10746
+ const cooldownLabel = cooldownLeft > 0 ? `Resend in ${cooldownLeft}s` : "Resend code";
10747
+ return /* @__PURE__ */ jsx("div", { className: cn("flex min-h-svh items-center justify-center p-6 sm:p-10", className), children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-6", children: [
10748
+ /* @__PURE__ */ jsxs("header", { className: "space-y-2 text-center", children: [
10749
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: heading.title }),
10750
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: heading.description })
10751
+ ] }),
10752
+ error ? /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
10753
+ /* @__PURE__ */ jsx(AlertTitle, { children: "Couldn\u2019t verify code" }),
10754
+ /* @__PURE__ */ jsx(AlertDescription, { children: error.message })
10755
+ ] }) : null,
10756
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
10757
+ /* @__PURE__ */ jsx(
10758
+ InputOTP,
10759
+ {
10760
+ maxLength: length,
10761
+ value: code,
10762
+ onChange: setCode,
10763
+ disabled: submitting,
10764
+ "aria-label": "One-time code",
10765
+ children: /* @__PURE__ */ jsx(InputOTPGroup, { children: slots.map((i) => /* @__PURE__ */ jsx(InputOTPSlot, { index: i }, i)) })
10766
+ }
10767
+ ),
10768
+ adapter.resendOtp ? /* @__PURE__ */ jsx(
10769
+ Button,
10770
+ {
10771
+ type: "button",
10772
+ variant: "ghost",
10773
+ size: "sm",
10774
+ onClick: handleResend,
10775
+ disabled: resending || cooldownLeft > 0 || submitting,
10776
+ loading: resending,
10777
+ children: cooldownLabel
10778
+ }
10779
+ ) : null
10780
+ ] })
10781
+ ] }) });
10782
+ }
10783
+
10784
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, Arc, AspectRatio, Attachment, AudioPlayer, AudioWaveform, AuthForgotPassword, AuthResetPassword, AuthSignInSplit, AuthSignUpCard, AuthVerifyEmail, AuthVerifyOtp, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Calendar, Canvas, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chord, Citation, Cloze, Cluster, CodeBlock, CodeBlockCopy2 as CodeBlockCopy, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ColorPicker, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CompareTable, Composer, Container, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuTrigger, DataTable, DatePicker, Deck, Dendrogram, Diagram, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuTrigger, Dropzone, Empty, ErrorState, FileTree, Flashcard, Flowchart, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Funnel, Gantt, Grid, HoverCard, HoverCardContent, HoverCardTrigger, ImageOcclusion, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label, Loading, LoadingIndicator, Markdown, Matrix, Menubar, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarSeparator, MenubarShortcut, MenubarTrigger, Message, MessageActions, MessageList, MindMap, MultiCombobox, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, OrgChart, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, Pyramid, Quiz, RadioGroup, RadioGroupItem, Reasoning, ResizableHandle, ResizablePanel, ResizablePanelGroup, Sankey, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Sequence, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarItem, SidebarProvider, SidebarTrigger, Skeleton, Slider, SpacedRepetition, Spacer, SpeechRecognition, Stack, Stepper, Suggestion, Sunburst, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, Terminal, Textarea, TimeAxis, TimePicker, Timeline, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolCall, Toolbar, ToolbarButton, ToolbarLink, ToolbarSeparator, ToolbarToggleGroup, ToolbarToggleItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Tree, TreeMap, Venn, alertVariants, attachmentVariants, badgeVariants, buttonVariants, clusterVariants, cn, containerVariants, emptyVariants, errorStateVariants, formatHslTriplet, gridVariants, hexToHslTriplet, hslToRgb, hslTripletToHex, loadingIndicatorVariants, loadingVariants, messageVariants, mockAuthAdapter, navigationMenuTriggerStyle, parseHslTriplet, rgbToHsl, spacerVariants, stackVariants, tagVariants, toggleVariants, toolbarVariants, useFormField, useSidebar };
9757
10785
  //# sourceMappingURL=index.js.map
9758
10786
  //# sourceMappingURL=index.js.map