@insforge/react 0.2.10 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -32
- package/dist/atoms.d.mts +23 -2
- package/dist/atoms.d.ts +23 -2
- package/dist/atoms.js +138 -0
- package/dist/atoms.js.map +1 -1
- package/dist/atoms.mjs +139 -2
- package/dist/atoms.mjs.map +1 -1
- package/dist/components.d.mts +120 -3
- package/dist/components.d.ts +120 -3
- package/dist/components.js +993 -393
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +991 -395
- package/dist/components.mjs.map +1 -1
- package/dist/forms.d.mts +2 -2
- package/dist/forms.d.ts +2 -2
- package/dist/forms.js +318 -71
- package/dist/forms.js.map +1 -1
- package/dist/forms.mjs +319 -72
- package/dist/forms.mjs.map +1 -1
- package/dist/hooks.d.mts +4 -0
- package/dist/hooks.d.ts +4 -0
- package/dist/hooks.js.map +1 -1
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.d.mts +6 -11
- package/dist/index.d.ts +6 -11
- package/dist/index.js +986 -472
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +983 -473
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types.d.mts +12 -1
- package/dist/types.d.ts +12 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
|
|
5
5
|
if (!document.getElementById(styleId)) {
|
|
6
6
|
const style = document.createElement('style');
|
|
7
7
|
style.id = styleId;
|
|
8
|
-
style.textContent = "/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n@import \"https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap\";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-content:\"\"}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-green-100:oklch(96.2% .044 156.743);--color-green-400:oklch(79.2% .209 151.711);--color-green-600:oklch(62.7% .194 149.214);--color-green-900:oklch(39.3% .095 152.535);--color-blue-50:oklch(97% .014 254.604);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-900:oklch(37.9% .146 265.522);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-800:oklch(43.8% .218 303.724);--color-purple-900:oklch(38.1% .176 304.987);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-normal:1.5;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-manrope:\"Manrope\",sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.relative{position:relative}.top-1\\/2{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-16{height:calc(var(--spacing)*16)}.h-\\[18px\\]{height:18px}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-10{width:calc(var(--spacing)*10)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-\\[18px\\]{width:18px}.w-full{width:100%}.max-w-\\[400px\\]{max-width:400px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.min-w-40{min-width:calc(var(--spacing)*40)}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.self-stretch{align-self:stretch}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-none{--tw-border-style:none;border-style:none}.border-\\[\\#D4D4D4\\]{border-color:#d4d4d4}.border-\\[\\#E0E0E0\\]{border-color:#e0e0e0}.border-\\[\\#E4E4E7\\]{border-color:#e4e4e7}.border-black{border-color:var(--color-black)}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-600{border-color:var(--color-blue-600)}.border-gray-200{border-color:var(--color-gray-200)}.border-neutral-400{border-color:var(--color-neutral-400)}.border-purple-300{border-color:var(--color-purple-300)}.border-red-600{border-color:var(--color-red-600)}.border-transparent{border-color:#0000}.bg-\\[\\#059669\\]{background-color:#059669}.bg-\\[\\#FAFAFA\\]{background-color:#fafafa}.bg-black{background-color:var(--color-black)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-purple-600{background-color:var(--color-purple-600)}.bg-red-50{background-color:var(--color-red-50)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-50{--tw-gradient-from:var(--color-blue-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-6{padding:calc(var(--spacing)*6)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pl-3{padding-left:calc(var(--spacing)*3)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-manrope{font-family:var(--font-manrope)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-4{--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4)}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-6{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}.leading-8{--tw-leading:calc(var(--spacing)*8);line-height:calc(var(--spacing)*8)}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-\\[\\#09090B\\]{color:#09090b}.text-\\[\\#525252\\]{color:#525252}.text-\\[\\#737373\\]{color:#737373}.text-\\[\\#828282\\]{color:#828282}.text-\\[\\#A3A3A3\\]{color:#a3a3a3}.text-\\[\\#A6A6A6\\]{color:#a6a6a6}.text-black{color:var(--color-black)}.text-blue-500{color:var(--color-blue-500)}.text-blue-900{color:var(--color-blue-900)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-600{color:var(--color-green-600)}.text-neutral-600{color:var(--color-neutral-600)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-purple-900{color:var(--color-purple-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_1px_2px_0_rgba\\(0\\,0\\,0\\,0\\.10\\)\\]{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.placeholder\\:font-normal::placeholder{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.placeholder\\:text-\\[\\#A3A3A3\\]::placeholder{color:#a3a3a3}.before\\:h-px:before{content:var(--tw-content);height:1px}.before\\:flex-1:before{content:var(--tw-content);flex:1}.before\\:bg-\\[\\#E5E5E5\\]:before{content:var(--tw-content);background-color:#e5e5e5}.before\\:content-\\[\\'\\'\\]:before{--tw-content:\"\";content:var(--tw-content)}.after\\:h-px:after{content:var(--tw-content);height:1px}.after\\:flex-1:after{content:var(--tw-content);flex:1}.after\\:bg-\\[\\#E5E5E5\\]:after{content:var(--tw-content);background-color:#e5e5e5}.after\\:content-\\[\\'\\'\\]:after{--tw-content:\"\";content:var(--tw-content)}@media (hover:hover){.hover\\:border-\\[\\#9ca3af\\]:hover{border-color:#9ca3af}.hover\\:bg-\\[\\#f9fafb\\]:hover{background-color:#f9fafb}.hover\\:bg-black\\/5:hover{background-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-black\\/5:hover{background-color:color-mix(in oklab,var(--color-black)5%,transparent)}}.hover\\:bg-blue-50:hover{background-color:var(--color-blue-50)}.hover\\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\\:bg-purple-700:hover{background-color:var(--color-purple-700)}.hover\\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\\:bg-white\\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-white\\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\\:text-gray-600:hover{color:var(--color-gray-600)}.hover\\:text-purple-800:hover{color:var(--color-purple-800)}}.focus\\:border-black:focus{border-color:var(--color-black)}.focus\\:border-purple-500:focus{border-color:var(--color-purple-500)}.focus\\:shadow-\\[0_0_0_2px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]:focus{--tw-shadow:0 0 0 2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:bg-\\[\\#F5F5F5\\]:disabled{background-color:#f5f5f5}.disabled\\:opacity-50:disabled{opacity:.5}.disabled\\:opacity-60:disabled{opacity:.6}@media (prefers-color-scheme:dark){.dark\\:border-white{border-color:var(--color-white)}.dark\\:bg-green-900{background-color:var(--color-green-900)}.dark\\:text-gray-400{color:var(--color-gray-400)}.dark\\:text-green-400{color:var(--color-green-400)}.dark\\:text-neutral-400{color:var(--color-neutral-400)}.dark\\:text-white{color:var(--color-white)}}}@property --tw-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-z{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:\"*\";inherits:false}@property --tw-gradient-from{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:\"*\";inherits:false}@property --tw-gradient-via-stops{syntax:\"*\";inherits:false}@property --tw-gradient-from-position{syntax:\"<length-percentage>\";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:\"<length-percentage>\";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:\"<length-percentage>\";inherits:false;initial-value:100%}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-content{syntax:\"*\";inherits:false;initial-value:\"\"}@keyframes spin{to{transform:rotate(360deg)}}";
|
|
8
|
+
style.textContent = "/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n@import \"https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap\";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-content:\"\"}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-green-100:oklch(96.2% .044 156.743);--color-green-400:oklch(79.2% .209 151.711);--color-green-600:oklch(62.7% .194 149.214);--color-green-900:oklch(39.3% .095 152.535);--color-blue-50:oklch(97% .014 254.604);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-900:oklch(37.9% .146 265.522);--color-indigo-50:oklch(96.2% .018 272.314);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-800:oklch(43.8% .218 303.724);--color-purple-900:oklch(38.1% .176 304.987);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-neutral-100:oklch(97% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-normal:1.5;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-manrope:\"Manrope\",sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.relative{position:relative}.top-1\\/2{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-16{height:calc(var(--spacing)*16)}.h-\\[18px\\]{height:18px}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-10{width:calc(var(--spacing)*10)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-\\[18px\\]{width:18px}.w-full{width:100%}.max-w-\\[400px\\]{max-width:400px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.min-w-40{min-width:calc(var(--spacing)*40)}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.self-stretch{align-self:stretch}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-none{--tw-border-style:none;border-style:none}.border-\\[\\#D4D4D4\\]{border-color:#d4d4d4}.border-\\[\\#E0E0E0\\]{border-color:#e0e0e0}.border-\\[\\#E4E4E7\\]{border-color:#e4e4e7}.border-black{border-color:var(--color-black)}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-600{border-color:var(--color-blue-600)}.border-gray-200{border-color:var(--color-gray-200)}.border-neutral-400{border-color:var(--color-neutral-400)}.border-purple-300{border-color:var(--color-purple-300)}.border-red-600{border-color:var(--color-red-600)}.border-transparent{border-color:#0000}.bg-\\[\\#059669\\]{background-color:#059669}.bg-\\[\\#FAFAFA\\]{background-color:#fafafa}.bg-black{background-color:var(--color-black)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-purple-600{background-color:var(--color-purple-600)}.bg-red-50{background-color:var(--color-red-50)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-50{--tw-gradient-from:var(--color-blue-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-indigo-50{--tw-gradient-from:var(--color-indigo-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-6{padding:calc(var(--spacing)*6)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pb-6{padding-bottom:calc(var(--spacing)*6)}.pl-3{padding-left:calc(var(--spacing)*3)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-manrope{font-family:var(--font-manrope)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-4{--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4)}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-6{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}.leading-8{--tw-leading:calc(var(--spacing)*8);line-height:calc(var(--spacing)*8)}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-\\[\\#09090B\\]{color:#09090b}.text-\\[\\#525252\\]{color:#525252}.text-\\[\\#737373\\]{color:#737373}.text-\\[\\#828282\\]{color:#828282}.text-\\[\\#A3A3A3\\]{color:#a3a3a3}.text-\\[\\#A6A6A6\\]{color:#a6a6a6}.text-black{color:var(--color-black)}.text-blue-500{color:var(--color-blue-500)}.text-blue-900{color:var(--color-blue-900)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-600{color:var(--color-green-600)}.text-neutral-600{color:var(--color-neutral-600)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-purple-900{color:var(--color-purple-900)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_1px_2px_0_rgba\\(0\\,0\\,0\\,0\\.10\\)\\]{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.placeholder\\:font-normal::placeholder{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.placeholder\\:text-\\[\\#A3A3A3\\]::placeholder{color:#a3a3a3}.before\\:h-px:before{content:var(--tw-content);height:1px}.before\\:flex-1:before{content:var(--tw-content);flex:1}.before\\:bg-\\[\\#E5E5E5\\]:before{content:var(--tw-content);background-color:#e5e5e5}.before\\:content-\\[\\'\\'\\]:before{--tw-content:\"\";content:var(--tw-content)}.after\\:h-px:after{content:var(--tw-content);height:1px}.after\\:flex-1:after{content:var(--tw-content);flex:1}.after\\:bg-\\[\\#E5E5E5\\]:after{content:var(--tw-content);background-color:#e5e5e5}.after\\:content-\\[\\'\\'\\]:after{--tw-content:\"\";content:var(--tw-content)}@media (hover:hover){.hover\\:border-\\[\\#9ca3af\\]:hover{border-color:#9ca3af}.hover\\:bg-\\[\\#f9fafb\\]:hover{background-color:#f9fafb}.hover\\:bg-black\\/5:hover{background-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-black\\/5:hover{background-color:color-mix(in oklab,var(--color-black)5%,transparent)}}.hover\\:bg-blue-50:hover{background-color:var(--color-blue-50)}.hover\\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\\:bg-indigo-700:hover{background-color:var(--color-indigo-700)}.hover\\:bg-purple-700:hover{background-color:var(--color-purple-700)}.hover\\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\\:bg-white\\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-white\\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\\:text-gray-600:hover{color:var(--color-gray-600)}.hover\\:text-purple-800:hover{color:var(--color-purple-800)}.hover\\:underline:hover{text-decoration-line:underline}}.focus\\:border-black:focus{border-color:var(--color-black)}.focus\\:border-purple-500:focus{border-color:var(--color-purple-500)}.focus\\:shadow-\\[0_0_0_2px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]:focus{--tw-shadow:0 0 0 2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:bg-\\[\\#F5F5F5\\]:disabled{background-color:#f5f5f5}.disabled\\:no-underline:disabled{text-decoration-line:none}.disabled\\:opacity-50:disabled{opacity:.5}.disabled\\:opacity-60:disabled{opacity:.6}@media (prefers-color-scheme:dark){.dark\\:border-white{border-color:var(--color-white)}.dark\\:bg-green-900{background-color:var(--color-green-900)}.dark\\:bg-neutral-800{background-color:var(--color-neutral-800)}.dark\\:text-gray-400{color:var(--color-gray-400)}.dark\\:text-green-400{color:var(--color-green-400)}.dark\\:text-neutral-400{color:var(--color-neutral-400)}.dark\\:text-white{color:var(--color-white)}}}@property --tw-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-translate-z{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:\"*\";inherits:false}@property --tw-gradient-from{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:\"<color>\";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:\"*\";inherits:false}@property --tw-gradient-via-stops{syntax:\"*\";inherits:false}@property --tw-gradient-from-position{syntax:\"<length-percentage>\";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:\"<length-percentage>\";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:\"<length-percentage>\";inherits:false;initial-value:100%}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-content{syntax:\"*\";inherits:false;initial-value:\"\"}@keyframes spin{to{transform:rotate(360deg)}}";
|
|
9
9
|
if (document.head) {
|
|
10
10
|
document.head.appendChild(style);
|
|
11
11
|
}
|
|
@@ -158,70 +158,6 @@ function InsforgeProvider({
|
|
|
158
158
|
},
|
|
159
159
|
[insforge, onAuthChange, syncTokenToCookie]
|
|
160
160
|
);
|
|
161
|
-
const handleAuthCallback = useCallback(
|
|
162
|
-
async (params) => {
|
|
163
|
-
try {
|
|
164
|
-
await insforge.auth.setSession({
|
|
165
|
-
accessToken: params.accessToken,
|
|
166
|
-
user: {
|
|
167
|
-
id: params.userId || "",
|
|
168
|
-
email: params.email || "",
|
|
169
|
-
name: params.name || "",
|
|
170
|
-
emailVerified: false,
|
|
171
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
172
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
const userResult = await insforge.auth.getCurrentUser();
|
|
176
|
-
if (!userResult.data) {
|
|
177
|
-
await insforge.auth.signOut();
|
|
178
|
-
if (clearCookie) {
|
|
179
|
-
try {
|
|
180
|
-
await clearCookie();
|
|
181
|
-
} catch (error) {
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return { success: false, error: "invalid_token" };
|
|
185
|
-
}
|
|
186
|
-
const profile = userResult.data.profile;
|
|
187
|
-
const userData = {
|
|
188
|
-
id: userResult.data.user.id,
|
|
189
|
-
email: userResult.data.user.email,
|
|
190
|
-
name: profile?.nickname || params.name || "",
|
|
191
|
-
avatarUrl: profile?.avatarUrl || ""
|
|
192
|
-
};
|
|
193
|
-
setUser(userData);
|
|
194
|
-
if (onAuthChange) {
|
|
195
|
-
onAuthChange(userData);
|
|
196
|
-
}
|
|
197
|
-
if (syncTokenToCookie) {
|
|
198
|
-
try {
|
|
199
|
-
await syncTokenToCookie(params.accessToken);
|
|
200
|
-
} catch (error) {
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return { success: true };
|
|
204
|
-
} catch (error) {
|
|
205
|
-
console.error("[InsforgeProvider] Auth callback failed:", error);
|
|
206
|
-
await insforge.auth.signOut();
|
|
207
|
-
if (clearCookie) {
|
|
208
|
-
try {
|
|
209
|
-
await clearCookie();
|
|
210
|
-
} catch (error2) {
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
setUser(null);
|
|
214
|
-
if (onAuthChange) {
|
|
215
|
-
onAuthChange(null);
|
|
216
|
-
}
|
|
217
|
-
return {
|
|
218
|
-
success: false,
|
|
219
|
-
error: error instanceof Error ? error.message : "authentication_failed"
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
[insforge, onAuthChange, syncTokenToCookie, clearCookie]
|
|
224
|
-
);
|
|
225
161
|
const signIn = useCallback(
|
|
226
162
|
async (email, password) => {
|
|
227
163
|
const sdkResult = await insforge.auth.signInWithPassword({
|
|
@@ -239,8 +175,11 @@ function InsforgeProvider({
|
|
|
239
175
|
);
|
|
240
176
|
return sdkResult.data;
|
|
241
177
|
} else {
|
|
242
|
-
|
|
243
|
-
|
|
178
|
+
return {
|
|
179
|
+
error: sdkResult.error?.message || "Invalid email or password",
|
|
180
|
+
statusCode: sdkResult.error?.statusCode,
|
|
181
|
+
errorCode: sdkResult.error?.error
|
|
182
|
+
};
|
|
244
183
|
}
|
|
245
184
|
},
|
|
246
185
|
[insforge, handleAuthSuccess]
|
|
@@ -249,18 +188,23 @@ function InsforgeProvider({
|
|
|
249
188
|
async (email, password) => {
|
|
250
189
|
const sdkResult = await insforge.auth.signUp({ email, password });
|
|
251
190
|
if (sdkResult.data) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
191
|
+
if (sdkResult.data.accessToken) {
|
|
192
|
+
await handleAuthSuccess(
|
|
193
|
+
sdkResult.data.accessToken,
|
|
194
|
+
sdkResult.data.user ? {
|
|
195
|
+
id: sdkResult.data.user.id,
|
|
196
|
+
email: sdkResult.data.user.email,
|
|
197
|
+
name: sdkResult.data.user.name
|
|
198
|
+
} : void 0
|
|
199
|
+
);
|
|
200
|
+
}
|
|
260
201
|
return sdkResult.data;
|
|
261
202
|
} else {
|
|
262
|
-
|
|
263
|
-
|
|
203
|
+
return {
|
|
204
|
+
error: sdkResult.error?.message || "Sign up failed",
|
|
205
|
+
statusCode: sdkResult.error?.statusCode,
|
|
206
|
+
errorCode: sdkResult.error?.error
|
|
207
|
+
};
|
|
264
208
|
}
|
|
265
209
|
},
|
|
266
210
|
[insforge, handleAuthSuccess]
|
|
@@ -345,7 +289,6 @@ function InsforgeProvider({
|
|
|
345
289
|
signOut,
|
|
346
290
|
updateUser,
|
|
347
291
|
reloadAuth: loadAuthState,
|
|
348
|
-
handleAuthCallback,
|
|
349
292
|
baseUrl,
|
|
350
293
|
sendPasswordResetCode,
|
|
351
294
|
resetPassword,
|
|
@@ -1034,6 +977,7 @@ function AuthVerificationCodeInput({
|
|
|
1034
977
|
email,
|
|
1035
978
|
onChange,
|
|
1036
979
|
disabled = false,
|
|
980
|
+
onComplete,
|
|
1037
981
|
appearance = {}
|
|
1038
982
|
}) {
|
|
1039
983
|
const inputRefs = useRef([]);
|
|
@@ -1047,6 +991,9 @@ function AuthVerificationCodeInput({
|
|
|
1047
991
|
if (digit && index < length - 1) {
|
|
1048
992
|
inputRefs.current[index + 1]?.focus();
|
|
1049
993
|
}
|
|
994
|
+
if (digit && index === length - 1 && updatedValue.length === length && onComplete) {
|
|
995
|
+
onComplete(updatedValue);
|
|
996
|
+
}
|
|
1050
997
|
};
|
|
1051
998
|
const handleKeyDown = (index, e) => {
|
|
1052
999
|
if (e.key === "Backspace") {
|
|
@@ -1067,6 +1014,9 @@ function AuthVerificationCodeInput({
|
|
|
1067
1014
|
if (/^\d+$/.test(pastedData) && pastedData.length === length) {
|
|
1068
1015
|
onChange(pastedData);
|
|
1069
1016
|
inputRefs.current[length - 1]?.focus();
|
|
1017
|
+
if (onComplete) {
|
|
1018
|
+
onComplete(pastedData);
|
|
1019
|
+
}
|
|
1070
1020
|
}
|
|
1071
1021
|
};
|
|
1072
1022
|
return /* @__PURE__ */ jsxs("div", { className: cn(
|
|
@@ -1107,6 +1057,125 @@ function AuthVerificationCodeInput({
|
|
|
1107
1057
|
)) })
|
|
1108
1058
|
] });
|
|
1109
1059
|
}
|
|
1060
|
+
function AuthEmailVerificationStep({
|
|
1061
|
+
email,
|
|
1062
|
+
description,
|
|
1063
|
+
method = "code",
|
|
1064
|
+
onVerifyCode
|
|
1065
|
+
}) {
|
|
1066
|
+
const { baseUrl } = useInsforge();
|
|
1067
|
+
const [insforge] = useState(() => createClient({ baseUrl }));
|
|
1068
|
+
const [resendDisabled, setResendDisabled] = useState(true);
|
|
1069
|
+
const [resendCountdown, setResendCountdown] = useState(60);
|
|
1070
|
+
const [isSending, setIsSending] = useState(false);
|
|
1071
|
+
const [verificationCode, setVerificationCode] = useState("");
|
|
1072
|
+
const [isVerifying, setIsVerifying] = useState(false);
|
|
1073
|
+
const [verificationError, setVerificationError] = useState("");
|
|
1074
|
+
const defaultDescription = method === "code" ? "We've sent a 6-digit verification code to {email}. Please enter it below to verify your account. The code will expire in 10 minutes." : "We've sent a verification link to {email}. Please check your email and click the link to verify your account. The link will expire in 10 minutes.";
|
|
1075
|
+
useEffect(() => {
|
|
1076
|
+
const sendInitialEmail = async () => {
|
|
1077
|
+
try {
|
|
1078
|
+
if (method === "code") {
|
|
1079
|
+
await insforge.auth.sendVerificationCode({ email });
|
|
1080
|
+
} else {
|
|
1081
|
+
await insforge.auth.sendVerificationLink({ email });
|
|
1082
|
+
}
|
|
1083
|
+
} catch {
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
void sendInitialEmail();
|
|
1087
|
+
}, [email, method, insforge.auth]);
|
|
1088
|
+
useEffect(() => {
|
|
1089
|
+
if (resendCountdown > 0) {
|
|
1090
|
+
const timer = setInterval(() => {
|
|
1091
|
+
setResendCountdown((prev) => {
|
|
1092
|
+
if (prev <= 1) {
|
|
1093
|
+
setResendDisabled(false);
|
|
1094
|
+
return 0;
|
|
1095
|
+
}
|
|
1096
|
+
return prev - 1;
|
|
1097
|
+
});
|
|
1098
|
+
}, 1e3);
|
|
1099
|
+
return () => clearInterval(timer);
|
|
1100
|
+
}
|
|
1101
|
+
}, [resendCountdown]);
|
|
1102
|
+
const handleResend = async () => {
|
|
1103
|
+
setResendDisabled(true);
|
|
1104
|
+
setResendCountdown(60);
|
|
1105
|
+
setIsSending(true);
|
|
1106
|
+
setVerificationError("");
|
|
1107
|
+
try {
|
|
1108
|
+
if (method === "code") {
|
|
1109
|
+
await insforge.auth.sendVerificationCode({ email });
|
|
1110
|
+
} else {
|
|
1111
|
+
await insforge.auth.sendVerificationLink({ email });
|
|
1112
|
+
}
|
|
1113
|
+
} catch {
|
|
1114
|
+
setResendDisabled(false);
|
|
1115
|
+
setResendCountdown(0);
|
|
1116
|
+
} finally {
|
|
1117
|
+
setIsSending(false);
|
|
1118
|
+
}
|
|
1119
|
+
};
|
|
1120
|
+
const handleVerifyCode = async (code) => {
|
|
1121
|
+
if (!onVerifyCode) {
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
setIsVerifying(true);
|
|
1125
|
+
setVerificationError("");
|
|
1126
|
+
try {
|
|
1127
|
+
await onVerifyCode(code);
|
|
1128
|
+
} catch (error) {
|
|
1129
|
+
setVerificationError(
|
|
1130
|
+
error instanceof Error ? error.message : "Invalid verification code. Please try again."
|
|
1131
|
+
);
|
|
1132
|
+
setVerificationCode("");
|
|
1133
|
+
} finally {
|
|
1134
|
+
setIsVerifying(false);
|
|
1135
|
+
}
|
|
1136
|
+
};
|
|
1137
|
+
const displayDescription = description || defaultDescription;
|
|
1138
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6 items-stretch", children: [
|
|
1139
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 leading-relaxed", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxs("span", { children: [
|
|
1140
|
+
part,
|
|
1141
|
+
index < array.length - 1 && /* @__PURE__ */ jsx("span", { className: "font-medium text-black dark:text-white", children: email })
|
|
1142
|
+
] }, index)) }),
|
|
1143
|
+
verificationError && /* @__PURE__ */ jsx("div", { className: "pl-3 py-2 pr-2 bg-red-50 border-2 border-red-600 rounded", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1144
|
+
/* @__PURE__ */ jsx("svg", { className: "w-6 h-6 text-red-500 shrink-0", fill: "none", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
|
|
1145
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-red-600 flex-1", children: verificationError })
|
|
1146
|
+
] }) }),
|
|
1147
|
+
method === "code" && /* @__PURE__ */ jsxs("div", { className: "w-full bg-neutral-100 dark:bg-neutral-800 rounded-lg px-4 pt-4 pb-6 flex flex-col gap-4", children: [
|
|
1148
|
+
/* @__PURE__ */ jsx(
|
|
1149
|
+
AuthVerificationCodeInput,
|
|
1150
|
+
{
|
|
1151
|
+
value: verificationCode,
|
|
1152
|
+
onChange: setVerificationCode,
|
|
1153
|
+
email,
|
|
1154
|
+
disabled: isVerifying,
|
|
1155
|
+
onComplete: (code) => {
|
|
1156
|
+
void handleVerifyCode(code);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
),
|
|
1160
|
+
isVerifying && /* @__PURE__ */ jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: "Verifying..." })
|
|
1161
|
+
] }),
|
|
1162
|
+
/* @__PURE__ */ jsxs("div", { className: "w-full text-sm text-center text-neutral-600 dark:text-neutral-400", children: [
|
|
1163
|
+
"Didn't receive the email?",
|
|
1164
|
+
" ",
|
|
1165
|
+
/* @__PURE__ */ jsx(
|
|
1166
|
+
"button",
|
|
1167
|
+
{
|
|
1168
|
+
onClick: () => {
|
|
1169
|
+
void handleResend();
|
|
1170
|
+
},
|
|
1171
|
+
disabled: resendDisabled || isSending,
|
|
1172
|
+
className: "text-black dark:text-white font-medium transition-colors disabled:cursor-not-allowed cursor-pointer hover:underline disabled:no-underline disabled:opacity-50",
|
|
1173
|
+
children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
|
|
1174
|
+
}
|
|
1175
|
+
)
|
|
1176
|
+
] })
|
|
1177
|
+
] });
|
|
1178
|
+
}
|
|
1110
1179
|
function SignInForm({
|
|
1111
1180
|
email,
|
|
1112
1181
|
password,
|
|
@@ -1133,7 +1202,11 @@ function SignInForm({
|
|
|
1133
1202
|
signUpText = "Don't have an account?",
|
|
1134
1203
|
signUpLinkText = "Sign Up Now",
|
|
1135
1204
|
signUpUrl = "/sign-up",
|
|
1136
|
-
dividerText = "or"
|
|
1205
|
+
dividerText = "or",
|
|
1206
|
+
// Email verification step props
|
|
1207
|
+
showVerificationStep = false,
|
|
1208
|
+
onVerifyCode,
|
|
1209
|
+
verificationDescription
|
|
1137
1210
|
}) {
|
|
1138
1211
|
return /* @__PURE__ */ jsxs(
|
|
1139
1212
|
AuthContainer,
|
|
@@ -1146,8 +1219,8 @@ function SignInForm({
|
|
|
1146
1219
|
/* @__PURE__ */ jsx(
|
|
1147
1220
|
AuthHeader,
|
|
1148
1221
|
{
|
|
1149
|
-
title,
|
|
1150
|
-
subtitle,
|
|
1222
|
+
title: showVerificationStep ? "Verify Your Email" : title,
|
|
1223
|
+
subtitle: showVerificationStep ? "" : subtitle,
|
|
1151
1224
|
appearance: {
|
|
1152
1225
|
containerClassName: appearance.header?.container,
|
|
1153
1226
|
titleClassName: appearance.header?.title,
|
|
@@ -1162,7 +1235,14 @@ function SignInForm({
|
|
|
1162
1235
|
className: appearance.errorBanner
|
|
1163
1236
|
}
|
|
1164
1237
|
),
|
|
1165
|
-
/* @__PURE__ */
|
|
1238
|
+
showVerificationStep ? /* @__PURE__ */ jsx(
|
|
1239
|
+
AuthEmailVerificationStep,
|
|
1240
|
+
{
|
|
1241
|
+
email,
|
|
1242
|
+
description: verificationDescription,
|
|
1243
|
+
onVerifyCode
|
|
1244
|
+
}
|
|
1245
|
+
) : /* @__PURE__ */ jsxs(
|
|
1166
1246
|
"form",
|
|
1167
1247
|
{
|
|
1168
1248
|
onSubmit,
|
|
@@ -1221,39 +1301,41 @@ function SignInForm({
|
|
|
1221
1301
|
]
|
|
1222
1302
|
}
|
|
1223
1303
|
),
|
|
1224
|
-
/* @__PURE__ */
|
|
1225
|
-
AuthLink,
|
|
1226
|
-
{
|
|
1227
|
-
text: signUpText,
|
|
1228
|
-
linkText: signUpLinkText,
|
|
1229
|
-
href: signUpUrl,
|
|
1230
|
-
appearance: {
|
|
1231
|
-
containerClassName: appearance.link?.container,
|
|
1232
|
-
linkClassName: appearance.link?.link
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
),
|
|
1236
|
-
availableProviders.length > 0 && onOAuthClick && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1237
|
-
/* @__PURE__ */ jsx(
|
|
1238
|
-
AuthDivider,
|
|
1239
|
-
{
|
|
1240
|
-
text: dividerText,
|
|
1241
|
-
className: appearance.divider
|
|
1242
|
-
}
|
|
1243
|
-
),
|
|
1304
|
+
!showVerificationStep && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1244
1305
|
/* @__PURE__ */ jsx(
|
|
1245
|
-
|
|
1306
|
+
AuthLink,
|
|
1246
1307
|
{
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
loading: oauthLoading,
|
|
1308
|
+
text: signUpText,
|
|
1309
|
+
linkText: signUpLinkText,
|
|
1310
|
+
href: signUpUrl,
|
|
1251
1311
|
appearance: {
|
|
1252
|
-
containerClassName: appearance.
|
|
1253
|
-
|
|
1312
|
+
containerClassName: appearance.link?.container,
|
|
1313
|
+
linkClassName: appearance.link?.link
|
|
1254
1314
|
}
|
|
1255
1315
|
}
|
|
1256
|
-
)
|
|
1316
|
+
),
|
|
1317
|
+
availableProviders.length > 0 && onOAuthClick && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1318
|
+
/* @__PURE__ */ jsx(
|
|
1319
|
+
AuthDivider,
|
|
1320
|
+
{
|
|
1321
|
+
text: dividerText,
|
|
1322
|
+
className: appearance.divider
|
|
1323
|
+
}
|
|
1324
|
+
),
|
|
1325
|
+
/* @__PURE__ */ jsx(
|
|
1326
|
+
AuthOAuthProviders,
|
|
1327
|
+
{
|
|
1328
|
+
providers: availableProviders,
|
|
1329
|
+
onClick: onOAuthClick,
|
|
1330
|
+
disabled: loading || oauthLoading !== null,
|
|
1331
|
+
loading: oauthLoading,
|
|
1332
|
+
appearance: {
|
|
1333
|
+
containerClassName: appearance.oauth?.container,
|
|
1334
|
+
buttonClassName: appearance.oauth?.button
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
)
|
|
1338
|
+
] })
|
|
1257
1339
|
] })
|
|
1258
1340
|
]
|
|
1259
1341
|
}
|
|
@@ -1271,6 +1353,7 @@ function SignIn({
|
|
|
1271
1353
|
const [password, setPassword] = useState("");
|
|
1272
1354
|
const [error, setError] = useState("");
|
|
1273
1355
|
const [loading, setLoading] = useState(false);
|
|
1356
|
+
const [step, setStep] = useState("form");
|
|
1274
1357
|
const [oauthLoading, setOauthLoading] = useState(
|
|
1275
1358
|
null
|
|
1276
1359
|
);
|
|
@@ -1282,6 +1365,11 @@ function SignIn({
|
|
|
1282
1365
|
try {
|
|
1283
1366
|
const result = await signIn(email, password);
|
|
1284
1367
|
if ("error" in result) {
|
|
1368
|
+
if (result.statusCode === 403) {
|
|
1369
|
+
setStep("awaiting-verification");
|
|
1370
|
+
setLoading(false);
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1285
1373
|
throw new Error(result.error);
|
|
1286
1374
|
}
|
|
1287
1375
|
const { user, accessToken } = result;
|
|
@@ -1296,6 +1384,21 @@ function SignIn({
|
|
|
1296
1384
|
setLoading(false);
|
|
1297
1385
|
}
|
|
1298
1386
|
}
|
|
1387
|
+
async function handleVerifyCode(code) {
|
|
1388
|
+
try {
|
|
1389
|
+
const result = await insforge.auth.verifyEmail({ email, otp: code });
|
|
1390
|
+
if (result.error) {
|
|
1391
|
+
throw new Error(result.error.message || "Verification failed");
|
|
1392
|
+
}
|
|
1393
|
+
if (result.data?.accessToken) {
|
|
1394
|
+
if (onSuccess && result.data.user) {
|
|
1395
|
+
onSuccess(result.data.user, result.data.accessToken);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
} catch (err) {
|
|
1399
|
+
throw new Error(err.message || "Invalid verification code");
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1299
1402
|
async function handleOAuth(provider) {
|
|
1300
1403
|
try {
|
|
1301
1404
|
setOauthLoading(provider);
|
|
@@ -1328,6 +1431,8 @@ function SignIn({
|
|
|
1328
1431
|
availableProviders: emailConfig?.oAuthProviders || [],
|
|
1329
1432
|
onOAuthClick: handleOAuth,
|
|
1330
1433
|
emailAuthConfig: emailConfig,
|
|
1434
|
+
showVerificationStep: step === "awaiting-verification",
|
|
1435
|
+
onVerifyCode: handleVerifyCode,
|
|
1331
1436
|
...uiProps
|
|
1332
1437
|
}
|
|
1333
1438
|
);
|
|
@@ -1356,7 +1461,11 @@ function SignUpForm({
|
|
|
1356
1461
|
signInText = "Already have an account?",
|
|
1357
1462
|
signInLinkText = "Login Now",
|
|
1358
1463
|
signInUrl = "/sign-in",
|
|
1359
|
-
dividerText = "or"
|
|
1464
|
+
dividerText = "or",
|
|
1465
|
+
// Email verification step props
|
|
1466
|
+
showVerificationStep = false,
|
|
1467
|
+
onVerifyCode,
|
|
1468
|
+
verificationDescription
|
|
1360
1469
|
}) {
|
|
1361
1470
|
return /* @__PURE__ */ jsxs(
|
|
1362
1471
|
AuthContainer,
|
|
@@ -1369,8 +1478,8 @@ function SignUpForm({
|
|
|
1369
1478
|
/* @__PURE__ */ jsx(
|
|
1370
1479
|
AuthHeader,
|
|
1371
1480
|
{
|
|
1372
|
-
title,
|
|
1373
|
-
subtitle,
|
|
1481
|
+
title: showVerificationStep ? "Verify Your Email" : title,
|
|
1482
|
+
subtitle: showVerificationStep ? "" : subtitle,
|
|
1374
1483
|
appearance: {
|
|
1375
1484
|
containerClassName: appearance.header?.container,
|
|
1376
1485
|
titleClassName: appearance.header?.title,
|
|
@@ -1385,7 +1494,14 @@ function SignUpForm({
|
|
|
1385
1494
|
className: appearance.errorBanner
|
|
1386
1495
|
}
|
|
1387
1496
|
),
|
|
1388
|
-
/* @__PURE__ */
|
|
1497
|
+
showVerificationStep ? /* @__PURE__ */ jsx(
|
|
1498
|
+
AuthEmailVerificationStep,
|
|
1499
|
+
{
|
|
1500
|
+
email,
|
|
1501
|
+
description: verificationDescription,
|
|
1502
|
+
onVerifyCode
|
|
1503
|
+
}
|
|
1504
|
+
) : /* @__PURE__ */ jsxs(
|
|
1389
1505
|
"form",
|
|
1390
1506
|
{
|
|
1391
1507
|
onSubmit,
|
|
@@ -1442,44 +1558,117 @@ function SignUpForm({
|
|
|
1442
1558
|
]
|
|
1443
1559
|
}
|
|
1444
1560
|
),
|
|
1445
|
-
/* @__PURE__ */
|
|
1446
|
-
AuthLink,
|
|
1447
|
-
{
|
|
1448
|
-
text: signInText,
|
|
1449
|
-
linkText: signInLinkText,
|
|
1450
|
-
href: signInUrl,
|
|
1451
|
-
appearance: {
|
|
1452
|
-
containerClassName: appearance.link?.container,
|
|
1453
|
-
linkClassName: appearance.link?.link
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
),
|
|
1457
|
-
availableProviders.length > 0 && onOAuthClick && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1561
|
+
!showVerificationStep && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1458
1562
|
/* @__PURE__ */ jsx(
|
|
1459
|
-
|
|
1563
|
+
AuthLink,
|
|
1460
1564
|
{
|
|
1461
|
-
text:
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
),
|
|
1465
|
-
/* @__PURE__ */ jsx(
|
|
1466
|
-
AuthOAuthProviders,
|
|
1467
|
-
{
|
|
1468
|
-
providers: availableProviders,
|
|
1469
|
-
onClick: onOAuthClick,
|
|
1470
|
-
disabled: loading || oauthLoading !== null,
|
|
1471
|
-
loading: oauthLoading,
|
|
1565
|
+
text: signInText,
|
|
1566
|
+
linkText: signInLinkText,
|
|
1567
|
+
href: signInUrl,
|
|
1472
1568
|
appearance: {
|
|
1473
|
-
containerClassName: appearance.
|
|
1474
|
-
|
|
1569
|
+
containerClassName: appearance.link?.container,
|
|
1570
|
+
linkClassName: appearance.link?.link
|
|
1475
1571
|
}
|
|
1476
1572
|
}
|
|
1477
|
-
)
|
|
1573
|
+
),
|
|
1574
|
+
availableProviders.length > 0 && onOAuthClick && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1575
|
+
/* @__PURE__ */ jsx(
|
|
1576
|
+
AuthDivider,
|
|
1577
|
+
{
|
|
1578
|
+
text: dividerText,
|
|
1579
|
+
className: appearance.divider
|
|
1580
|
+
}
|
|
1581
|
+
),
|
|
1582
|
+
/* @__PURE__ */ jsx(
|
|
1583
|
+
AuthOAuthProviders,
|
|
1584
|
+
{
|
|
1585
|
+
providers: availableProviders,
|
|
1586
|
+
onClick: onOAuthClick,
|
|
1587
|
+
disabled: loading || oauthLoading !== null,
|
|
1588
|
+
loading: oauthLoading,
|
|
1589
|
+
appearance: {
|
|
1590
|
+
containerClassName: appearance.oauth?.container,
|
|
1591
|
+
buttonClassName: appearance.oauth?.button
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
)
|
|
1595
|
+
] })
|
|
1478
1596
|
] })
|
|
1479
1597
|
]
|
|
1480
1598
|
}
|
|
1481
1599
|
);
|
|
1482
1600
|
}
|
|
1601
|
+
var emailSchema = z.string().min(1, "Email is required").email("Invalid email address");
|
|
1602
|
+
function createPasswordSchema(options) {
|
|
1603
|
+
const {
|
|
1604
|
+
minLength = 6,
|
|
1605
|
+
requireUppercase = false,
|
|
1606
|
+
requireLowercase = false,
|
|
1607
|
+
requireNumber = false,
|
|
1608
|
+
requireSpecialChar = false
|
|
1609
|
+
} = options || {};
|
|
1610
|
+
let schema = z.string().min(minLength, `Password must be at least ${minLength} characters`);
|
|
1611
|
+
if (requireUppercase) {
|
|
1612
|
+
schema = schema.regex(/[A-Z]/, "Password must contain at least one uppercase letter");
|
|
1613
|
+
}
|
|
1614
|
+
if (requireLowercase) {
|
|
1615
|
+
schema = schema.regex(/[a-z]/, "Password must contain at least one lowercase letter");
|
|
1616
|
+
}
|
|
1617
|
+
if (requireNumber) {
|
|
1618
|
+
schema = schema.regex(/\d/, "Password must contain at least one number");
|
|
1619
|
+
}
|
|
1620
|
+
if (requireSpecialChar) {
|
|
1621
|
+
schema = schema.regex(
|
|
1622
|
+
/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
|
|
1623
|
+
"Password must contain at least one special character"
|
|
1624
|
+
);
|
|
1625
|
+
}
|
|
1626
|
+
return schema;
|
|
1627
|
+
}
|
|
1628
|
+
var passwordSchema = createPasswordSchema();
|
|
1629
|
+
function validateEmail(email) {
|
|
1630
|
+
const result = emailSchema.safeParse(email);
|
|
1631
|
+
if (result.success) {
|
|
1632
|
+
return { valid: true };
|
|
1633
|
+
}
|
|
1634
|
+
return { valid: false, error: result.error.message };
|
|
1635
|
+
}
|
|
1636
|
+
function validatePassword(password, options) {
|
|
1637
|
+
const schema = createPasswordSchema(options);
|
|
1638
|
+
const result = schema.safeParse(password);
|
|
1639
|
+
if (result.success) {
|
|
1640
|
+
return { valid: true };
|
|
1641
|
+
}
|
|
1642
|
+
return { valid: false, error: result.error.message };
|
|
1643
|
+
}
|
|
1644
|
+
function checkPasswordStrength(password) {
|
|
1645
|
+
const feedback = [];
|
|
1646
|
+
let score = 0;
|
|
1647
|
+
if (password.length >= 8) {
|
|
1648
|
+
score += 1;
|
|
1649
|
+
} else {
|
|
1650
|
+
feedback.push("Use at least 8 characters");
|
|
1651
|
+
}
|
|
1652
|
+
if (password.length >= 12) {
|
|
1653
|
+
score += 1;
|
|
1654
|
+
}
|
|
1655
|
+
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {
|
|
1656
|
+
score += 1;
|
|
1657
|
+
} else {
|
|
1658
|
+
feedback.push("Use both uppercase and lowercase letters");
|
|
1659
|
+
}
|
|
1660
|
+
if (/\d/.test(password)) {
|
|
1661
|
+
score += 1;
|
|
1662
|
+
} else {
|
|
1663
|
+
feedback.push("Include at least one number");
|
|
1664
|
+
}
|
|
1665
|
+
if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
|
|
1666
|
+
score += 1;
|
|
1667
|
+
} else {
|
|
1668
|
+
feedback.push("Include at least one special character");
|
|
1669
|
+
}
|
|
1670
|
+
return { score, feedback };
|
|
1671
|
+
}
|
|
1483
1672
|
function SignUp({
|
|
1484
1673
|
afterSignUpUrl,
|
|
1485
1674
|
onSuccess,
|
|
@@ -1492,6 +1681,7 @@ function SignUp({
|
|
|
1492
1681
|
const [password, setPassword] = useState("");
|
|
1493
1682
|
const [error, setError] = useState("");
|
|
1494
1683
|
const [loading, setLoading] = useState(false);
|
|
1684
|
+
const [step, setStep] = useState("form");
|
|
1495
1685
|
const [oauthLoading, setOauthLoading] = useState(
|
|
1496
1686
|
null
|
|
1497
1687
|
);
|
|
@@ -1500,19 +1690,46 @@ function SignUp({
|
|
|
1500
1690
|
e.preventDefault();
|
|
1501
1691
|
setLoading(true);
|
|
1502
1692
|
setError("");
|
|
1503
|
-
if (
|
|
1504
|
-
setError("
|
|
1693
|
+
if (!emailConfig) {
|
|
1694
|
+
setError("Configuration not loaded. Please refresh the page.");
|
|
1695
|
+
setLoading(false);
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
const emailValidation = emailSchema.safeParse(email);
|
|
1699
|
+
if (!emailValidation.success) {
|
|
1700
|
+
const firstError = emailValidation.error.issues[0];
|
|
1701
|
+
setError(firstError.message);
|
|
1702
|
+
setLoading(false);
|
|
1703
|
+
return;
|
|
1704
|
+
}
|
|
1705
|
+
const passwordZodSchema = createPasswordSchema({
|
|
1706
|
+
minLength: emailConfig.passwordMinLength,
|
|
1707
|
+
requireUppercase: emailConfig.requireUppercase,
|
|
1708
|
+
requireLowercase: emailConfig.requireLowercase,
|
|
1709
|
+
requireNumber: emailConfig.requireNumber,
|
|
1710
|
+
requireSpecialChar: emailConfig.requireSpecialChar
|
|
1711
|
+
});
|
|
1712
|
+
const passwordValidation = passwordZodSchema.safeParse(password);
|
|
1713
|
+
if (!passwordValidation.success) {
|
|
1714
|
+
const firstError = passwordValidation.error.issues[0];
|
|
1715
|
+
setError(firstError.message);
|
|
1505
1716
|
setLoading(false);
|
|
1506
1717
|
return;
|
|
1507
1718
|
}
|
|
1508
1719
|
try {
|
|
1509
|
-
const result = await signUp(
|
|
1720
|
+
const result = await signUp(emailValidation.data, password);
|
|
1510
1721
|
if ("error" in result) {
|
|
1511
1722
|
throw new Error(result.error);
|
|
1512
1723
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1724
|
+
if (result.requiresEmailVerification && !result.accessToken) {
|
|
1725
|
+
setStep("awaiting-verification");
|
|
1726
|
+
setLoading(false);
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
if (result.accessToken && result.user) {
|
|
1730
|
+
if (onSuccess) {
|
|
1731
|
+
onSuccess(result.user, result.accessToken);
|
|
1732
|
+
}
|
|
1516
1733
|
}
|
|
1517
1734
|
} catch (err) {
|
|
1518
1735
|
const errorMessage = err.message || "Sign up failed";
|
|
@@ -1522,6 +1739,21 @@ function SignUp({
|
|
|
1522
1739
|
setLoading(false);
|
|
1523
1740
|
}
|
|
1524
1741
|
}
|
|
1742
|
+
async function handleVerifyCode(code) {
|
|
1743
|
+
try {
|
|
1744
|
+
const result = await insforge.auth.verifyEmail({ email, otp: code });
|
|
1745
|
+
if (result.error) {
|
|
1746
|
+
throw new Error(result.error.message || "Verification failed");
|
|
1747
|
+
}
|
|
1748
|
+
if (result.data?.accessToken) {
|
|
1749
|
+
if (onSuccess && result.data.user) {
|
|
1750
|
+
onSuccess(result.data.user, result.data.accessToken);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
} catch (err) {
|
|
1754
|
+
throw new Error(err.message || "Invalid verification code");
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1525
1757
|
async function handleOAuth(provider) {
|
|
1526
1758
|
try {
|
|
1527
1759
|
setOauthLoading(provider);
|
|
@@ -1554,247 +1786,12 @@ function SignUp({
|
|
|
1554
1786
|
availableProviders: emailConfig?.oAuthProviders || [],
|
|
1555
1787
|
onOAuthClick: handleOAuth,
|
|
1556
1788
|
emailAuthConfig: emailConfig,
|
|
1789
|
+
showVerificationStep: step === "awaiting-verification",
|
|
1790
|
+
onVerifyCode: handleVerifyCode,
|
|
1557
1791
|
...uiProps
|
|
1558
1792
|
}
|
|
1559
1793
|
);
|
|
1560
1794
|
}
|
|
1561
|
-
function UserButton({
|
|
1562
|
-
afterSignOutUrl = "/",
|
|
1563
|
-
mode = "detailed",
|
|
1564
|
-
appearance = {}
|
|
1565
|
-
}) {
|
|
1566
|
-
const { user, signOut } = useInsforge();
|
|
1567
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
1568
|
-
const [imageError, setImageError] = useState(false);
|
|
1569
|
-
const dropdownRef = useRef(null);
|
|
1570
|
-
useEffect(() => {
|
|
1571
|
-
setImageError(false);
|
|
1572
|
-
const avatarUrl = user?.avatarUrl;
|
|
1573
|
-
if (!avatarUrl) return;
|
|
1574
|
-
const checkImageUrl = async () => {
|
|
1575
|
-
try {
|
|
1576
|
-
const response = await fetch(avatarUrl, {
|
|
1577
|
-
method: "HEAD",
|
|
1578
|
-
cache: "no-cache"
|
|
1579
|
-
});
|
|
1580
|
-
if (!response.ok) {
|
|
1581
|
-
setImageError(true);
|
|
1582
|
-
}
|
|
1583
|
-
} catch (error) {
|
|
1584
|
-
setImageError(true);
|
|
1585
|
-
}
|
|
1586
|
-
};
|
|
1587
|
-
checkImageUrl();
|
|
1588
|
-
}, [user?.avatarUrl]);
|
|
1589
|
-
useEffect(() => {
|
|
1590
|
-
function handleClickOutside(event) {
|
|
1591
|
-
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
1592
|
-
setIsOpen(false);
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
if (isOpen) {
|
|
1596
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
1597
|
-
}
|
|
1598
|
-
return () => {
|
|
1599
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
1600
|
-
};
|
|
1601
|
-
}, [isOpen]);
|
|
1602
|
-
async function handleSignOut() {
|
|
1603
|
-
await signOut();
|
|
1604
|
-
setIsOpen(false);
|
|
1605
|
-
window.location.href = afterSignOutUrl;
|
|
1606
|
-
}
|
|
1607
|
-
if (!user) return null;
|
|
1608
|
-
const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
|
|
1609
|
-
return /* @__PURE__ */ jsxs(
|
|
1610
|
-
"div",
|
|
1611
|
-
{
|
|
1612
|
-
className: cn("relative inline-block", appearance.containerClassName),
|
|
1613
|
-
ref: dropdownRef,
|
|
1614
|
-
children: [
|
|
1615
|
-
/* @__PURE__ */ jsxs(
|
|
1616
|
-
"button",
|
|
1617
|
-
{
|
|
1618
|
-
className: cn(
|
|
1619
|
-
"p-1 bg-transparent border-0 rounded-full cursor-pointer transition-all duration-200",
|
|
1620
|
-
"flex items-center justify-center gap-2",
|
|
1621
|
-
"hover:bg-black/5",
|
|
1622
|
-
mode === "detailed" && "rounded-lg p-2",
|
|
1623
|
-
appearance.buttonClassName
|
|
1624
|
-
),
|
|
1625
|
-
onClick: () => setIsOpen(!isOpen),
|
|
1626
|
-
"aria-expanded": isOpen,
|
|
1627
|
-
"aria-haspopup": "true",
|
|
1628
|
-
children: [
|
|
1629
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-10 h-10 bg-blue-500 rounded-full", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
|
|
1630
|
-
"img",
|
|
1631
|
-
{
|
|
1632
|
-
src: user.avatarUrl,
|
|
1633
|
-
alt: user.email,
|
|
1634
|
-
onError: () => setImageError(true),
|
|
1635
|
-
className: "rounded-full object-cover w-full h-full"
|
|
1636
|
-
}
|
|
1637
|
-
) : /* @__PURE__ */ jsx("span", { className: "text-white font-semibold text-sm", children: initials }) }),
|
|
1638
|
-
mode === "detailed" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-0.5", children: [
|
|
1639
|
-
user.name && /* @__PURE__ */ jsx(
|
|
1640
|
-
"div",
|
|
1641
|
-
{
|
|
1642
|
-
className: cn(
|
|
1643
|
-
"text-sm font-semibold text-gray-900 leading-5 text-left",
|
|
1644
|
-
appearance.nameClassName
|
|
1645
|
-
),
|
|
1646
|
-
children: user.name
|
|
1647
|
-
}
|
|
1648
|
-
),
|
|
1649
|
-
/* @__PURE__ */ jsx(
|
|
1650
|
-
"div",
|
|
1651
|
-
{
|
|
1652
|
-
className: cn(
|
|
1653
|
-
"text-xs text-gray-500 leading-4 text-left",
|
|
1654
|
-
appearance.emailClassName
|
|
1655
|
-
),
|
|
1656
|
-
children: user.email
|
|
1657
|
-
}
|
|
1658
|
-
)
|
|
1659
|
-
] })
|
|
1660
|
-
]
|
|
1661
|
-
}
|
|
1662
|
-
),
|
|
1663
|
-
isOpen && /* @__PURE__ */ jsx(
|
|
1664
|
-
"div",
|
|
1665
|
-
{
|
|
1666
|
-
className: cn(
|
|
1667
|
-
"absolute top-full right-0 mt-2 min-w-40",
|
|
1668
|
-
"bg-white border border-gray-200 rounded-lg",
|
|
1669
|
-
"shadow-lg z-50 overflow-hidden p-1",
|
|
1670
|
-
appearance.dropdownClassName
|
|
1671
|
-
),
|
|
1672
|
-
children: /* @__PURE__ */ jsxs(
|
|
1673
|
-
"button",
|
|
1674
|
-
{
|
|
1675
|
-
onClick: handleSignOut,
|
|
1676
|
-
className: "flex items-center justify-start gap-2 w-full px-3 py-2 text-sm font-normal text-red-600 bg-transparent border-0 rounded-md cursor-pointer transition-colors hover:bg-red-50 text-left",
|
|
1677
|
-
children: [
|
|
1678
|
-
/* @__PURE__ */ jsx(LogOut, { className: "w-5 h-5" }),
|
|
1679
|
-
"Sign out"
|
|
1680
|
-
]
|
|
1681
|
-
}
|
|
1682
|
-
)
|
|
1683
|
-
}
|
|
1684
|
-
)
|
|
1685
|
-
]
|
|
1686
|
-
}
|
|
1687
|
-
);
|
|
1688
|
-
}
|
|
1689
|
-
function Protect({
|
|
1690
|
-
children,
|
|
1691
|
-
fallback,
|
|
1692
|
-
redirectTo = "/sign-in",
|
|
1693
|
-
condition,
|
|
1694
|
-
onRedirect
|
|
1695
|
-
}) {
|
|
1696
|
-
const { isSignedIn, isLoaded, user } = useInsforge();
|
|
1697
|
-
useEffect(() => {
|
|
1698
|
-
if (isLoaded && !isSignedIn) {
|
|
1699
|
-
if (onRedirect) {
|
|
1700
|
-
onRedirect(redirectTo);
|
|
1701
|
-
} else {
|
|
1702
|
-
window.location.href = redirectTo;
|
|
1703
|
-
}
|
|
1704
|
-
} else if (isLoaded && isSignedIn && condition && user) {
|
|
1705
|
-
if (!condition(user)) {
|
|
1706
|
-
if (onRedirect) {
|
|
1707
|
-
onRedirect(redirectTo);
|
|
1708
|
-
} else {
|
|
1709
|
-
window.location.href = redirectTo;
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
}, [isLoaded, isSignedIn, redirectTo, condition, user, onRedirect]);
|
|
1714
|
-
if (!isLoaded) {
|
|
1715
|
-
return fallback || /* @__PURE__ */ jsx("div", { className: "insforge-loading", children: "Loading..." });
|
|
1716
|
-
}
|
|
1717
|
-
if (!isSignedIn) {
|
|
1718
|
-
return fallback || null;
|
|
1719
|
-
}
|
|
1720
|
-
if (condition && user && !condition(user)) {
|
|
1721
|
-
return fallback || null;
|
|
1722
|
-
}
|
|
1723
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1724
|
-
}
|
|
1725
|
-
function SignedIn({ children }) {
|
|
1726
|
-
const { isSignedIn, isLoaded } = useInsforge();
|
|
1727
|
-
if (!isLoaded) return null;
|
|
1728
|
-
if (!isSignedIn) return null;
|
|
1729
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1730
|
-
}
|
|
1731
|
-
function SignedOut({ children }) {
|
|
1732
|
-
const { isSignedIn, isLoaded } = useInsforge();
|
|
1733
|
-
if (!isLoaded) return null;
|
|
1734
|
-
if (isSignedIn) return null;
|
|
1735
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1736
|
-
}
|
|
1737
|
-
function InsforgeCallback({
|
|
1738
|
-
redirectTo = "/",
|
|
1739
|
-
onSuccess,
|
|
1740
|
-
onError,
|
|
1741
|
-
loadingComponent,
|
|
1742
|
-
onRedirect
|
|
1743
|
-
}) {
|
|
1744
|
-
const isProcessingRef = useRef(false);
|
|
1745
|
-
const { isLoaded, isSignedIn } = useInsforge();
|
|
1746
|
-
useEffect(() => {
|
|
1747
|
-
if (!isLoaded) return;
|
|
1748
|
-
if (isProcessingRef.current) return;
|
|
1749
|
-
isProcessingRef.current = true;
|
|
1750
|
-
const processCallback = async () => {
|
|
1751
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
1752
|
-
const error = searchParams.get("error");
|
|
1753
|
-
if (error) {
|
|
1754
|
-
if (onError) {
|
|
1755
|
-
onError(error);
|
|
1756
|
-
} else {
|
|
1757
|
-
const errorUrl = "/?error=" + encodeURIComponent(error);
|
|
1758
|
-
if (onRedirect) {
|
|
1759
|
-
onRedirect(errorUrl);
|
|
1760
|
-
} else {
|
|
1761
|
-
window.location.href = errorUrl;
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
return;
|
|
1765
|
-
}
|
|
1766
|
-
if (!isSignedIn) {
|
|
1767
|
-
const errorMsg = "authentication_failed";
|
|
1768
|
-
if (onError) {
|
|
1769
|
-
onError(errorMsg);
|
|
1770
|
-
} else {
|
|
1771
|
-
const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
|
|
1772
|
-
if (onRedirect) {
|
|
1773
|
-
onRedirect(errorUrl);
|
|
1774
|
-
} else {
|
|
1775
|
-
window.location.href = errorUrl;
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
return;
|
|
1779
|
-
}
|
|
1780
|
-
window.history.replaceState({}, "", window.location.pathname);
|
|
1781
|
-
if (onSuccess) {
|
|
1782
|
-
onSuccess();
|
|
1783
|
-
}
|
|
1784
|
-
if (onRedirect) {
|
|
1785
|
-
onRedirect(redirectTo);
|
|
1786
|
-
} else {
|
|
1787
|
-
window.location.href = redirectTo;
|
|
1788
|
-
}
|
|
1789
|
-
};
|
|
1790
|
-
processCallback();
|
|
1791
|
-
}, [isLoaded, isSignedIn, redirectTo, onSuccess, onError, onRedirect]);
|
|
1792
|
-
const defaultLoading = /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1793
|
-
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold mb-4", children: "Completing authentication..." }),
|
|
1794
|
-
/* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto" })
|
|
1795
|
-
] }) });
|
|
1796
|
-
return loadingComponent || defaultLoading;
|
|
1797
|
-
}
|
|
1798
1795
|
function ForgotPasswordForm({
|
|
1799
1796
|
email,
|
|
1800
1797
|
onEmailChange,
|
|
@@ -2015,27 +2012,323 @@ function ResetPasswordForm({
|
|
|
2015
2012
|
]
|
|
2016
2013
|
}
|
|
2017
2014
|
),
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2015
|
+
/* @__PURE__ */ jsx(
|
|
2016
|
+
AuthLink,
|
|
2017
|
+
{
|
|
2018
|
+
text: backToSignInText,
|
|
2019
|
+
linkText: "Back to Sign In",
|
|
2020
|
+
href: backToSignInUrl,
|
|
2021
|
+
appearance: {
|
|
2022
|
+
containerClassName: appearance.link?.container,
|
|
2023
|
+
linkClassName: appearance.link?.link
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
)
|
|
2025
2027
|
]
|
|
2026
2028
|
}
|
|
2027
2029
|
);
|
|
2028
2030
|
}
|
|
2029
|
-
function
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
|
|
2036
|
-
errorTitle = "Verification Failed"
|
|
2031
|
+
function ResetPassword({
|
|
2032
|
+
token,
|
|
2033
|
+
backToSignInUrl = "/sign-in",
|
|
2034
|
+
onSuccess,
|
|
2035
|
+
onError,
|
|
2036
|
+
...uiProps
|
|
2037
2037
|
}) {
|
|
2038
|
-
|
|
2038
|
+
const { resetPassword } = useInsforge();
|
|
2039
|
+
const { emailConfig } = usePublicAuthConfig();
|
|
2040
|
+
const [newPassword, setNewPassword] = useState("");
|
|
2041
|
+
const [confirmPassword, setConfirmPassword] = useState("");
|
|
2042
|
+
const [error, setError] = useState("");
|
|
2043
|
+
const [loading, setLoading] = useState(false);
|
|
2044
|
+
async function handleSubmit(e) {
|
|
2045
|
+
e.preventDefault();
|
|
2046
|
+
setLoading(true);
|
|
2047
|
+
setError("");
|
|
2048
|
+
if (!emailConfig) {
|
|
2049
|
+
setError("Configuration not loaded. Please refresh the page.");
|
|
2050
|
+
setLoading(false);
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
if (newPassword !== confirmPassword) {
|
|
2054
|
+
setError("Passwords do not match");
|
|
2055
|
+
setLoading(false);
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
2058
|
+
if (!token) {
|
|
2059
|
+
setError("Reset token is missing");
|
|
2060
|
+
setLoading(false);
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
const passwordZodSchema = createPasswordSchema({
|
|
2064
|
+
minLength: emailConfig.passwordMinLength,
|
|
2065
|
+
requireUppercase: emailConfig.requireUppercase,
|
|
2066
|
+
requireLowercase: emailConfig.requireLowercase,
|
|
2067
|
+
requireNumber: emailConfig.requireNumber,
|
|
2068
|
+
requireSpecialChar: emailConfig.requireSpecialChar
|
|
2069
|
+
});
|
|
2070
|
+
const passwordValidation = passwordZodSchema.safeParse(newPassword);
|
|
2071
|
+
if (!passwordValidation.success) {
|
|
2072
|
+
const firstError = passwordValidation.error.issues[0];
|
|
2073
|
+
setError(firstError.message);
|
|
2074
|
+
setLoading(false);
|
|
2075
|
+
return;
|
|
2076
|
+
}
|
|
2077
|
+
try {
|
|
2078
|
+
const result = await resetPassword(token, newPassword);
|
|
2079
|
+
if (result?.message) {
|
|
2080
|
+
if (onSuccess) {
|
|
2081
|
+
onSuccess(result.redirectTo);
|
|
2082
|
+
}
|
|
2083
|
+
} else {
|
|
2084
|
+
const errorMessage = "Failed to reset password";
|
|
2085
|
+
setError(errorMessage);
|
|
2086
|
+
if (onError) {
|
|
2087
|
+
onError(new Error(errorMessage));
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
} catch (err) {
|
|
2091
|
+
const errorMessage = err.message || "Failed to reset password";
|
|
2092
|
+
setError(errorMessage);
|
|
2093
|
+
if (onError) {
|
|
2094
|
+
onError(new Error(errorMessage));
|
|
2095
|
+
}
|
|
2096
|
+
} finally {
|
|
2097
|
+
setLoading(false);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
if (!emailConfig) {
|
|
2101
|
+
return null;
|
|
2102
|
+
}
|
|
2103
|
+
return /* @__PURE__ */ jsx(
|
|
2104
|
+
ResetPasswordForm,
|
|
2105
|
+
{
|
|
2106
|
+
newPassword,
|
|
2107
|
+
confirmPassword,
|
|
2108
|
+
onNewPasswordChange: setNewPassword,
|
|
2109
|
+
onConfirmPasswordChange: setConfirmPassword,
|
|
2110
|
+
onSubmit: handleSubmit,
|
|
2111
|
+
error,
|
|
2112
|
+
loading,
|
|
2113
|
+
emailAuthConfig: emailConfig,
|
|
2114
|
+
backToSignInUrl,
|
|
2115
|
+
...uiProps
|
|
2116
|
+
}
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
function ForgotPassword({
|
|
2120
|
+
backToSignInUrl = "/sign-in",
|
|
2121
|
+
onSuccess,
|
|
2122
|
+
onError,
|
|
2123
|
+
...uiProps
|
|
2124
|
+
}) {
|
|
2125
|
+
const { sendPasswordResetCode, baseUrl } = useInsforge();
|
|
2126
|
+
const { emailConfig } = usePublicAuthConfig();
|
|
2127
|
+
const [insforge] = useState(() => createClient({ baseUrl }));
|
|
2128
|
+
const [step, setStep] = useState("email");
|
|
2129
|
+
const [email, setEmail] = useState("");
|
|
2130
|
+
const [verificationCode, setVerificationCode] = useState("");
|
|
2131
|
+
const [resetToken, setResetToken] = useState("");
|
|
2132
|
+
const [error, setError] = useState("");
|
|
2133
|
+
const [loading, setLoading] = useState(false);
|
|
2134
|
+
const [success, setSuccess] = useState(false);
|
|
2135
|
+
const [resendDisabled, setResendDisabled] = useState(true);
|
|
2136
|
+
const [resendCountdown, setResendCountdown] = useState(60);
|
|
2137
|
+
const [isSendingCode, setIsSendingCode] = useState(false);
|
|
2138
|
+
const [isVerifyingCode, setIsVerifyingCode] = useState(false);
|
|
2139
|
+
useEffect(() => {
|
|
2140
|
+
if (resendCountdown > 0 && step === "code") {
|
|
2141
|
+
const timer = setInterval(() => {
|
|
2142
|
+
setResendCountdown((prev) => {
|
|
2143
|
+
if (prev <= 1) {
|
|
2144
|
+
setResendDisabled(false);
|
|
2145
|
+
return 0;
|
|
2146
|
+
}
|
|
2147
|
+
return prev - 1;
|
|
2148
|
+
});
|
|
2149
|
+
}, 1e3);
|
|
2150
|
+
return () => clearInterval(timer);
|
|
2151
|
+
}
|
|
2152
|
+
}, [resendCountdown, step]);
|
|
2153
|
+
async function handleEmailSubmit(e) {
|
|
2154
|
+
e.preventDefault();
|
|
2155
|
+
setLoading(true);
|
|
2156
|
+
setError("");
|
|
2157
|
+
const emailValidation = emailSchema.safeParse(email);
|
|
2158
|
+
if (!emailValidation.success) {
|
|
2159
|
+
const firstError = emailValidation.error.issues[0];
|
|
2160
|
+
setError(firstError.message);
|
|
2161
|
+
setLoading(false);
|
|
2162
|
+
return;
|
|
2163
|
+
}
|
|
2164
|
+
try {
|
|
2165
|
+
const result = await sendPasswordResetCode(emailValidation.data);
|
|
2166
|
+
if (result?.success) {
|
|
2167
|
+
if (emailConfig?.resetPasswordMethod === "link") {
|
|
2168
|
+
setSuccess(true);
|
|
2169
|
+
if (onSuccess) {
|
|
2170
|
+
onSuccess();
|
|
2171
|
+
}
|
|
2172
|
+
} else {
|
|
2173
|
+
setStep("code");
|
|
2174
|
+
setResendDisabled(true);
|
|
2175
|
+
setResendCountdown(60);
|
|
2176
|
+
}
|
|
2177
|
+
} else {
|
|
2178
|
+
const errorMessage = result?.message || "Failed to send reset code";
|
|
2179
|
+
setError(errorMessage);
|
|
2180
|
+
if (onError) {
|
|
2181
|
+
onError(new Error(errorMessage));
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
} catch (err) {
|
|
2185
|
+
const errorMessage = err.message || "Failed to send reset code";
|
|
2186
|
+
setError(errorMessage);
|
|
2187
|
+
if (onError) {
|
|
2188
|
+
onError(new Error(errorMessage));
|
|
2189
|
+
}
|
|
2190
|
+
} finally {
|
|
2191
|
+
setLoading(false);
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
async function handleVerifyCode(code) {
|
|
2195
|
+
setIsVerifyingCode(true);
|
|
2196
|
+
setError("");
|
|
2197
|
+
setVerificationCode(code);
|
|
2198
|
+
try {
|
|
2199
|
+
const result = await insforge.auth.verifyResetPasswordCode({ email, code });
|
|
2200
|
+
if (result.error) {
|
|
2201
|
+
throw new Error(result.error.message || "Failed to verify code");
|
|
2202
|
+
}
|
|
2203
|
+
if (result.data) {
|
|
2204
|
+
setResetToken(result.data.resetToken);
|
|
2205
|
+
setStep("password");
|
|
2206
|
+
}
|
|
2207
|
+
} catch (err) {
|
|
2208
|
+
setError(err.message || "Invalid verification code");
|
|
2209
|
+
setVerificationCode("");
|
|
2210
|
+
} finally {
|
|
2211
|
+
setIsVerifyingCode(false);
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
const handleResendCode = useCallback(async () => {
|
|
2215
|
+
setResendDisabled(true);
|
|
2216
|
+
setResendCountdown(60);
|
|
2217
|
+
setIsSendingCode(true);
|
|
2218
|
+
setError("");
|
|
2219
|
+
try {
|
|
2220
|
+
await sendPasswordResetCode(email);
|
|
2221
|
+
} catch (err) {
|
|
2222
|
+
setError(err.message || "Failed to resend code");
|
|
2223
|
+
setResendDisabled(false);
|
|
2224
|
+
setResendCountdown(0);
|
|
2225
|
+
} finally {
|
|
2226
|
+
setIsSendingCode(false);
|
|
2227
|
+
}
|
|
2228
|
+
}, [email, sendPasswordResetCode]);
|
|
2229
|
+
function handlePasswordResetSuccess() {
|
|
2230
|
+
if (onSuccess) {
|
|
2231
|
+
onSuccess();
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
if (!emailConfig) {
|
|
2235
|
+
return null;
|
|
2236
|
+
}
|
|
2237
|
+
if (step === "email") {
|
|
2238
|
+
return /* @__PURE__ */ jsx(
|
|
2239
|
+
ForgotPasswordForm,
|
|
2240
|
+
{
|
|
2241
|
+
email,
|
|
2242
|
+
onEmailChange: setEmail,
|
|
2243
|
+
onSubmit: handleEmailSubmit,
|
|
2244
|
+
error,
|
|
2245
|
+
loading,
|
|
2246
|
+
success,
|
|
2247
|
+
backToSignInUrl,
|
|
2248
|
+
...uiProps
|
|
2249
|
+
}
|
|
2250
|
+
);
|
|
2251
|
+
}
|
|
2252
|
+
if (step === "code") {
|
|
2253
|
+
return /* @__PURE__ */ jsxs(
|
|
2254
|
+
AuthContainer,
|
|
2255
|
+
{
|
|
2256
|
+
appearance: {
|
|
2257
|
+
containerClassName: uiProps.appearance?.container,
|
|
2258
|
+
cardClassName: uiProps.appearance?.card
|
|
2259
|
+
},
|
|
2260
|
+
children: [
|
|
2261
|
+
/* @__PURE__ */ jsx(
|
|
2262
|
+
AuthHeader,
|
|
2263
|
+
{
|
|
2264
|
+
title: "Enter Reset Code",
|
|
2265
|
+
subtitle: `We've sent a 6-digit verification code to ${email}. Please enter it below to reset your password. The code will expire in 10 minutes.`,
|
|
2266
|
+
appearance: {
|
|
2267
|
+
containerClassName: uiProps.appearance?.header?.container,
|
|
2268
|
+
titleClassName: uiProps.appearance?.header?.title,
|
|
2269
|
+
subtitleClassName: uiProps.appearance?.header?.subtitle
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
),
|
|
2273
|
+
/* @__PURE__ */ jsx(AuthErrorBanner, { error, className: uiProps.appearance?.errorBanner }),
|
|
2274
|
+
/* @__PURE__ */ jsxs("div", { className: "w-full flex flex-col gap-6 items-center", children: [
|
|
2275
|
+
/* @__PURE__ */ jsx("div", { className: "w-full bg-neutral-100 dark:bg-neutral-800 rounded-lg px-4 pt-4 pb-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 mt-2", children: [
|
|
2276
|
+
/* @__PURE__ */ jsx(
|
|
2277
|
+
AuthVerificationCodeInput,
|
|
2278
|
+
{
|
|
2279
|
+
value: verificationCode,
|
|
2280
|
+
onChange: setVerificationCode,
|
|
2281
|
+
email,
|
|
2282
|
+
disabled: isVerifyingCode,
|
|
2283
|
+
onComplete: (code) => {
|
|
2284
|
+
void handleVerifyCode(code);
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
),
|
|
2288
|
+
isVerifyingCode && /* @__PURE__ */ jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: "Verifying..." })
|
|
2289
|
+
] }) }),
|
|
2290
|
+
/* @__PURE__ */ jsxs("div", { className: "w-full text-sm text-center text-neutral-600 dark:text-neutral-400", children: [
|
|
2291
|
+
"Didn't receive the email?",
|
|
2292
|
+
" ",
|
|
2293
|
+
/* @__PURE__ */ jsx(
|
|
2294
|
+
"button",
|
|
2295
|
+
{
|
|
2296
|
+
onClick: () => {
|
|
2297
|
+
void handleResendCode();
|
|
2298
|
+
},
|
|
2299
|
+
disabled: resendDisabled || isSendingCode,
|
|
2300
|
+
className: "text-black dark:text-white font-medium transition-colors disabled:cursor-not-allowed cursor-pointer hover:underline disabled:no-underline disabled:opacity-50",
|
|
2301
|
+
children: isSendingCode ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
|
|
2302
|
+
}
|
|
2303
|
+
)
|
|
2304
|
+
] })
|
|
2305
|
+
] }),
|
|
2306
|
+
/* @__PURE__ */ jsx("p", { className: "text-center text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsx("a", { href: backToSignInUrl, className: "text-black dark:text-white font-medium", children: "Back to Sign In" }) })
|
|
2307
|
+
]
|
|
2308
|
+
}
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
return /* @__PURE__ */ jsx(
|
|
2312
|
+
ResetPassword,
|
|
2313
|
+
{
|
|
2314
|
+
token: resetToken,
|
|
2315
|
+
backToSignInUrl,
|
|
2316
|
+
onSuccess: handlePasswordResetSuccess,
|
|
2317
|
+
onError,
|
|
2318
|
+
appearance: uiProps.appearance
|
|
2319
|
+
}
|
|
2320
|
+
);
|
|
2321
|
+
}
|
|
2322
|
+
function VerifyEmailStatus({
|
|
2323
|
+
status,
|
|
2324
|
+
error,
|
|
2325
|
+
appearance = {},
|
|
2326
|
+
verifyingTitle = "Verifying your email...",
|
|
2327
|
+
successTitle = "Email Verified!",
|
|
2328
|
+
successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
|
|
2329
|
+
errorTitle = "Verification Failed"
|
|
2330
|
+
}) {
|
|
2331
|
+
if (status === "verifying") {
|
|
2039
2332
|
return /* @__PURE__ */ jsx(AuthContainer, { appearance, children: /* @__PURE__ */ jsxs("div", { className: "w-full flex flex-col items-center justify-center gap-6", children: [
|
|
2040
2333
|
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold text-black dark:text-white", children: verifyingTitle }),
|
|
2041
2334
|
/* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-black dark:border-white" })
|
|
@@ -2056,6 +2349,294 @@ function VerifyEmailStatus({
|
|
|
2056
2349
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: successMessage })
|
|
2057
2350
|
] }) }) });
|
|
2058
2351
|
}
|
|
2352
|
+
function VerifyEmail({
|
|
2353
|
+
token,
|
|
2354
|
+
onSuccess,
|
|
2355
|
+
onError,
|
|
2356
|
+
...uiProps
|
|
2357
|
+
}) {
|
|
2358
|
+
const { verifyEmail } = useInsforge();
|
|
2359
|
+
const [status, setStatus] = useState("verifying");
|
|
2360
|
+
const [error, setError] = useState("");
|
|
2361
|
+
useEffect(() => {
|
|
2362
|
+
const verifyEmailFn = async () => {
|
|
2363
|
+
if (!token) {
|
|
2364
|
+
const errorMessage = "Invalid verification link. Missing required token.";
|
|
2365
|
+
setError(errorMessage);
|
|
2366
|
+
setStatus("error");
|
|
2367
|
+
if (onError) {
|
|
2368
|
+
onError(new Error(errorMessage));
|
|
2369
|
+
}
|
|
2370
|
+
return;
|
|
2371
|
+
}
|
|
2372
|
+
try {
|
|
2373
|
+
const result = await verifyEmail(token);
|
|
2374
|
+
if (!result?.accessToken) {
|
|
2375
|
+
const errorMessage = result ? "Verification succeeded but no access token received" : "Email verification failed";
|
|
2376
|
+
setError(errorMessage);
|
|
2377
|
+
setStatus("error");
|
|
2378
|
+
if (onError) {
|
|
2379
|
+
onError(new Error(errorMessage));
|
|
2380
|
+
}
|
|
2381
|
+
return;
|
|
2382
|
+
}
|
|
2383
|
+
setStatus("success");
|
|
2384
|
+
if (onSuccess) {
|
|
2385
|
+
onSuccess({
|
|
2386
|
+
accessToken: result.accessToken,
|
|
2387
|
+
user: result.user
|
|
2388
|
+
});
|
|
2389
|
+
}
|
|
2390
|
+
} catch (err) {
|
|
2391
|
+
const errorMessage = err.message || "Email verification failed";
|
|
2392
|
+
setError(errorMessage);
|
|
2393
|
+
setStatus("error");
|
|
2394
|
+
if (onError) {
|
|
2395
|
+
onError(new Error(errorMessage));
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
};
|
|
2399
|
+
void verifyEmailFn();
|
|
2400
|
+
}, [token, verifyEmail, onSuccess, onError]);
|
|
2401
|
+
return /* @__PURE__ */ jsx(VerifyEmailStatus, { status, error, ...uiProps });
|
|
2402
|
+
}
|
|
2403
|
+
function UserButton({
|
|
2404
|
+
afterSignOutUrl = "/",
|
|
2405
|
+
mode = "detailed",
|
|
2406
|
+
appearance = {}
|
|
2407
|
+
}) {
|
|
2408
|
+
const { user, signOut } = useInsforge();
|
|
2409
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
2410
|
+
const [imageError, setImageError] = useState(false);
|
|
2411
|
+
const dropdownRef = useRef(null);
|
|
2412
|
+
useEffect(() => {
|
|
2413
|
+
setImageError(false);
|
|
2414
|
+
const avatarUrl = user?.avatarUrl;
|
|
2415
|
+
if (!avatarUrl) return;
|
|
2416
|
+
const checkImageUrl = async () => {
|
|
2417
|
+
try {
|
|
2418
|
+
const response = await fetch(avatarUrl, {
|
|
2419
|
+
method: "HEAD",
|
|
2420
|
+
cache: "no-cache"
|
|
2421
|
+
});
|
|
2422
|
+
if (!response.ok) {
|
|
2423
|
+
setImageError(true);
|
|
2424
|
+
}
|
|
2425
|
+
} catch (error) {
|
|
2426
|
+
setImageError(true);
|
|
2427
|
+
}
|
|
2428
|
+
};
|
|
2429
|
+
checkImageUrl();
|
|
2430
|
+
}, [user?.avatarUrl]);
|
|
2431
|
+
useEffect(() => {
|
|
2432
|
+
function handleClickOutside(event) {
|
|
2433
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
2434
|
+
setIsOpen(false);
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
if (isOpen) {
|
|
2438
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2439
|
+
}
|
|
2440
|
+
return () => {
|
|
2441
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
2442
|
+
};
|
|
2443
|
+
}, [isOpen]);
|
|
2444
|
+
async function handleSignOut() {
|
|
2445
|
+
await signOut();
|
|
2446
|
+
setIsOpen(false);
|
|
2447
|
+
window.location.href = afterSignOutUrl;
|
|
2448
|
+
}
|
|
2449
|
+
if (!user) return null;
|
|
2450
|
+
const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
|
|
2451
|
+
return /* @__PURE__ */ jsxs(
|
|
2452
|
+
"div",
|
|
2453
|
+
{
|
|
2454
|
+
className: cn("relative inline-block", appearance.containerClassName),
|
|
2455
|
+
ref: dropdownRef,
|
|
2456
|
+
children: [
|
|
2457
|
+
/* @__PURE__ */ jsxs(
|
|
2458
|
+
"button",
|
|
2459
|
+
{
|
|
2460
|
+
className: cn(
|
|
2461
|
+
"p-1 bg-transparent border-0 rounded-full cursor-pointer transition-all duration-200",
|
|
2462
|
+
"flex items-center justify-center gap-2",
|
|
2463
|
+
"hover:bg-black/5",
|
|
2464
|
+
mode === "detailed" && "rounded-lg p-2",
|
|
2465
|
+
appearance.buttonClassName
|
|
2466
|
+
),
|
|
2467
|
+
onClick: () => setIsOpen(!isOpen),
|
|
2468
|
+
"aria-expanded": isOpen,
|
|
2469
|
+
"aria-haspopup": "true",
|
|
2470
|
+
children: [
|
|
2471
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-10 h-10 bg-blue-500 rounded-full", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
|
|
2472
|
+
"img",
|
|
2473
|
+
{
|
|
2474
|
+
src: user.avatarUrl,
|
|
2475
|
+
alt: user.email,
|
|
2476
|
+
onError: () => setImageError(true),
|
|
2477
|
+
className: "rounded-full object-cover w-full h-full"
|
|
2478
|
+
}
|
|
2479
|
+
) : /* @__PURE__ */ jsx("span", { className: "text-white font-semibold text-sm", children: initials }) }),
|
|
2480
|
+
mode === "detailed" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-0.5", children: [
|
|
2481
|
+
user.name && /* @__PURE__ */ jsx(
|
|
2482
|
+
"div",
|
|
2483
|
+
{
|
|
2484
|
+
className: cn(
|
|
2485
|
+
"text-sm font-semibold text-gray-900 leading-5 text-left",
|
|
2486
|
+
appearance.nameClassName
|
|
2487
|
+
),
|
|
2488
|
+
children: user.name
|
|
2489
|
+
}
|
|
2490
|
+
),
|
|
2491
|
+
/* @__PURE__ */ jsx(
|
|
2492
|
+
"div",
|
|
2493
|
+
{
|
|
2494
|
+
className: cn(
|
|
2495
|
+
"text-xs text-gray-500 leading-4 text-left",
|
|
2496
|
+
appearance.emailClassName
|
|
2497
|
+
),
|
|
2498
|
+
children: user.email
|
|
2499
|
+
}
|
|
2500
|
+
)
|
|
2501
|
+
] })
|
|
2502
|
+
]
|
|
2503
|
+
}
|
|
2504
|
+
),
|
|
2505
|
+
isOpen && /* @__PURE__ */ jsx(
|
|
2506
|
+
"div",
|
|
2507
|
+
{
|
|
2508
|
+
className: cn(
|
|
2509
|
+
"absolute top-full right-0 mt-2 min-w-40",
|
|
2510
|
+
"bg-white border border-gray-200 rounded-lg",
|
|
2511
|
+
"shadow-lg z-50 overflow-hidden p-1",
|
|
2512
|
+
appearance.dropdownClassName
|
|
2513
|
+
),
|
|
2514
|
+
children: /* @__PURE__ */ jsxs(
|
|
2515
|
+
"button",
|
|
2516
|
+
{
|
|
2517
|
+
onClick: handleSignOut,
|
|
2518
|
+
className: "flex items-center justify-start gap-2 w-full px-3 py-2 text-sm font-normal text-red-600 bg-transparent border-0 rounded-md cursor-pointer transition-colors hover:bg-red-50 text-left",
|
|
2519
|
+
children: [
|
|
2520
|
+
/* @__PURE__ */ jsx(LogOut, { className: "w-5 h-5" }),
|
|
2521
|
+
"Sign out"
|
|
2522
|
+
]
|
|
2523
|
+
}
|
|
2524
|
+
)
|
|
2525
|
+
}
|
|
2526
|
+
)
|
|
2527
|
+
]
|
|
2528
|
+
}
|
|
2529
|
+
);
|
|
2530
|
+
}
|
|
2531
|
+
function Protect({
|
|
2532
|
+
children,
|
|
2533
|
+
fallback,
|
|
2534
|
+
redirectTo = "/sign-in",
|
|
2535
|
+
condition,
|
|
2536
|
+
onRedirect
|
|
2537
|
+
}) {
|
|
2538
|
+
const { isSignedIn, isLoaded, user } = useInsforge();
|
|
2539
|
+
useEffect(() => {
|
|
2540
|
+
if (isLoaded && !isSignedIn) {
|
|
2541
|
+
if (onRedirect) {
|
|
2542
|
+
onRedirect(redirectTo);
|
|
2543
|
+
} else {
|
|
2544
|
+
window.location.href = redirectTo;
|
|
2545
|
+
}
|
|
2546
|
+
} else if (isLoaded && isSignedIn && condition && user) {
|
|
2547
|
+
if (!condition(user)) {
|
|
2548
|
+
if (onRedirect) {
|
|
2549
|
+
onRedirect(redirectTo);
|
|
2550
|
+
} else {
|
|
2551
|
+
window.location.href = redirectTo;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
}, [isLoaded, isSignedIn, redirectTo, condition, user, onRedirect]);
|
|
2556
|
+
if (!isLoaded) {
|
|
2557
|
+
return fallback || /* @__PURE__ */ jsx("div", { className: "insforge-loading", children: "Loading..." });
|
|
2558
|
+
}
|
|
2559
|
+
if (!isSignedIn) {
|
|
2560
|
+
return fallback || null;
|
|
2561
|
+
}
|
|
2562
|
+
if (condition && user && !condition(user)) {
|
|
2563
|
+
return fallback || null;
|
|
2564
|
+
}
|
|
2565
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2566
|
+
}
|
|
2567
|
+
function SignedIn({ children }) {
|
|
2568
|
+
const { isSignedIn, isLoaded } = useInsforge();
|
|
2569
|
+
if (!isLoaded) return null;
|
|
2570
|
+
if (!isSignedIn) return null;
|
|
2571
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2572
|
+
}
|
|
2573
|
+
function SignedOut({ children }) {
|
|
2574
|
+
const { isSignedIn, isLoaded } = useInsforge();
|
|
2575
|
+
if (!isLoaded) return null;
|
|
2576
|
+
if (isSignedIn) return null;
|
|
2577
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2578
|
+
}
|
|
2579
|
+
function InsforgeCallback({
|
|
2580
|
+
redirectTo = "/",
|
|
2581
|
+
onSuccess,
|
|
2582
|
+
onError,
|
|
2583
|
+
loadingComponent,
|
|
2584
|
+
onRedirect
|
|
2585
|
+
}) {
|
|
2586
|
+
const isProcessingRef = useRef(false);
|
|
2587
|
+
const { isLoaded, isSignedIn } = useInsforge();
|
|
2588
|
+
useEffect(() => {
|
|
2589
|
+
if (!isLoaded) return;
|
|
2590
|
+
if (isProcessingRef.current) return;
|
|
2591
|
+
isProcessingRef.current = true;
|
|
2592
|
+
const processCallback = async () => {
|
|
2593
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
2594
|
+
const error = searchParams.get("error");
|
|
2595
|
+
if (error) {
|
|
2596
|
+
if (onError) {
|
|
2597
|
+
onError(error);
|
|
2598
|
+
} else {
|
|
2599
|
+
const errorUrl = "/?error=" + encodeURIComponent(error);
|
|
2600
|
+
if (onRedirect) {
|
|
2601
|
+
onRedirect(errorUrl);
|
|
2602
|
+
} else {
|
|
2603
|
+
window.location.href = errorUrl;
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
return;
|
|
2607
|
+
}
|
|
2608
|
+
if (!isSignedIn) {
|
|
2609
|
+
const errorMsg = "authentication_failed";
|
|
2610
|
+
if (onError) {
|
|
2611
|
+
onError(errorMsg);
|
|
2612
|
+
} else {
|
|
2613
|
+
const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
|
|
2614
|
+
if (onRedirect) {
|
|
2615
|
+
onRedirect(errorUrl);
|
|
2616
|
+
} else {
|
|
2617
|
+
window.location.href = errorUrl;
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
return;
|
|
2621
|
+
}
|
|
2622
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
2623
|
+
if (onSuccess) {
|
|
2624
|
+
onSuccess();
|
|
2625
|
+
}
|
|
2626
|
+
if (onRedirect) {
|
|
2627
|
+
onRedirect(redirectTo);
|
|
2628
|
+
} else {
|
|
2629
|
+
window.location.href = redirectTo;
|
|
2630
|
+
}
|
|
2631
|
+
};
|
|
2632
|
+
processCallback();
|
|
2633
|
+
}, [isLoaded, isSignedIn, redirectTo, onSuccess, onError, onRedirect]);
|
|
2634
|
+
const defaultLoading = /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2635
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold mb-4", children: "Completing authentication..." }),
|
|
2636
|
+
/* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto" })
|
|
2637
|
+
] }) });
|
|
2638
|
+
return loadingComponent || defaultLoading;
|
|
2639
|
+
}
|
|
2059
2640
|
|
|
2060
2641
|
// src/hooks/useAuth.ts
|
|
2061
2642
|
function useAuth() {
|
|
@@ -2068,77 +2649,6 @@ function useUser() {
|
|
|
2068
2649
|
const { user, isLoaded, updateUser, setUser } = useInsforge();
|
|
2069
2650
|
return { user, isLoaded, updateUser, setUser };
|
|
2070
2651
|
}
|
|
2071
|
-
var emailSchema = z.string().min(1, "Email is required").email("Invalid email address");
|
|
2072
|
-
function createPasswordSchema(options) {
|
|
2073
|
-
const {
|
|
2074
|
-
minLength = 6,
|
|
2075
|
-
requireUppercase = false,
|
|
2076
|
-
requireLowercase = false,
|
|
2077
|
-
requireNumber = false,
|
|
2078
|
-
requireSpecialChar = false
|
|
2079
|
-
} = options || {};
|
|
2080
|
-
let schema = z.string().min(minLength, `Password must be at least ${minLength} characters`);
|
|
2081
|
-
if (requireUppercase) {
|
|
2082
|
-
schema = schema.regex(/[A-Z]/, "Password must contain at least one uppercase letter");
|
|
2083
|
-
}
|
|
2084
|
-
if (requireLowercase) {
|
|
2085
|
-
schema = schema.regex(/[a-z]/, "Password must contain at least one lowercase letter");
|
|
2086
|
-
}
|
|
2087
|
-
if (requireNumber) {
|
|
2088
|
-
schema = schema.regex(/\d/, "Password must contain at least one number");
|
|
2089
|
-
}
|
|
2090
|
-
if (requireSpecialChar) {
|
|
2091
|
-
schema = schema.regex(
|
|
2092
|
-
/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
|
|
2093
|
-
"Password must contain at least one special character"
|
|
2094
|
-
);
|
|
2095
|
-
}
|
|
2096
|
-
return schema;
|
|
2097
|
-
}
|
|
2098
|
-
var passwordSchema = createPasswordSchema();
|
|
2099
|
-
function validateEmail(email) {
|
|
2100
|
-
const result = emailSchema.safeParse(email);
|
|
2101
|
-
if (result.success) {
|
|
2102
|
-
return { valid: true };
|
|
2103
|
-
}
|
|
2104
|
-
return { valid: false, error: result.error.message };
|
|
2105
|
-
}
|
|
2106
|
-
function validatePassword(password, options) {
|
|
2107
|
-
const schema = createPasswordSchema(options);
|
|
2108
|
-
const result = schema.safeParse(password);
|
|
2109
|
-
if (result.success) {
|
|
2110
|
-
return { valid: true };
|
|
2111
|
-
}
|
|
2112
|
-
return { valid: false, error: result.error.message };
|
|
2113
|
-
}
|
|
2114
|
-
function checkPasswordStrength(password) {
|
|
2115
|
-
const feedback = [];
|
|
2116
|
-
let score = 0;
|
|
2117
|
-
if (password.length >= 8) {
|
|
2118
|
-
score += 1;
|
|
2119
|
-
} else {
|
|
2120
|
-
feedback.push("Use at least 8 characters");
|
|
2121
|
-
}
|
|
2122
|
-
if (password.length >= 12) {
|
|
2123
|
-
score += 1;
|
|
2124
|
-
}
|
|
2125
|
-
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {
|
|
2126
|
-
score += 1;
|
|
2127
|
-
} else {
|
|
2128
|
-
feedback.push("Use both uppercase and lowercase letters");
|
|
2129
|
-
}
|
|
2130
|
-
if (/\d/.test(password)) {
|
|
2131
|
-
score += 1;
|
|
2132
|
-
} else {
|
|
2133
|
-
feedback.push("Include at least one number");
|
|
2134
|
-
}
|
|
2135
|
-
if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
|
|
2136
|
-
score += 1;
|
|
2137
|
-
} else {
|
|
2138
|
-
feedback.push("Include at least one special character");
|
|
2139
|
-
}
|
|
2140
|
-
return { score, feedback };
|
|
2141
|
-
}
|
|
2142
2652
|
function RedirectToAuth({ baseUrl, path }) {
|
|
2143
2653
|
useEffect(() => {
|
|
2144
2654
|
const callbackUrl = `${window.location.origin}/auth/callback`;
|
|
@@ -2189,6 +2699,6 @@ function getInsforgeRoutes(config) {
|
|
|
2189
2699
|
return routes;
|
|
2190
2700
|
}
|
|
2191
2701
|
|
|
2192
|
-
export { AuthBranding, AuthContainer, AuthDivider, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthSubmitButton, AuthVerificationCodeInput, ForgotPasswordForm, InsforgeCallback, InsforgeProvider, OAUTH_PROVIDER_CONFIG, Protect, ResetPasswordForm, SignIn, SignInForm, SignUp, SignUpForm, SignedIn, SignedOut, UserButton, VerifyEmailStatus, checkPasswordStrength, cn, createPasswordSchema, emailSchema, getAllProviderConfigs, getInsforgeRoutes, getProviderConfig, passwordSchema, useAuth, useInsforge, usePublicAuthConfig, useUser, validateEmail, validatePassword, validatePasswordStrength };
|
|
2702
|
+
export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthSubmitButton, AuthVerificationCodeInput, ForgotPassword, ForgotPasswordForm, InsforgeCallback, InsforgeProvider, OAUTH_PROVIDER_CONFIG, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInForm, SignUp, SignUpForm, SignedIn, SignedOut, UserButton, VerifyEmail, VerifyEmailStatus, checkPasswordStrength, cn, createPasswordSchema, emailSchema, getAllProviderConfigs, getInsforgeRoutes, getProviderConfig, passwordSchema, useAuth, useInsforge, usePublicAuthConfig, useUser, validateEmail, validatePassword, validatePasswordStrength };
|
|
2193
2703
|
//# sourceMappingURL=index.mjs.map
|
|
2194
2704
|
//# sourceMappingURL=index.mjs.map
|