1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js"; 2import { a as api } from "./index-D0Bmh-UX.js"; 3import { aY as TriangleAlert, cm as ArrowRight, a_ as CircleCheck, e5 as Lock, d9 as Music2, e8 as KeyRound, cL as RefreshCw } from "./vendor-dVNaLJx_.js"; 4import "./vendor-i18n-R-bMoYp_.js"; 5const ResetPassword = ({ onAuthSuccess, onAuthRequested, onNavigate }) => { 6 const params = new URLSearchParams(window.location.search); 7 const token = params.get("token"); 8 const [password, setPassword] = reactExports.useState(""); 9 const [confirmPassword, setConfirmPassword] = reactExports.useState(""); 10 const [status, setStatus] = reactExports.useState("idle"); 11 const [message, setMessage] = reactExports.useState(""); 12 const handleSubmit = async (e) => { 13 e.preventDefault(); 14 if (!token) { 15 setStatus("error"); 16 setMessage("Missing reset token. Please check your email link."); 17 return; 18 } 19 if (password !== confirmPassword) { 20 setStatus("error"); 21 setMessage("Passwords do not match."); 22 return; 23 } 24 if (password.length < 8) { 25 setStatus("error"); 26 setMessage("Password must be at least 8 characters long."); 27 return; 28 } 29 setStatus("loading"); 30 try { 31 const result = await api.resetPassword(token, password); 32 if (result.success) { 33 if (result.user) { 34 localStorage.setItem("hamie_session", JSON.stringify(result.user)); 35 if (onAuthSuccess) { 36 onAuthSuccess(result.user); 37 } 38 } 39 setStatus("success"); 40 setMessage(result.message); 41 } else { 42 setStatus("error"); 43 setMessage(result.message || "Failed to reset password."); 44 } 45 } catch (err) { 46 setStatus("error"); 47 setMessage(err.message || "An unexpected error occurred."); 48 } 49 }; 50 if (!token && status !== "success") { 51 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex items-center justify-center p-6 bg-zinc-50 dark:bg-[#0a0a0a]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-md w-full p-8 bg-white dark:bg-zinc-900 rounded-3xl shadow-2xl border border-zinc-200 dark:border-zinc-800 text-center", children: [
52 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-6 flex justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-20 h-20 bg-red-50 dark:bg-red-900/20 text-red-500 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { size: 40 }) }) }), 53 /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-2xl font-black mb-2", children: "Invalid Request" }), 54 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-500 mb-6", children: "This password reset link is invalid or has expired." }), 55 /* @__PURE__ */ jsxRuntimeExports.jsxs("a", { href: "/", className: "inline-flex items-center gap-2 text-indigo-500 font-bold hover:underline", children: [ 56 "Go back to home ", 57 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 16 }) 58 ] }) 59 ] }) }); 60 } 61 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex items-center justify-center p-6 bg-zinc-50 dark:bg-[#0a0a0a]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-w-md w-full animate-in fade-in slide-in-from-bottom-8 duration-700", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-zinc-900 rounded-3xl p-8 shadow-2xl shadow-indigo-500/10 border border-zinc-200 dark:border-zinc-800", children: [ 62 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-8 flex justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
63 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `w-24 h-24 rounded-full flex items-center justify-center ${status === "success" ? "bg-emerald-50 dark:bg-emerald-900/20 text-emerald-500" : "bg-indigo-50 dark:bg-indigo-900/20 text-indigo-500"}`, children: status === "success" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { size: 48 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Lock, { size: 48 }) }), 64 status === "success" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute -top-2 -right-2 w-8 h-8 bg-indigo-500 rounded-full flex items-center justify-center text-white animate-bounce", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Music2, { size: 16 }) }) 65 ] }) }), 66 /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-3xl font-black text-zinc-900 dark:text-white mb-3 tracking-tight text-center", children: status === "success" ? "Password Reset!" : "New Password" }), 67 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-600 dark:text-zinc-400 mb-8 leading-relaxed text-center", children: status === "success" ? "Your password has been successfully updated and your account is now signed in." : "Choose a strong password to protect your HamieNET account." }),
68 status === "success" ? /* @__PURE__ */ jsxRuntimeExports.jsxs( 69 "button", 70 { 71 type: "button", 72 onClick: () => { 73 if (onNavigate) { 74 onNavigate("home"); 75 } else { 76 window.location.href = "/"; 77 } 78 }, 79 className: "w-full flex items-center justify-center gap-2 py-4 rounded-2xl font-bold bg-indigo-600 hover:bg-indigo-700 text-white shadow-lg shadow-indigo-600/30 transition-all cursor-pointer", 80 children: [ 81 "Continue to HamieNET", 82 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 18 }) 83 ] 84 } 85 ) : /* @__PURE__ */ jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [ 86 status === "error" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-xl flex gap-3 text-red-800 dark:text-red-200 text-sm", children: [ 87 /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "shrink-0", size: 18 }),
88 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: message }) 89 ] }), 90 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 91 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-bold text-zinc-500 uppercase mb-1 px-1", children: "New Password" }), 92 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ 93 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-zinc-400", children: /* @__PURE__ */ jsxRuntimeExports.jsx(KeyRound, { size: 16 }) }), 94 /* @__PURE__ */ jsxRuntimeExports.jsx( 95 "input", 96 { 97 type: "password", 98 required: true, 99 placeholder: "Min 8 characters", 100 className: "w-full pl-11 pr-4 py-4 bg-zinc-50 dark:bg-zinc-950 border border-zinc-200 dark:border-zinc-800 rounded-2xl outline-none focus:ring-2 focus:ring-indigo-500 transition-all text-sm", 101 value: password, 102 onChange: (e) => setPassword(e.target.value) 103 } 104 ) 105 ] }) 106 ] }),
107 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 108 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-bold text-zinc-500 uppercase mb-1 px-1", children: "Confirm Password" }), 109 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ 110 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-zinc-400", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Lock, { size: 16 }) }), 111 /* @__PURE__ */ jsxRuntimeExports.jsx( 112 "input", 113 { 114 type: "password", 115 required: true, 116 placeholder: "Repeat new password", 117 className: "w-full pl-11 pr-4 py-4 bg-zinc-50 dark:bg-zinc-950 border border-zinc-200 dark:border-zinc-800 rounded-2xl outline-none focus:ring-2 focus:ring-indigo-500 transition-all text-sm", 118 value: confirmPassword, 119 onChange: (e) => setConfirmPassword(e.target.value) 120 } 121 ) 122 ] }) 123 ] }),
124 /* @__PURE__ */ jsxRuntimeExports.jsx( 125 "button", 126 { 127 type: "submit", 128 disabled: status === "loading", 129 className: "w-full h-14 bg-indigo-600 hover:bg-indigo-700 text-white rounded-2xl font-bold shadow-xl shadow-indigo-600/20 transition-all flex items-center justify-center gap-2 group disabled:opacity-50", 130 children: status === "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "animate-spin", size: 20 }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 131 "Update Password", 132 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { className: "group-hover:translate-x-1 transition-transform", size: 20 }) 133 ] }) 134 } 135 ) 136 ] }) 137 ] }) }) }); 138}; 139export { 140 ResetPassword as default 141};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.