Files
turftracker/frontend/dist/assets/Profile-1kT_Rbg4.js
2026-04-09 13:19:47 -05:00

2 lines
15 KiB
JavaScript

import{u as K,r as l,j as e,e as _,h as v,z as u}from"./index-9FS9bw8D.js";const E={emailReports:!0,weatherAlerts:!0,applicationReminders:!0,wateringReminders:!1},q=256,A=s=>{if(!s)return"N/A";try{return new Date(s).toLocaleDateString()}catch{return s}},Q=s=>new Promise((g,N)=>{const i=new FileReader;i.onload=()=>g(i.result),i.onerror=()=>N(new Error("Failed to read image")),i.readAsDataURL(s)}),Y=s=>new Promise((g,N)=>{const i=new Image;i.onload=()=>{const n=Math.min(q/i.width,q/i.height,1),o=Math.max(1,Math.round(i.width*n)),x=Math.max(1,Math.round(i.height*n)),h=document.createElement("canvas");h.width=o,h.height=x;const p=h.getContext("2d");if(!p){N(new Error("Failed to prepare image preview"));return}p.drawImage(i,0,0,o,x),g(h.toDataURL("image/jpeg",.82))},i.onerror=()=>N(new Error("Invalid image file")),i.src=s}),ee=s=>{if(!s||typeof s!="string")return"";if(s.startsWith("data:image/")||s.startsWith("blob:")||s.startsWith("/"))return s;try{const g=new URL(s,window.location.origin);if(g.origin===window.location.origin)return g.toString()}catch{return""}return""},S=s=>({firstName:(s==null?void 0:s.firstName)||"",lastName:(s==null?void 0:s.lastName)||"",email:(s==null?void 0:s.email)||"",avatarUrl:(s==null?void 0:s.avatarUrl)||"",notificationPreferences:{...E,...(s==null?void 0:s.notificationPreferences)||{}}}),z=s=>({firstName:s.firstName,lastName:s.lastName,email:s.email,role:s.role,avatarUrl:s.avatarUrl||"",notificationPreferences:{...E,...s.notificationPreferences||{}},createdAt:s.createdAt,updatedAt:s.updatedAt}),se={emailReports:{title:"Email Reports",description:"Receive report exports and operational summaries by email."},weatherAlerts:{title:"Weather Alerts",description:"Notify me when weather conditions may affect planned work."},applicationReminders:{title:"Application Reminders",description:"Send reminders for upcoming product applications."},wateringReminders:{title:"Watering Reminders",description:"Send reminders for watering plans and logged runs."}},ae={application:"Application",mowing:"Mowing",watering:"Watering"},re=()=>{const{user:s,updateUser:g,changePassword:N,logout:i}=K(),[n,o]=l.useState(S()),[x,h]=l.useState({currentPassword:"",newPassword:"",confirmPassword:""}),[p,U]=l.useState({currentPassword:"",confirmationText:""}),[r,V]=l.useState(null),[C,B]=l.useState([]),[H,R]=l.useState(!0),[b,D]=l.useState(!1),[F,L]=l.useState(!1),[w,k]=l.useState(!1),[T,M]=l.useState(!1);l.useEffect(()=>{s&&o(a=>({...a,firstName:s.firstName||"",lastName:s.lastName||"",email:s.email||"",avatarUrl:s.avatarUrl||a.avatarUrl||"",notificationPreferences:{...E,...s.notificationPreferences||a.notificationPreferences||{}}}))},[s]),l.useEffect(()=>{(async()=>{var t,c,d,m,f,j;try{R(!0);const[W,$]=await Promise.all([v.getProfile(),v.getStats()]),P=(c=(t=W.data)==null?void 0:t.data)==null?void 0:c.user;P&&(o(S(P)),g(z(P))),V(((m=(d=$.data)==null?void 0:d.data)==null?void 0:m.stats)||null),B(((j=(f=$.data)==null?void 0:f.data)==null?void 0:j.recentActivity)||[])}catch{u.error("Failed to load profile information")}finally{R(!1)}})()},[s==null?void 0:s.id]);const I=l.useMemo(()=>{var a,t;return`${((a=n.firstName)==null?void 0:a[0])||""}${((t=n.lastName)==null?void 0:t[0])||""}`.toUpperCase()},[n.firstName,n.lastName]),y=l.useMemo(()=>ee(n.avatarUrl),[n.avatarUrl]),X=l.useMemo(()=>[{label:"Properties",value:(r==null?void 0:r.totalProperties)??0},{label:"Sections",value:(r==null?void 0:r.totalSections)??0},{label:"Plans",value:(r==null?void 0:r.totalPlans)??0},{label:"Completion Rate",value:`${(r==null?void 0:r.completionRate)??0}%`}],[r]),O=async a=>{var t,c,d,m;a.preventDefault();try{D(!0);const j=(c=(t=(await v.updateProfile(n)).data)==null?void 0:t.data)==null?void 0:c.user;j&&(g(z(j)),o(S(j))),u.success("Profile updated")}catch(f){u.error(((m=(d=f.response)==null?void 0:d.data)==null?void 0:m.message)||"Failed to update profile")}finally{D(!1)}},Z=async a=>{if(a.preventDefault(),x.newPassword!==x.confirmPassword){u.error("New passwords do not match");return}try{L(!0),(await N({currentPassword:x.currentPassword,newPassword:x.newPassword})).success&&h({currentPassword:"",newPassword:"",confirmPassword:""})}finally{L(!1)}},G=async a=>{var c;const t=(c=a.target.files)==null?void 0:c[0];if(a.target.value="",!!t){if(!t.type.startsWith("image/")){u.error("Choose an image file");return}try{k(!0);const d=await Q(t),m=await Y(d);if(m.length>5e5){u.error("Image is still too large after compression. Choose a smaller file.");return}o(f=>({...f,avatarUrl:m})),u.success("Avatar ready to save")}catch(d){u.error(d.message||"Failed to process avatar")}finally{k(!1)}}},J=async a=>{var t,c;if(a.preventDefault(),p.confirmationText!=="DELETE"){u.error("Type DELETE to confirm account deletion");return}try{M(!0),await v.deleteAccount(p),i()}catch(d){u.error(((c=(t=d.response)==null?void 0:t.data)==null?void 0:c.message)||"Failed to delete account")}finally{M(!1)}};return H?e.jsxs("div",{className:"p-6",children:[e.jsx("h1",{className:"mb-6 text-2xl font-bold text-gray-900",children:"Profile"}),e.jsx("div",{className:"card p-6 text-gray-600",children:"Loading profile..."})]}):e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsx("div",{className:"flex flex-col gap-2",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"Profile"}),e.jsx("p",{className:"text-sm text-gray-600",children:"Manage identity, notifications, and account security."})]})}),e.jsxs("div",{className:"grid gap-6 xl:grid-cols-3",children:[e.jsxs("div",{className:"card p-6 xl:col-span-1",children:[e.jsxs("div",{className:"flex items-start gap-4",children:[y?e.jsx("img",{src:y,alt:"Profile avatar",className:"h-20 w-20 rounded-full border border-gray-200 object-cover"}):e.jsx("div",{className:"flex h-20 w-20 items-center justify-center rounded-full bg-green-100 text-2xl font-semibold text-green-700",children:I||"U"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"text-xl font-semibold text-gray-900",children:[n.firstName," ",n.lastName]}),e.jsx("div",{className:"truncate text-sm text-gray-600",children:n.email}),e.jsx("div",{className:"mt-2 inline-flex rounded-full bg-gray-100 px-3 py-1 text-xs font-medium uppercase tracking-wide text-gray-700",children:(s==null?void 0:s.role)||"user"})]})]}),e.jsxs("div",{className:"mt-6 grid gap-3 text-sm text-gray-700",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Member Since"}),e.jsx("span",{className:"font-medium",children:A(s==null?void 0:s.createdAt)})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Last Updated"}),e.jsx("span",{className:"font-medium",children:A(s==null?void 0:s.updatedAt)})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Equipment"}),e.jsx("span",{className:"font-medium",children:(r==null?void 0:r.totalEquipment)??0})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Applications Logged"}),e.jsx("span",{className:"font-medium",children:(r==null?void 0:r.totalApplications)??0})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Upcoming Plans"}),e.jsx("span",{className:"font-medium",children:(r==null?void 0:r.upcomingPlans)??0})]})]})]}),e.jsxs("div",{className:"space-y-6 xl:col-span-2",children:[e.jsxs("div",{className:"card p-6",children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsx("h2",{className:"text-lg font-semibold text-gray-900",children:"Overview"}),e.jsx(_,{to:"/history",className:"text-sm font-medium text-green-700 hover:text-green-800",children:"Open History"})]}),e.jsx("div",{className:"grid gap-4 md:grid-cols-4",children:X.map(a=>e.jsxs("div",{className:"rounded-lg border border-gray-200 bg-gray-50 p-4",children:[e.jsx("div",{className:"text-sm text-gray-500",children:a.label}),e.jsx("div",{className:"mt-1 text-2xl font-semibold text-gray-900",children:a.value})]},a.label))})]}),e.jsxs("div",{className:"card p-6",children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsx("h2",{className:"text-lg font-semibold text-gray-900",children:"Recent Activity"}),e.jsx("span",{className:"text-sm text-gray-500",children:"Latest completed work"})]}),e.jsxs("div",{className:"space-y-3",children:[C.length===0&&e.jsx("div",{className:"rounded-lg border border-dashed border-gray-200 p-4 text-sm text-gray-500",children:"No recent activity yet."}),C.map((a,t)=>e.jsxs("div",{className:"flex flex-col gap-3 rounded-lg border border-gray-200 p-4 md:flex-row md:items-start md:justify-between",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"rounded-full bg-green-50 px-2.5 py-1 text-xs font-medium text-green-700",children:ae[a.type]||a.type}),e.jsx("span",{className:"text-sm text-gray-500",children:A(a.date)})]}),e.jsxs("div",{className:"font-medium text-gray-900",children:[a.propertyName||"Property",a.sectionName?` - ${a.sectionName}`:""]}),a.detail&&e.jsx("div",{className:"mt-1 text-sm text-gray-600",children:a.detail}),a.metric&&e.jsx("div",{className:"mt-1 text-sm font-medium text-gray-700",children:a.metric})]}),e.jsx(_,{to:a.href||"/history",className:"inline-flex items-center justify-center rounded-md border border-gray-300 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50",children:"View Activity"})]},`${a.type}-${a.activityId||a.date}-${t}`))]})]})]})]}),e.jsxs("div",{className:"grid gap-6 xl:grid-cols-2",children:[e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"card p-6",children:[e.jsx("h2",{className:"mb-4 text-lg font-semibold text-gray-900",children:"Personal Information"}),e.jsx("form",{className:"space-y-6",onSubmit:O,children:e.jsxs("div",{className:"grid gap-6 lg:grid-cols-[220px,1fr]",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"text-sm font-medium text-gray-700",children:"Profile Photo"}),e.jsxs("div",{className:"flex flex-col items-center gap-3 rounded-lg border border-dashed border-gray-300 bg-gray-50 p-4",children:[y?e.jsx("img",{src:y,alt:"Avatar preview",className:"h-28 w-28 rounded-full border border-gray-200 object-cover"}):e.jsx("div",{className:"flex h-28 w-28 items-center justify-center rounded-full bg-green-100 text-3xl font-semibold text-green-700",children:I||"U"}),e.jsxs("label",{className:"btn-secondary cursor-pointer",children:[w?"Processing...":"Upload Photo",e.jsx("input",{type:"file",accept:"image/*",className:"hidden",onChange:G})]}),n.avatarUrl&&e.jsx("button",{type:"button",className:"text-sm text-red-600 hover:text-red-700",onClick:()=>o(a=>({...a,avatarUrl:""})),children:"Remove photo"})]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"First Name"}),e.jsx("input",{className:"input",value:n.firstName,onChange:a=>o(t=>({...t,firstName:a.target.value}))})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Last Name"}),e.jsx("input",{className:"input",value:n.lastName,onChange:a=>o(t=>({...t,lastName:a.target.value}))})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Email Address"}),e.jsx("input",{type:"email",className:"input",value:n.email,onChange:a=>o(t=>({...t,email:a.target.value}))})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{className:"btn-primary",type:"submit",disabled:b||w,children:b?"Saving...":"Save Changes"})})]})]})})]}),e.jsxs("div",{className:"card p-6",children:[e.jsx("h2",{className:"mb-4 text-lg font-semibold text-gray-900",children:"Notifications"}),e.jsx("div",{className:"space-y-3",children:Object.entries(se).map(([a,t])=>{var c;return e.jsxs("label",{className:"flex items-start justify-between gap-4 rounded-lg border border-gray-200 p-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-gray-900",children:t.title}),e.jsx("div",{className:"text-sm text-gray-600",children:t.description})]}),e.jsx("input",{type:"checkbox",className:"mt-1 h-4 w-4 rounded border-gray-300 text-green-600 focus:ring-green-500",checked:!!((c=n.notificationPreferences)!=null&&c[a]),onChange:d=>o(m=>({...m,notificationPreferences:{...m.notificationPreferences,[a]:d.target.checked}}))})]},a)})}),e.jsx("div",{className:"mt-4 flex justify-end",children:e.jsx("button",{className:"btn-primary",type:"button",onClick:O,disabled:b||w,children:b?"Saving...":"Save Preferences"})})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"card p-6",children:[e.jsx("h2",{className:"mb-4 text-lg font-semibold text-gray-900",children:"Security"}),e.jsxs("form",{className:"space-y-4",onSubmit:Z,children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Current Password"}),e.jsx("input",{type:"password",className:"input",value:x.currentPassword,onChange:a=>h(t=>({...t,currentPassword:a.target.value}))})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"New Password"}),e.jsx("input",{type:"password",className:"input",value:x.newPassword,onChange:a=>h(t=>({...t,newPassword:a.target.value}))})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Confirm New Password"}),e.jsx("input",{type:"password",className:"input",value:x.confirmPassword,onChange:a=>h(t=>({...t,confirmPassword:a.target.value}))})]})]}),e.jsx("p",{className:"text-xs text-gray-500",children:"Use at least 8 characters with uppercase, lowercase, number, and special character."}),e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{className:"btn-primary",type:"submit",disabled:F,children:F?"Updating...":"Change Password"})})]})]}),e.jsxs("div",{className:"card border border-red-200 p-6",children:[e.jsx("h2",{className:"mb-2 text-lg font-semibold text-red-700",children:"Danger Zone"}),e.jsx("p",{className:"mb-4 text-sm text-gray-600",children:"Deleting your account permanently removes your profile and related data. Ongoing planned applications must be cleared first."}),e.jsxs("form",{className:"space-y-4",onSubmit:J,children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Current Password"}),e.jsx("input",{type:"password",className:"input",value:p.currentPassword,onChange:a=>U(t=>({...t,currentPassword:a.target.value}))})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Type DELETE to confirm"}),e.jsx("input",{className:"input",value:p.confirmationText,onChange:a=>U(t=>({...t,confirmationText:a.target.value}))})]}),e.jsx("button",{className:"btn-secondary w-full border-red-300 text-red-700 hover:bg-red-50",type:"submit",disabled:T,children:T?"Deleting...":"Delete Account"})]})]})]})]})]})};export{re as default};