1import { u as useLocation, r as reactExports, t as trpc, s as setStoredAgentSession, j as jsxRuntimeExports, S as Shield, U as USFlag, L as LoaderCircle, M as Mail, B as Button } from './index-CNT5CkK7.js'; 2import { C as Card, b as CardHeader, c as CardTitle, d as CardDescription, a as CardContent } from './card-CV3CzesJ.js'; 3import { A as Alert, a as AlertDescription, D as Delete } from './alert-HWzlhw99.js'; 4import { S as Select, a as SelectTrigger, b as SelectValue, c as SelectContent, d as SelectItem } from './select-3x7TRCw-.js'; 5import { C as CircleCheck } from './circle-check-CqW-unub.js'; 6import { A as ArrowLeft } from './arrow-left-BTjDVb-D.js'; 7import './index-BEBgmBqK.js'; 8import './index-B88B3rZe.js'; 9import './chevron-down-DFKrqu4j.js'; 10import './check-BezXvNsL.js'; 11import './chevron-up-Do8Lk9oa.js'; 12 13function AgentLogin() { 14 const [, setLocation] = useLocation(); 15 const [agentKey, setAgentKey] = reactExports.useState(""); 16 const [pin, setPin] = reactExports.useState(""); 17 const [error, setError] = reactExports.useState(""); 18 const [expiredLink, setExpiredLink] = reactExports.useState(false); 19 reactExports.useEffect(() => { 20 const params = new URLSearchParams(window.location.search); 21 if (params.get("reason") === "expired") { 22 setExpiredLink(true); 23 window.history.replaceState({}, "", "/agent-login"); 24 } 25 }, []); 26 const [showForgotPin, setShowForgotPin] = reactExports.useState(false); 27 const [forgotAgentKey, setForgotAgentKey] = reactExports.useState(""); 28 const [forgotSent, setForgotSent] = reactExports.useState(false); 29 const forgotPinMutation = trpc.agentAuth.forgotPin.useMutation({ 30 onSuccess: () => setForgotSent(true) 31 }); 32 const { data: agentNames, isLoading: loadingAgents } = trpc.agentAuth.listAgentNames.useQuery(); 33 const ADMIN_KEYS = ["stacey-hinkle", "greg-fay", "ryan-fay"]; 34 const loginMutation = trpc.agentAuth.login.useMutation({ 35 onSuccess: (data) => { 36 const isAdmin = data.isAdmin || ADMIN_KEYS.includes(data.agentKey); 37 setStoredAgentSession({ 38 agentKey: data.agentKey, 39 agentName: data.agentName, 40 isAdmin, 41 deniedSections: data.deniedSections 42 }); 43 if (data.mustChangePassword) { 44 if (isAdmin) { 45 setLocation("/agent/change-password?required=1&returnTo=/"); 46 } else { 47 setLocation("/agent/change-password?required=1"); 48 } 49 } else if (isAdmin) { 50 setLocation("/"); 51 } else { 52 setLocation("/agent"); 53 } 54 }, 55 onError: (err) => { 56 setError(err.message); 57 setPin(""); 58 } 59 }); 60 const handleDigit = (digit) => { 61 if (pin.length < 6) { 62 setPin((prev) => prev + digit); 63 setError(""); 64 } 65 }; 66 const handleDelete = () => { 67 setPin((prev) => prev.slice(0, -1)); 68 setError(""); 69 }; 70 reactExports.useEffect(() => { 71 if (pin.length === 6 && agentKey) { 72 loginMutation.mutate({ agentKey, pin }); 73 } 74 }, [pin, agentKey]); 75 reactExports.useEffect(() => { 76 const handler = (e) => { 77 if (e.key >= "0" && e.key <= "9") handleDigit(e.key); 78 else if (e.key === "Backspace") handleDelete(); 79 else if (e.key === "Escape") { 80 setPin(""); 81 setError(""); 82 } 83 }; 84 window.addEventListener("keydown", handler); 85 return () => window.removeEventListener("keydown", handler); 86 }); 87 const digits = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "del"]; 88 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-screen bg-gradient-to-br from-[#3C3B6E] via-[#3C3B6E] to-[#3C3B6E] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full max-w-sm", children: [ 89 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center mb-8", children: [
90 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-[#B22234]/20 border border-[#B22234]/30 mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Shield, { className: "w-8 h-8 text-[#B22234]" }) }), 91 /* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { className: "text-2xl font-bold text-white flex items-center justify-center gap-2", children: [ 92 /* @__PURE__ */ jsxRuntimeExports.jsx(USFlag, { size: 18 }), 93 " Agent Portal ", 94 /* @__PURE__ */ jsxRuntimeExports.jsx(USFlag, { size: 18 }) 95 ] }), 96 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-blue-200/60 text-sm mt-1", children: "Expert Protection Services" }) 97 ] }), 98 expiredLink && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 rounded-lg border border-amber-500/40 bg-amber-500/10 px-4 py-3 text-center", children: [ 99 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-amber-200 text-sm font-medium", children: "This login link has expired." }),
100 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-amber-200/70 text-xs mt-0.5", children: "Please log in with your PIN below." }) 101 ] }), 102 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "bg-white/5 border-white/10 backdrop-blur-sm shadow-2xl", children: [ 103 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { className: "pb-4", children: [ 104 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-white text-center text-lg", children: "Sign In" }), 105 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { className: "text-blue-200/60 text-center text-sm", children: "Select your name and enter your 6-digit PIN" }) 106 ] }), 107 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [ 108 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ 109 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-blue-200/80 text-xs font-medium uppercase tracking-wide", children: "Your Name" }),
110 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: agentKey, onValueChange: (v) => { 111 setAgentKey(v); 112 setPin(""); 113 setError(""); 114 }, disabled: loadingAgents, children: [ 115 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "bg-white/10 border-white/20 text-white focus:ring-[#B22234] focus:border-[#B22234]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: loadingAgents ? "Loadingâ¦" : "Select your name" }) }), 116 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: (agentNames ?? []).map((a) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: a.agentKey, children: a.agentName }, a.agentKey)) }) 117 ] }) 118 ] }), 119 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ 120 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-blue-200/80 text-xs font-medium uppercase tracking-wide", children: "PIN" }), 121 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center gap-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsx( 122 "div", 123 { 124 className: `w-10 h-10 rounded-full border-2 flex items-center justify-center transition-all duration-150 ${i < pin.length ? "bg-[#B22234] border-[#B22234] scale-110" : "bg-white/10 border-white/20"}`,
125 children: i < pin.length && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-3 h-3 rounded-full bg-white" }) 126 }, 127 i 128 )) }) 129 ] }), 130 error && /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { variant: "destructive", className: "bg-red-500/10 border-red-500/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlertDescription, { className: "text-red-300 text-sm", children: error }) }), 131 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-3 gap-2", children: digits.map((d, i) => { 132 if (d === "") return /* @__PURE__ */ jsxRuntimeExports.jsx("div", {}, i); 133 if (d === "del") return /* @__PURE__ */ jsxRuntimeExports.jsx( 134 "button", 135 { 136 onClick: handleDelete, 137 disabled: !agentKey || loginMutation.isPending, 138 className: "h-14 rounded-xl bg-white/10 hover:bg-white/20 active:bg-white/30 border border-white/10 text-white flex items-center justify-center transition-all disabled:opacity-40", 139 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Delete, { className: "w-5 h-5" }) 140 }, 141 i 142 ); 143 return /* @__PURE__ */ jsxRuntimeExports.jsx( 144 "button", 145 { 146 onClick: () => handleDigit(d), 147 disabled: !agentKey || pin.length >= 6 || loginMutation.isPending, 148 className: "h-14 rounded-xl bg-white/10 hover:bg-white/20 active:scale-95 active:bg-[#B22234]/30 border border-white/10 text-white text-xl font-semibold transition-all disabled:opacity-40", 149 children: d 150 }, 151 i 152 ); 153 }) }), 154 loginMutation.isPending && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center gap-2 text-blue-200/60 text-sm", children: [
155 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 animate-spin" }), 156 "Verifyingâ¦" 157 ] }), 158 !showForgotPin ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-2 border-t border-white/10 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-blue-200/40 text-xs", children: [ 159 "Forgot your PIN?", 160 " ", 161 /* @__PURE__ */ jsxRuntimeExports.jsx( 162 "button", 163 { 164 type: "button", 165 onClick: () => { 166 setShowForgotPin(true); 167 setForgotSent(false); 168 setForgotAgentKey(""); 169 }, 170 className: "text-[#B22234]/80 hover:text-[#B22234] underline underline-offset-2 transition-colors font-medium", 171 children: "Send me a temporary PIN" 172 } 173 ) 174 ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-3 border-t border-white/10 space-y-3", children: forgotSent ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center space-y-2", children: [
175 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "w-8 h-8 text-green-400 mx-auto" }), 176 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-white text-sm font-medium", children: "Temporary PIN sent!" }), 177 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-blue-200/60 text-xs", children: "If your username is registered, a temporary PIN has been emailed to you. Check your inbox and log in with it â you'll be asked to set a new PIN right away." }), 178 /* @__PURE__ */ jsxRuntimeExports.jsxs( 179 "button", 180 { 181 type: "button", 182 onClick: () => { 183 setShowForgotPin(false); 184 setForgotSent(false); 185 }, 186 className: "text-[#B22234]/80 hover:text-[#B22234] text-xs underline underline-offset-2 flex items-center gap-1 mx-auto", 187 children: [ 188 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "w-3 h-3" }), 189 " Back to login" 190 ] 191 } 192 ) 193 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
194 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1", children: [ 195 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 196 /* @__PURE__ */ jsxRuntimeExports.jsx(Mail, { className: "w-4 h-4 text-[#B22234]" }), 197 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-white text-sm font-medium", children: "Forgot your PIN?" }) 198 ] }), 199 /* @__PURE__ */ jsxRuntimeExports.jsxs( 200 "button", 201 { 202 type: "button", 203 onClick: () => setShowForgotPin(false), 204 className: "text-blue-200/50 hover:text-white text-xs flex items-center gap-1 transition-colors", 205 children: [ 206 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "w-3 h-3" }), 207 " Back to Login" 208 ] 209 } 210 ) 211 ] }), 212 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-blue-200/60 text-xs", children: "Select your name and we'll email a temporary PIN to your registered address." }),
213 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: forgotAgentKey, onValueChange: setForgotAgentKey, disabled: loadingAgents, children: [ 214 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "bg-white/10 border-white/20 text-white focus:ring-[#B22234] focus:border-[#B22234]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: loadingAgents ? "Loadingâ¦" : "Select your name" }) }), 215 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: (agentNames ?? []).map((a) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: a.agentKey, children: a.agentName }, a.agentKey)) }) 216 ] }), 217 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ 218 /* @__PURE__ */ jsxRuntimeExports.jsxs( 219 Button, 220 { 221 variant: "ghost", 222 size: "sm", 223 onClick: () => setShowForgotPin(false), 224 className: "text-blue-200/60 hover:text-white flex-1 gap-1", 225 children: [
226 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "w-3.5 h-3.5" }), 227 " Back" 228 ] 229 } 230 ), 231 /* @__PURE__ */ jsxRuntimeExports.jsxs( 232 Button, 233 { 234 size: "sm", 235 onClick: () => forgotAgentKey && forgotPinMutation.mutate({ username: forgotAgentKey }), 236 disabled: !forgotAgentKey || forgotPinMutation.isPending, 237 className: "flex-1 gap-1 font-semibold", 238 style: { background: "#B22234", color: "white" }, 239 children: [ 240 forgotPinMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-3.5 h-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Mail, { className: "w-3.5 h-3.5" }), 241 "Send PIN" 242 ] 243 } 244 ) 245 ] }) 246 ] }) }) 247 ] }) 248 ] }), 249 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-center text-blue-200/30 text-xs mt-6", children: [
250 /* @__PURE__ */ jsxRuntimeExports.jsx(USFlag, { size: 18 }), 251 " © ", 252 (/* @__PURE__ */ new Date()).getFullYear(), 253 " Expert Protection Services. All rights reserved. ", 254 /* @__PURE__ */ jsxRuntimeExports.jsx(USFlag, { size: 18 }) 255 ] }) 256 ] }) }); 257} 258 259export { AgentLogin as default };
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.