vendor: 4,766 bytes, lines 1-32
1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-C9G79VZA.js","assets/index-Bs7hbQUI.css"])))=>i.map(i=>d[i]); 2import{c as V,f as ps,r as n,i as gs,G as bs,j as e,n as Ke,l as fs,a1 as js,J as Ee,N as Te,b as Me,a9 as Ze,a as Ge,u as ws,O as C,am as De,aB as vs,B as c,Q as ys,a2 as F,a3 as E,a4 as D,a5 as A,L as p,I as O,aC as Ae,aD as Qe,aE as be,aF as Be,Z as Ns,s as Cs,aA as U,aG as ks,av as Ss}from"./index-C9G79VZA.js";import{u as Ps,S as me,a as ue,b as he,c as xe,d as S}from"./select-CMSEpRfo.js";import{A as Z,a as G,b as Q,c as W,d as J,e as X,f as ee,g as se,h as ae}from"./alert-dialog-DGKKBgw3.js";import{L as Fs}from"./loading-spinner-DOOG2czA.js";import{u as Es}from"./use-permissions-DqObKU7A.js";import{C as Ds}from"./chevron-left-CjeXMlvm.js";import{L as As}from"./layout-dashboard-y77pES4o.js";import{Z as Ts,S as Ms,L as Ls}from"./zap-DkDkHX1Y.js";import{T as We}from"./trash-2-CnIe5eeI.js";import{U as Is,S as Je}from"./users-CmlMVJiQ.js";import{S as Rs}from"./save-w8JZXKGn.js";import{B as Os}from"./book-open-CkOPR93I.js";import{M as Us}from"./message-square-D3y-8y9b.js";import{D as qs}from"./download-CuEtWsvZ.js";/** 3 * @license lucide-react v0.453.0 - ISC 4 * 5 * This source code is licensed under the ISC license. 6 * See the LICENSE file in the root directory of this source tree. 7 */const $s=V("ExternalLink",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]]);/** 8 * @license lucide-react v0.453.0 - ISC 9 * 10 * This source code is licensed under the ISC license. 11 * See the LICENSE file in the root directory of this source tree. 12 */const Hs=V("MapPin",[["path",{d:"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0",key:"1r0f0z"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}]]);/** 13 * @license lucide-react v0.453.0 - ISC 14 * 15 * This source code is licensed under the ISC license. 16 * See the LICENSE file in the root directory of this source tree. 17 */const Vs=V("Send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]]);/** 18 * @license lucide-react v0.453.0 - ISC 19 * 20 * This source code is licensed under the ISC license. 21 * See the LICENSE file in the root directory of this source tree. 22 */const Xe=V("Shield",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]]);/** 23 * @license lucide-react v0.453.0 - ISC 24 * 25 * This source code is licensed under the ISC license. 26 * See the LICENSE file in the root directory of this source tree. 27 */const Ys=V("UserMinus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]);/** 28 * @license lucide-react v0.453.0 - ISC 29 * 30 * This source code is licensed under the ISC license. 31 * See the LICENSE file in the root directory of this source tree. 32 */const pe=V("UserPlus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]);var Le="Switch",[_s,ma]=ps(Le),[zs,Bs]=_s(Le),es=n.forwardRef((t,a)=>{const{__scopeSwitch:l,name:m,checked:u,defaultChecked:i,required:r,disabled:b,value:f="on",onCheckedChange:h,form:g,...w}=t,[v,q]=n.useState(null),L=gs(a,T=>q(T)),I=n.useRef(!1),k=v?g||!!v.closest("form"):!0,[y=!1,N]=bs({prop:u,defaultProp:i,onChange:h});return e.jsxs(zs,{scope:l,checked:y,disabled:b,children:[e.jsx(Ke.button,{type:"button",role:"switch","aria-checked":y,"aria-required":r,"data-state":ts(y),"data-disabled":b?"":void 0,disabled:b,value:f,...w,ref:L,onClick:fs(t.onClick,T=>{N(o=>!o),k&&(I.current=T.isPropagationStopped(),I.current||T.stopPropagation())})}),k&&e.jsx(Ks,{control:v,bubbles:!I.current,name:m,value:f,checked:y,required:r,disabled:b,form:g,style:{transform:"translateX(-100%)"}})]})});es.displayName=Le;var ss="SwitchThumb",as=n.forwardRef((t,a)=>{const{__scopeSwitch:l,...m}=t,u=Bs(ss,l);return e.jsx(Ke.span,{"data-state":ts(u.checked),"data-disabled":u.disabled?"":void 0,...m,ref:a})});as.displayName=ss;var Ks=t=>{const{control:a,checked:l,bubbles:m=!0,...u}=t,i=n.useRef(null),r=Ps(l),b=js(a);return n.useEffect(()=>{const f=i.current,h=window.HTMLInputElement.prototype,w=Object.getOwnPropertyDescriptor(h,"checked").set;if(r!==l&&w){const v=new Event("click",{bubbles:m});
32w.call(f,l),f.dispatchEvent(v)}},[r,l,m]),e.jsx("input",{type:"checkbox","aria-hidden":!0,defaultChecked:l,...u,tabIndex:-1,ref:i,style:{...t.style,...b,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})};function ts(t){return t?"checked":"unchecked"}var rs=es,Zs=as;const ge=n.forwardRef(({className:t,...a},l)=>e.jsx(rs,{className:Ee("peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",t),...a,ref:l,children:e.jsx(Zs,{className:Ee("pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0")})}));ge.displayName=rs.displayName;const ns=n.forwardRef(({className:t,...a},l)=>e.jsx("textarea",{className:Ee("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:l,...a}));ns.displayName="Textarea";function ua(){const[,t]=Te(),{toast:a}=Me(),l=Ze(),{user:m}=Ge(),{farms:u,activeFarm:i,activeFarmId:r,setActiveFarmId:b,isViewer:f}=ws(),h=(i==null?void 0:i.role)==="owner",{canManageFarmMembers:g,canUpgradeFarmPlan:w,canCreateFarm:v,canAddMember:q,memberLimit:L,memberCount:I,isFreePlan:k,isFarmerPlan:y,isBetaUser:N,stockClassLimit:T,sessionLimit:o,stockClassCount:M,sessionCount:$,currentPeriodEnd:x,cancelAtPeriodEnd:R}=Es(),[Y,fe]=n.useState(""),[je,we]=n.useState("member"),[is,te]=n.useState(!1),[cs,ve]=n.useState(!1),[_,ye]=n.useState(""),z=C({mutationFn:async s=>Ns(s),onSuccess:s=>{b(s.id),ye(""),ve(!1),a({title:"Farm created",description:navigator.onLine?`"${s.name}" is now your active farm.`:`"${s.name}" saved â will sync when back online.`}),navigator.onLine&&Cs.sync().catch(()=>{})},onError:s=>{a({title:"Could not create farm",description:s.message,variant:"destructive"})}}),{data:Ie=[],refetch:Ne}=De({queryKey:["/api/farms",r,"members"],queryFn:async()=>{const s=await fetch(`/api/farms/${r}/members`,{credentials:"include"});if(!s.ok)throw new Error("Failed to load members");return s.json()},enabled:!!r&&h}),re=C({mutationFn:async({emailOrUsername:s,role:d})=>{const P=await fetch(`/api/farms/${r}/members`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({emailOrUsername:s,role:d})}),K=await P.json();if(!P.ok)throw new Error(K.message||"Failed to add member");return K},onSuccess:()=>{fe(""),we("member"),te(!1),Ne(),a({title:"Member added",description:"They can now access this farm."})},onError:s=>{a({title:"Could not add member",description:s.message,variant:"destructive"})}}),Re=C({mutationFn:async({userId:s,role:d})=>{const P=await fetch(`/api/farms/${r}/members/${s}`,{method:"PATCH",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({role:d})}),K=await P.json();if(!P.ok)throw new Error(K.message||"Failed to update role");return K},onSuccess:()=>{Ne(),a({title:"Role updated"})},onError:s=>{a({title:"Could not update role",description:s.message,variant:"destructive"})}}),Oe=C({mutationFn:async s=>{const d=await fetch(`/api/farms/${r}/members/${s}`,{method:"DELETE",credentials:"include"});if(!d.ok){const P=await d.json();throw new Error(P.message||"Failed to remove member")}},onSuccess:()=>{Ne(),a({title:"Member removed"})},onError:s=>{a({title:"Could not remove member",description:s.message,variant:"destructive"})}}),[B,Ue]=n.useState(!1),[ne,qe]=n.useState(!1),[ie,$e]=n.useState(!1),[ce,He]=n.useState("new_zealand"),[le,Ve]=n.useState(""),[oe,Ye]=n.useState(""),[H,_e]=n.useState(""),[de,ze]=n.useState(""),{data:j,isLoading:ls}=De({queryKey:["/api/user-settings"],retry:!1}),Ce=C({mutationFn:async s=>(await U("POST","/api/user-settings",s)).json(),onSuccess:()=>
32{l.invalidateQueries({queryKey:["/api/user-settings"]}),a({title:"Settings Created",description:"Your preferences have been saved successfully"})},onError:s=>{var d;(d=s.message)!=null&&d.startsWith("401")||a({title:"Error",description:s.message||"Failed to create settings",variant:"destructive"})}}),ke=C({mutationFn:async s=>(await U("PATCH","/api/user-settings",s)).json(),onSuccess:()=>{l.invalidateQueries({queryKey:["/api/user-settings"]}),a({title:"Settings Updated",description:"Your preferences have been saved successfully"})},onError:s=>{var d;(d=s.message)!=null&&d.startsWith("401")||a({title:"Error",description:s.message||"Failed to update settings",variant:"destructive"})}}),Se=C({mutationFn:async s=>(await U("POST","/api/feedback",{message:s})).json(),onSuccess:()=>{Ve(""),a({title:"Feedback Submitted",description:"Thank you for your feedback!"})},onError:s=>{a({title:"Error",description:s.message||"Failed to submit feedback",variant:"destructive"})}}),{refetch:os}=vs(),ds=C({mutationFn:async()=>(await U("POST","/api/cancel-subscription",{})).json(),onSuccess:()=>{os(),a({title:"Subscription Cancelled",description:"Your subscription will end at the current billing period. You'll retain access until then."})},onError:s=>{a({title:"Error",description:s.message||"Failed to cancel subscription",variant:"destructive"})}}),Pe=C({mutationFn:async()=>{if(r==null)throw new Error("No active farm selected");await ks(r)},onSuccess:()=>{l.invalidateQueries({queryKey:["/api/farms"]}),a({title:"Farm Deleted",description:navigator.onLine?"The farm and all its data have been deleted.":"Farm removed locally â server delete will sync when you're back online."})},onError:s=>{a({title:"Error",description:s.message,variant:"destructive"})}}),Fe=C({mutationFn:async s=>{const d=await U("POST","/api/change-password",s);if(!d.ok){const P=await d.json();throw new Error(P.error||"Failed to change password")}return d.json()},onSuccess:()=>{Ye(""),_e(""),ze(""),a({title:"Password Changed",description:"Your password has been updated successfully"})},onError:s=>{a({title:"Error",description:s.message||"Failed to change password",variant:"destructive"})}}),ms=()=>{if(!oe||!H||!de){a({title:"Error",description:"Please fill in all password fields",variant:"destructive"});return}if(H.length<6){a({title:"Error",description:"New password must be at least 6 characters",variant:"destructive"});return}if(H!==de){a({title:"Error",description:"New passwords don't match",variant:"destructive"});return}Fe.mutate({currentPassword:oe,newPassword:H})};n.useEffect(()=>{j&&(Ue(j.enableIndividualIds),qe(j.enableVoiceRecording??!1),$e(j.enableHalfScores??!1),He(j.country||"new_zealand"))},[j]);const us=()=>{const s={enableIndividualIds:B,enableVoiceRecording:ne,enableHalfScores:ie,country:ce};j?ke.mutate(s):Ce.mutate(s)},hs=()=>{if(!le.trim()){a({title:"Error",description:"Please enter your feedback",variant:"destructive"});return}Se.mutate(le)},xs=j?j.enableIndividualIds!==B||(j.enableVoiceRecording??!1)!==ne||(j.enableHalfScores??!1)!==ie||j.country!==ce:B!==!1||ne!==!1||ie!==!1||ce!=="new_zealand";return ls?e.jsx("div",{className:"max-w-md mx-auto bg-brand-cream min-h-screen shadow-lg relative",children:e.jsx("div",{className:"flex justify-center items-center h-64",children:e.jsx(Fs,{size:"lg"})})}):e.jsxs("div",{className:"max-w-md mx-auto bg-brand-cream min-h-screen shadow-lg relative",children:[e.jsx("header",{className:"bg-brand-green text-white p-4",children:e.jsxs("div",{className:"flex items-center",children:[e.jsxs(c,{variant:"ghost",size:"sm",onClick:()=>t("/"),className:"flex items-center gap-1 mr-2 px-2 py-1 hover:bg-white/10 rounded-lg transition-colors text-white","data-testid":"back-button",children:[e.jsx(Ds,{className:"w-5 h-5"}),e.jsx("span",{className:"text-sm",children:"Back"})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[e.jsx("img",{src:ys,alt:"StockScore Logo",className:"h-8 w-auto"}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold",children:"Settings"}),e.jsx("p",{className:"text-sm text-green-100",children:"Configure your preferences"})]})]})]})}),e.jsxs("div",{className:"p-4 space-y-4",children:[(m==null?void 0:m.isAdmin)&&e.jsxs(F,{"data-testid":"card-admin",children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Xe,{className:"w-5 h-5"}),"Admin"]})}),e.jsx(A,{children:e.jsxs(c,{className:"w-full bg-brand-green hover:bg-brand-green/90 text-white",onClick:()=>t("/admin/dashboard"),"data-testid":"button-admin-dashboard",children:[e.jsx(As,{className:"w-4 h-4 mr-2"}),"Open Admin Dashboard"]})})]}),u.length>0&&i&&e.jsxs(F,{children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Hs,{className:"w-5 h-5"}),"Farm & Plan"]})}),e.jsxs(A,{className:"space-y-4",children:[e.jsx("div",{className:"flex items-start justify-between gap-3",children:e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-semibold text-base leading-tight",children:i.name}),e.jsxs("div",{className:"flex items-center gap-2 mt-1 flex-wrap",children:[e.jsx("span",{className:`inline-flex items-center text-xs font-semibold px-2 py-0.5 rounded-full border ${i.role==="owner"?"bg-green-50 text-green-700 border-green-200":i.role==="member"?"bg-blue-50 text-blue-700 border-blue-200":"bg-amber-50 text-amber-700 border-amber-200"}`,children:i.role.charAt(0).toUpperCase()+i.role.slice(1)}),e.jsx("span",{className:`inline-flex items-center text-xs font-semibold px-2 py-0.5 rounded-full border ${N?"bg-purple-50 text-purple-700 border-purple-200":y?"bg-green-50 text-green-700 border-green-200":"bg-gray-100 text-gray-600 border-gray-200"}`,children:N?"Complimentary":y?"Farmer":"Free"})]})]})}),u.length>=2&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(p,{className:"text-sm font-medium",children:"Switch farm"}),e.jsxs(me,{value:String(r),onValueChange:s=>b(parseInt(s,10)),children:[e.jsx(ue,{children:e.jsx(he,{placeholder:"Select a farm"})}),e.jsx(xe,{children:u.map(s=>e.jsxs(S,{value:String(s.id),children:[s.name," ",e.jsxs("span",{className:"text-gray-400 text-xs",children:["(",s.role,")"]})]},s.id))})]})]}),v&&(cs?e.jsxs("div",{className:"space-y-2 p-3 bg-gray-50 rounded-lg border border-gray-200",children:[e.jsx(p,{className:"text-sm font-medium",children:"New farm name"}
32),e.jsx(O,{placeholder:"e.g. North Block",value:_,onChange:s=>ye(s.target.value),onKeyDown:s=>{s.key==="Enter"&&_.trim()&&(s.preventDefault(),z.mutate(_.trim()))},autoFocus:!0}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(c,{className:"flex-1 bg-brand-green hover:bg-brand-green/90 text-white",disabled:!_.trim()||z.isPending,onClick:()=>z.mutate(_.trim()),children:z.isPending?"Creating...":"Create Farm"}),e.jsx(c,{variant:"outline",className:"flex-1",onClick:()=>{ve(!1),ye("")},disabled:z.isPending,children:"Cancel"})]})]}):e.jsxs(c,{variant:"outline",className:"w-full border-dashed",onClick:()=>ve(!0),children:[e.jsx(pe,{className:"w-4 h-4 mr-2"}),"Create another farm"]})),N&&e.jsx("div",{className:"p-3 bg-purple-50 rounded-lg border border-purple-200",children:e.jsx("p",{className:"text-sm text-purple-800",children:"Your farm has complimentary access to StockScore. Thank you for being an early supporter!"})}),k&&!N&&e.jsxs("div",{className:"p-3 bg-amber-50 rounded-lg border border-amber-200 space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-amber-800",children:"Free plan usage:"}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex justify-between text-sm text-amber-700",children:[e.jsx("span",{children:"Stock classes"}),e.jsxs("span",{className:"font-semibold",children:[M," / ",T??"â"]})]}),e.jsxs("div",{className:"flex justify-between text-sm text-amber-700",children:[e.jsx("span",{children:"Recording sessions"}),e.jsxs("span",{className:"font-semibold",children:[$," / ",o??"â"]})]})]})]}),w&&e.jsxs(c,{className:"w-full bg-brand-green hover:bg-brand-green/90",onClick:()=>t("/subscription"),children:[e.jsx(Ts,{className:"w-4 h-4 mr-2"}),"Upgrade to Farmer Plan â $79 NZD/year excl. GST"]}),e.jsx(c,{variant:"outline",className:"w-full",onClick:()=>t("/plans"),"data-testid":"button-see-all-plans",children:"See all plans & pricing"}),k&&!N&&!h&&e.jsx("p",{className:"text-xs text-muted-foreground text-center",children:"Only the farm owner can change the plan. Ask them to upgrade to the Farmer plan for unlimited access."}),y&&!N&&x&&e.jsxs("div",{className:"flex justify-between items-center text-sm",children:[e.jsx("span",{className:"font-medium text-gray-700",children:R?"Access until:":"Renews on:"}),e.jsx("span",{className:"text-gray-600",children:new Date(x*1e3).toLocaleDateString("en-NZ",{year:"numeric",month:"long",day:"numeric"})})]}),R&&e.jsxs("div",{className:"p-3 bg-orange-50 rounded-lg border border-orange-200 flex items-start gap-2",children:[e.jsx(Ae,{className:"w-5 h-5 text-orange-600 mt-0.5 shrink-0"}),e.jsx("p",{className:"text-sm text-orange-800",children:"Your subscription is set to cancel. You'll retain access until the end of your billing period."})]}),y&&h&&!R&&!N&&e.jsxs(Z,{children:[e.jsx(G,{asChild:!0,children:e.jsxs(c,{variant:"destructive",className:"w-full","data-testid":"cancel-subscription-button",children:[e.jsx(Qe,{className:"w-4 h-4 mr-2"}),"Cancel Subscription"]})}),e.jsxs(Q,{children:[e.jsxs(W,{children:[e.jsx(J,{children:"Cancel Subscription?"}),e.jsxs(X,{children:["Your subscription will be cancelled, but you'll retain access to StockScore until the end of your current billing period",x&&e.jsxs(e.Fragment,{children:[" on ",new Date(x*1e3).toLocaleDateString("en-NZ",{year:"numeric",month:"long",day:"numeric"})]}),". Your subscription will not auto-renew."]})]}),e.jsxs(ee,{children:[e.jsx(se,{"data-testid":"cancel-dialog-cancel",children:"Keep Subscription"}),e.jsx(ae,{onClick:()=>ds.mutate(),className:"bg-red-600 hover:bg-red-700","data-testid":"cancel-dialog-confirm",children:"Cancel Subscription"})]})]})]}),h&&u&&u.length>1&&e.jsxs(Z,{children:[e.jsx(G,{asChild:!0,children:e.jsxs(c,{variant:"outline",className:"w-full border-red-200 text-red-600 hover:bg-red-50 hover:text-red-700","data-testid":"delete-farm-button",children:[e.jsx(We,{className:"w-4 h-4 mr-2"}),"Delete this farm"]})}),e.jsxs(Q,{children:[e.jsxs(W,{children:[e.jsxs(J,{children:['Delete "',i==null?void 0:i.name,'"?']}),e.jsx(X,{children:"This will permanently delete this farm and all its data â stock classes, recording sessions, and members. This action cannot be undone."})]}),e.jsxs(ee,{children:[e.jsx(se,{children:"Keep Farm"}),e.jsx(ae,{onClick:()=>Pe.mutate(),className:"bg-red-600 hover:bg-red-700","data-testid":"delete-farm-confirm",disabled:Pe.isPending,children:Pe.isPending?"Deletingâ¦":"Delete Farm"})]})]})]})]})]}),e.jsx(Qs,{}),g&&r&&e.jsxs(F,{children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Is,{className:"w-5 h-5"}),"Farm Members"]})}),e.jsxs(A,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[Ie.map(s=>e.jsxs("div",{className:"flex items-center justify-between gap-2 py-1",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[s.role==="owner"&&e.jsx(Je,{className:"w-4 h-4 text-brand-green shrink-0"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-sm font-medium truncate",children:s.username}),s.email&&e.jsx("p",{className:"text-xs text-gray-400 truncate",children:s.email})]})]}),e.jsx("div",{className:"flex items-center gap-2 shrink-0",children:s.role==="owner"?e.jsx("span",{className:"text-xs text-brand-green font-semibold",children:"Owner"}):e.jsxs(e.Fragment,{children:[e.jsxs(me,{value:s.role,onValueChange:d=>Re.mutate({userId:s.userId,role:d}),disabled:Re.isPending,children:[e.jsx(ue,{className:"h-7 text-xs w-24",children:e.jsx(he,{})}),e.jsxs(xe,{children:[e.jsx(S,{value:"member",children:"Member"}),e.jsx(S,{value:"viewer",children:"Viewer"})]})]}),e.jsxs(Z,{children:[e.jsx(G,{asChild:!0,children:e.jsx(c,{variant:"ghost",size:"sm",className:"h-7 w-7 p-0 text-red-400 hover:text-red-600 hover:bg-red-50",disabled:Oe.isPending,children:e.jsx(Ys,{className:"w-3.5 h-3.5"})})}),e.jsxs(Q,{children:[e.jsxs(W,{children:[e.jsx(J,{children:"Remove member"}),e.jsxs(X,{children:["Remove ",e.jsx("strong",{children:s.username})," from this farm? They will lose access immediately."]})]}),e.jsxs(ee,{children:[e.jsx(se,{children:"Cancel"}),e.jsx(ae,{onClick:()=>Oe.mutate(s.userId),className:"bg-red-500 hover:bg-red-600 text-white",children:"Remove"})]})]})]})]})})]},s.userId)),Ie.length===0&&e.jsx("p",{className:"text-sm text-gray-400",children:"No other members yet."})]}),is?e.jsxs("div",{className:"space-y-2 pt-2 border-t",children:[e.jsx(p,{className:"text-sm font-medium",children:"Add by email"}),e.jsx(O,{placeholder:"e.g. [email protected]",value:Y,onChange:s=>fe(s.target.value),onKeyDown:s=>{s.key==="Enter"&&Y.trim()&&re.mutate({emailOrUsername:Y.trim(),role:je})}}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs(me,{value:je,onValueChange:s=>we(s),children:[e.jsx(ue,{className:"flex-1",children:e.jsx(he,{})}),e.jsxs(xe,{children:[e.jsx(S,{value:"member",children:"Member â can record & edit"}),e.jsx(S,{value:"viewer",children:"Viewer â read-only"})]})]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(c,{className:"flex-1 brand-green",onClick:()=>re.mutate({emailOrUsername:Y.trim(),role:je}),disabled:!Y.trim()||re.isPending,children:re.isPending?e.jsx(be,{className:"w-4 h-4 animate-spin"}):"Add member"}),e.jsx(c,{variant:"outline",onClick:()=>{te(!1),fe("")},children:"Cancel"})]})]}):q?e.jsxs(c,{variant:"outline",className:"w-full",onClick:()=>te(!0),children:[e.jsx(pe,{className:"w-4 h-4 mr-2"}),"Add member"]}):e.jsxs("div",{className:"space-y-2 py-1",children:[e.jsxs("p",{className:"text-sm text-muted-foreground text-center",children:["Editor limit reached (",I,"/",L,")."," ",k&&"Upgrade to the Farmer plan to add more editors."]}),e.jsx("p",{className:"text-xs text-muted-foreground text-center",children:"Viewers (read-only â e.g. advisors or agronomists) don't count toward this limit and can always be added."}),e.jsxs(c,{variant:"outline",className:"w-full",onClick:()=>{we("viewer"),te(!0)},"data-testid":"button-add-viewer",children:[e.jsx(pe,{className:"w-4 h-4 mr-2"}),"Add viewer"]}),!k&&h&&r&&e.jsxs(c,{variant:"outline",className:"w-full",onClick:()=>t(`/buy-member-seat?farmId=${r}`),"data-testid":"button-buy-extra-seat",children:[e.jsx(pe,{className:"w-4 h-4 mr-2"}),"Add another editor seat â $5/year excl. GST"]})]})]})]}),e.jsxs(F,{children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Ms,{className:"w-5 h-5"}),"Recording Preferences"]})}),e.jsxs(A,{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(p,{htmlFor:"individual-ids",className:"text-base font-medium",children:"Individual ID Tracking"}),e.jsx("p",{className:"text-sm text-gray-600",children:"Record individual animal IDs for each body condition score"})]}),e.jsx(ge,{id:"individual-ids",checked:B,onCheckedChange:Ue,"data-testid":"individual-ids-switch"})]}),B&&e.jsx("div",{className:"p-3 bg-blue-50 rounded-lg border border-blue-200",children:e.jsxs("p",{className:"text-sm text-blue-800",children:[e.jsx("strong",{children:"Individual ID Tracking Enabled:"})," When recording scores, you'll be able to enter a unique ID for each animal scored."]})}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1 pr-4",children:[e.jsx(p,{htmlFor:"half-scores",className:"text-base font-medium",children:"Half scores for sheep & deer"}),e.jsx("p",{className:"text-sm text-gray-600",children:"Add 0.5 steps (e.g. 2.5, 3.5) to the sheep and deer scale. Off means whole numbers only (1â5). Cattle always use half steps."})]}),e.jsx(ge,{id:"half-scores",checked:ie,onCheckedChange:$e,"data-testid":"half-scores-switch"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1 pr-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(p,{htmlFor:"voice-recording",className:"text-base font-medium",children:"Voice-activated recording"}),e.jsx("span",{className:"rounded-full bg-amber-100 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-amber-700",children:"Beta"})]}),e.jsx("p",{className:"text-sm text-gray-600",children:'Record scores hands-free by speaking them out loud (e.g. "three" or "two and a half"). Experimental â works best in Chrome on Android and may be unavailable on some browsers.'})]}),e.jsx(ge,{id:"voice-recording",checked:ne,onCheckedChange:qe,"data-testid":"voice-recording-switch"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(p,{htmlFor:"country",className:"text-base font-medium",children:"Country"}),e.jsx("p",{className:"text-sm text-gray-600 mb-2",children:"Select your country to use the appropriate BCS scales"}),e.jsxs(me,{value:ce,onValueChange:He,children:[e.jsx(ue,{id:"country","data-testid":"country-select",children:e.jsx(he,{placeholder:"Select country"})}),e.jsxs(xe,{children:[e.jsx(S,{value:"new_zealand",children:"New Zealand"}),e.jsx(S,{value:"australia",children:"Australia"}),e.jsx(S,{value:"usa",disabled:!0,children:"United States (Coming Soon)"}),e.jsx(S,{value:"uk",disabled:!0,children:"United Kingdom (Coming Soon)"}),e.jsx(S,{value:"canada",disabled:!0,children:"Canada (Coming Soon)"})]})]})]})]})]}),xs&&e.jsxs(c,{onClick:us,disabled:Ce.isPending||ke.isPending,className:"w-full bg-brand-green hover:bg-brand-green/90 text-white","data-testid":"save-settings-button",children:[e.jsx(Rs,{className:"w-4 h-4 mr-2"}),Ce.isPending||ke.isPending?"Saving...":"Save Settings"]}),e.jsxs(F,{children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Be,{className:"w-5 h-5"}),"Change Password"]})}),e.jsxs(A,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(p,{htmlFor:"current-password",children:"Current Password"}),e.jsx(O,{id:"current-password",type:"password",placeholder:"Enter current password",value:oe,onChange:s=>Ye(s.target.value),"data-testid":"input-current-password"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(p,{htmlFor:"new-password",children:"New Password"}),e.jsx(O,{id:"new-password",type:"password",placeholder:"Enter new password (min 6 characters)",value:H,onChange:s=>_e(s.target.value),"data-testid":"input-new-password"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(p,{htmlFor:"confirm-password",children:"Confirm New Password"}),e.jsx(O,{id:"confirm-password",type:"password",placeholder:"Confirm new password",value:de,onChange:s=>ze(s.target.value),"data-testid":"input-confirm-password"})]}),e.jsx(c,{onClick:ms,disabled:Fe.isPending||!oe||!H||!de,className:"w-full bg-brand-green hover:bg-brand-green/90 text-white","data-testid":"button-change-password",children:Fe.isPending?e.jsxs(e.Fragment,{children:[e.jsx(be,{className:"w-4 h-4 mr-2 animate-spin"}),"Changing..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Be,{className:"w-4 h-4 mr-2"}),"Change Password"]})})]})]}),e.jsx(Gs,{}),e.jsxs(F,{children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Os,{className:"w-5 h-5"}),"Help & Support"]})}),e.jsx(A,{children:e.jsxs("a",{href:"/user-guide-farmer.html?back=/",className:"flex items-center justify-between w-full rounded-lg border p-4 text-sm hover:bg-gray-50 transition-colors",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"Farmer Plan User Guide"}),e.jsx("p",{className:"text-gray-500 text-xs mt-0.5",children:"Step-by-step guide to all features"})]}),e.jsx($s,{className:"w-4 h-4 text-gray-400 shrink-0"})]})})]}),e.jsxs(F,{children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Us,{className:"w-5 h-5"}),"Feedback"]})}),e.jsxs(A,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(p,{htmlFor:"feedback",className:"text-base font-medium",children:"Share your thoughts"}),e.jsx("p",{className:"text-sm text-gray-600",children:"We'd love to hear your feedback, suggestions, or report any issues you've encountered."}),e.jsx(ns,{id:"feedback",placeholder:"Type your feedback here...",value:le,onChange:s=>Ve(s.target.value),className:"min-h-[120px] resize-none","data-testid":"feedback-textarea"})]}),e.jsxs(c,{onClick:hs,disabled:Se.isPending||!le.trim(),className:"w-full bg-brand-green hover:bg-brand-green/90 text-white","data-testid":"submit-feedback-button",children:[e.jsx(Vs,{className:"w-4 h-4 mr-2"}),Se.isPending?"Sending...":"Send Feedback"]})]})]})]})]})}function Gs(){const{user:t,logoutMutation:a}=Ge(),[,l]=Te(),{toast:m}=Me(),[u,i]=n.useState(!1),[r,b]=n.useState(!1),[f,h]=n.useState(""),[g,w]=n.useState(""),[v,q]=n.useState(!1),L=((t==null?void 0:t.email)||(t==null?void 0:t.username)||"").trim().toLowerCase(),I=f.trim().toLowerCase(),k=L.length>0&&I===L&&g.length>0;async function y(){i(!0);try{const o=await fetch("/api/me/export",{credentials:"include"});if(!o.ok)throw new Error("Server returned "+o.status);const M=await o.blob(),$=URL.createObjectURL(M),x=document.createElement("a");x.href=$;const R=new Date().toISOString().slice(0,10);x.download=`stockscore-export-${R}.json`,document.body.appendChild(x),x.click(),x.remove(),URL.revokeObjectURL($),m({title:"Export ready",description:"Your data has been downloaded."})}catch(o){m({title:"Export failed",description:o.message||"Please try again or email [email protected].",variant:"destructive"})}finally{i(!1)}}async function N(){await a.mutateAsync(),l("/auth")}async function T(){var o;if(k){q(!0);try{const M=await U("POST","/api/me/delete-account",{confirmEmail:f,password:g});if(!M.ok){const x=await M.json().catch(()=>({}));throw new Error(((o=x==null?void 0:x.error)==null?void 0:o.message)||"Failed to delete account")}const{wipeLocalUserData:$}=await Ss(async()=>{const{wipeLocalUserData:x}=await import("./index-C9G79VZA.js").then(R=>R.bf);return{wipeLocalUserData:x}},__vite__mapDeps([0,1]));await $(),m({title:"Account deleted",description:"Your data has been removed. A confirmation has been emailed to you."}),window.location.href="/auth"}catch(M){m({title:"Couldn't delete account",description:M.message,variant:"destructive"}),q(!1)}}}return e.jsxs(F,{"data-testid":"card-privacy-data",children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Xe,{className:"w-5 h-5"}),"Privacy & Data"]})}),e.jsxs(A,{className:"space-y-4",c
32hildren:[e.jsxs("p",{className:"text-sm text-gray-600",children:["Your data is yours. Read our"," ",e.jsx("a",{href:"/privacy",className:"text-brand-green underline",children:"Privacy Policy"})," ","and"," ",e.jsx("a",{href:"/terms",className:"text-brand-green underline",children:"Terms of Service"}),"."]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(p,{className:"text-base font-medium",children:"Export my data"}),e.jsx("p",{className:"text-sm text-gray-600",children:"Download a JSON file containing every farm, stock class, recording session, score, and setting we hold for you."}),e.jsx(c,{onClick:y,disabled:u,variant:"outline",className:"w-full","data-testid":"button-export-data",children:u?e.jsxs(e.Fragment,{children:[e.jsx(be,{className:"w-4 h-4 mr-2 animate-spin"})," Preparing exportâ¦"]}):e.jsxs(e.Fragment,{children:[e.jsx(qs,{className:"w-4 h-4 mr-2"})," Export my data"]})})]}),e.jsxs("div",{className:"space-y-2 pt-2 border-t",children:[e.jsx(p,{className:"text-base font-medium",children:"Sign out"}),e.jsx("p",{className:"text-sm text-gray-600",children:"Signing out clears the offline copy of your data from this device. Useful on a shared iPad."}),e.jsx(c,{onClick:N,disabled:a.isPending,variant:"outline",className:"w-full","data-testid":"button-sign-out",children:a.isPending?e.jsxs(e.Fragment,{children:[e.jsx(be,{className:"w-4 h-4 mr-2 animate-spin"})," Signing outâ¦"]}):e.jsxs(e.Fragment,{children:[e.jsx(Ls,{className:"w-4 h-4 mr-2"})," Sign out"]})})]}),e.jsxs("div",{className:"space-y-2 pt-2 border-t",children:[e.jsx(p,{className:"text-base font-medium text-red-700",children:"Delete my account"}),e.jsx("p",{className:"text-sm text-gray-600",children:"Permanently deletes your account, the farms you own, and all records in them. This cannot be undone."}),e.jsxs(Z,{open:r,onOpenChange:o=>{b(o),o||(h(""),w(""))},children:[e.jsx(G,{asChild:!0,children:e.jsxs(c,{variant:"destructive",className:"w-full","data-testid":"button-delete-account",children:[e.jsx(We,{className:"w-4 h-4 mr-2"}),"Delete my account"]})}),e.jsxs(Q,{children:[e.jsxs(W,{children:[e.jsx(J,{children:"Delete your account?"}),e.jsxs(X,{children:["This will permanently remove your account and every farm you own â including all stock classes, recording sessions, scores, and billing records. Any farm you joined as a member or viewer stays with its owner; only your membership is removed."," ","Backups may retain a copy for up to 30 days, after which the data is unrecoverable."]})]}),e.jsxs("div",{className:"space-y-2 my-2",children:[e.jsxs(p,{htmlFor:"confirm-email-input",className:"text-sm",children:["Type ",e.jsx("strong",{children:L})," to confirm:"]}),e.jsx(O,{id:"confirm-email-input",type:"email",value:f,onChange:o=>h(o.target.value),placeholder:"[email protected]",autoComplete:"off","data-testid":"input-confirm-delete-email"}),e.jsx(p,{htmlFor:"confirm-password-input",className:"text-sm pt-2 block",children:"Enter your current password:"}),e.jsx(O,{id:"confirm-password-input",type:"password",value:g,onChange:o=>w(o.target.value),autoComplete:"current-password","data-testid":"input-confirm-delete-password"})]}),e.jsxs(ee,{children:[e.jsx(se,{disabled:v,children:"Keep my account"}),e.jsx(ae,{onClick:o=>{o.preventDefault(),T()},disabled:!k||v,className:"bg-red-600 hover:bg-red-700","data-testid":"button-confirm-delete-account",children:v?"Deletingâ¦":"Delete forever"})]})]})]})]})]})]})}function Qs(){const[,t]=Te(),{toast:a}=Me(),l=Ze(),{data:m,isLoading:u}=De({queryKey:["/api/advisor-status"]}),i=C({mutationFn:async()=>{const g=await U("POST","/api/billing/cancel-advisor-subscription",{});if(!g.ok){const w=await g.json().catch(()=>({}));throw new Error(w.message??"Failed to cancel")}return g.json()},onSuccess:()=>{a({title:"Advisor plan cancelled",description:"Access continues until the end of the period."}),l.invalidateQueries({queryKey:["/api/advisor-status"]})},onError:g=>{a({title:"Couldn't cancel",description:g.message,variant:"destructive"})}});if(u||!m)return null;const{active:r,currentPeriodEnd:b,cancelAtPeriodEnd:f,hiddenFarmCount:h}=m;return!r&&h===0?null:e.jsxs(F,{"data-testid":"card-advisor-subscription",children:[e.jsx(E,{children:e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(Je,{className:"w-5 h-5"}),"Advisor subscription"]})}),e.jsxs(A,{className:"space-y-4",children:[!r&&h>0&&e.jsxs("div",{className:"p-3 bg-orange-50 rounded-lg border border-orange-200 flex items-start gap-2",children:[e.jsx(Ae,{className:"w-5 h-5 text-orange-600 mt-0.5 shrink-0"}),e.jsxs("div",{className:"text-sm text-orange-800",children:[e.jsx("p",{className:"font-medium",children:h===1?"1 farm hidden":`${h} farms hidden`}),e.jsx("p",{children:"You have access to farms from more than one owner. The Advisor plan ($179 NZD/year excl. GST) is a per-person subscription that lets you work across farms from any number of owners â whether each owner adds you as an editor or a read-only viewer. It's separate from each farm's own plan, and you never get billing or admin control over their farms."})]})]}),r&&e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:"font-medium text-brand-green","data-testid":"text-advisor-active",children:"Active â work across farms from any number of owners."}),b&&e.jsxs("p",{className:"text-gray-600 mt-1",children:[f?"Access until: ":"Renews on: ",new Date(b*1e3).toLocaleDateString("en-NZ",{year:"numeric",month:"long",day:"numeric"})]})]}),f&&e.jsxs("div",{className:"p-3 bg-orange-50 rounded-lg border border-orange-200 flex items-start gap-2",children:[e.jsx(Ae,{className:"w-5 h-5 text-orange-600 mt-0.5 shrink-0"}),e.jsx("p",{className:"text-sm text-orange-800",children:"Your Advisor subscription is set to cancel. You'll keep cross-owner viewing access until the end of the peri
32od."})]}),!r&&e.jsx(c,{className:"w-full bg-brand-green hover:bg-brand-green/90 text-white",onClick:()=>t("/subscribe-advisor"),"data-testid":"button-go-subscribe-advisor",children:"Subscribe â $179 NZD/year excl. GST"}),r&&!f&&e.jsxs(Z,{children:[e.jsx(G,{asChild:!0,children:e.jsxs(c,{variant:"destructive",className:"w-full","data-testid":"button-cancel-advisor",children:[e.jsx(Qe,{className:"w-4 h-4 mr-2"}),"Cancel Advisor Subscription"]})}),e.jsxs(Q,{children:[e.jsxs(W,{children:[e.jsx(J,{children:"Cancel Advisor subscription?"}),e.jsx(X,{children:"You'll keep cross-owner access until the end of your current billing period. After that, you'll only be able to work on farms from one owner â whether as an editor or a viewer â unless you re-subscribe."})]}),e.jsxs(ee,{children:[e.jsx(se,{children:"Keep Subscription"}),e.jsx(ae,{onClick:()=>i.mutate(),className:"bg-red-600 hover:bg-red-700",disabled:i.isPending,children:"Cancel Subscription"})]})]})]})]})]})}export{ua 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.