all these changes

This commit is contained in:
Jake Kasper
2026-04-09 13:19:47 -05:00
parent e83a51a051
commit 65315f36d1
39102 changed files with 7932979 additions and 567 deletions
+14 -17
View File
@@ -1,26 +1,23 @@
###
### Frontend development image (hot reload)
### Runs CRA dev server for fast iteration behind Traefik
###
FROM node:18-alpine
FROM node:20-alpine AS build
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm install --silent
RUN npm ci --silent
# Copy source code
COPY . .
# Dev-friendly env for Docker volumes
ENV CHOKIDAR_USEPOLLING=true \
WATCHPACK_POLLING=true \
WDS_SOCKET_PORT=0 \
DANGEROUSLY_DISABLE_HOST_CHECK=true
ARG VITE_API_URL=/api
ENV VITE_API_URL=${VITE_API_URL}
EXPOSE 3000
RUN npm run build
# Start CRA dev server (HMR)
CMD ["npm", "start"]
FROM nginx:1.27-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD wget -q -O /dev/null http://127.0.0.1/ || exit 1
+14
View File
@@ -0,0 +1,14 @@
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --silent
COPY . .
ENV CHOKIDAR_USEPOLLING=true
EXPOSE 3000
CMD ["npm", "run", "dev"]
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+5
View File
@@ -0,0 +1,5 @@
import{r as n,j as s,L as z,M as B,T as _,a1 as $,l as q,n as O,P as R,a4 as p}from"./index-9FS9bw8D.js";const K=()=>{const[C,v]=n.useState(!0),[M,E]=n.useState([]),[g,T]=n.useState(""),[i,k]=n.useState(null),[d,h]=n.useState(null),[b,N]=n.useState(""),[f,w]=n.useState(""),[r,u]=n.useState(null),[S,o]=n.useState([]),P=async()=>{var e,a;try{v(!0);const t=await p.getProperties({search:g});E(((a=(e=t.data)==null?void 0:e.data)==null?void 0:a.properties)||[])}finally{v(!1)}};n.useEffect(()=>{P()},[g]);const y=async e=>{var t,l;const a=await p.getProperty(e);k(((l=(t=a.data)==null?void 0:t.data)==null?void 0:l.property)||null)},G=e=>{h(e),N(e.name),w(e.grassType||(e.grassTypes||[]).join(", "))},L=e=>{var a,t;u(e.id),o(((t=(a=e.polygonData)==null?void 0:a.coordinates)==null?void 0:t[0])||[])},A=async()=>{const e=f.split(",").map(t=>t.trim()).filter(Boolean),a={name:b,area:d.area,polygonData:d.polygonData,grassType:e.join(", "),grassTypes:e};await p.updateSectionAdmin(i.id,d.id,a),await y(i.id),h(null)},D=async()=>{const e=(i.sections||[]).find(t=>t.id===r),a={...e.polygonData||{},coordinates:[S]};await p.updateSectionAdmin(i.id,r,{name:e.name,area:e.area,polygonData:a,grassType:e.grassType,grassTypes:e.grassTypes}),await y(i.id),u(null),o([])},I=()=>{u(null),o([])};return C?s.jsx("div",{className:"p-6",children:s.jsx(z,{})}):s.jsxs("div",{className:"p-6",children:[s.jsxs("div",{className:"flex justify-between items-center mb-4",children:[s.jsx("h1",{className:"text-2xl font-bold",children:"Admin: Properties"}),s.jsx("input",{className:"input w-64",placeholder:"Search by name/address/email",value:g,onChange:e=>T(e.target.value)})]}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[s.jsxs("div",{className:"card",children:[s.jsx("h3",{className:"font-semibold mb-2",children:"All Properties"}),s.jsx("div",{className:"max-h-[60vh] overflow-auto divide-y",children:M.map(e=>s.jsxs("div",{className:`p-3 hover:bg-gray-50 cursor-pointer ${(i==null?void 0:i.id)===e.id?"bg-blue-50":""}`,onClick:()=>y(e.id),children:[s.jsxs("div",{className:"flex justify-between items-center",children:[s.jsxs("div",{children:[s.jsx("div",{className:"font-medium",children:e.name}),s.jsx("div",{className:"text-xs text-gray-600",children:e.userEmail})]}),s.jsxs("div",{className:"text-sm text-gray-700",children:[e.sectionCount," sections • ",(e.calculatedArea||0).toLocaleString()," sq ft"]})]}),s.jsx("div",{className:"text-xs text-gray-500",children:e.address})]},e.id))})]}),s.jsx("div",{className:"card",children:i?s.jsxs("div",{children:[s.jsx("div",{className:"flex justify-between items-center mb-2",children:s.jsxs("div",{children:[s.jsx("h3",{className:"font-semibold",children:i.name}),s.jsx("div",{className:"text-xs text-gray-600",children:i.userEmail})]})}),s.jsx("div",{className:"h-64 rounded overflow-hidden mb-3",children:s.jsxs(B,{center:[i.latitude||39.8,i.longitude||-98.6],zoom:16,style:{height:"100%",width:"100%"},children:[s.jsx(_,{attribution:"© Esri",url:"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"}),(i.sections||[]).map(e=>{var a,t;return s.jsx($,{positions:((t=(a=e.polygonData)==null?void 0:a.coordinates)==null?void 0:t[0])||[],pathOptions:{color:e.id===r?"#f59e0b":"#10b981",weight:2,fillOpacity:.2}},e.id)}),r&&S.map((e,a)=>s.jsx(q,{position:e,draggable:!0,eventHandlers:{dragend:t=>{const{lat:l,lng:m}=t.target.getLatLng();o(x=>x.map((c,j)=>j===a?[l,m]:c))}},icon:new O.Icon({iconUrl:"data:image/svg+xml;base64,"+btoa(`
<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<circle cx="6" cy="6" r="5" fill="#f59e0b" stroke="white" stroke-width="2"/>
</svg>
`),iconSize:[12,12],iconAnchor:[6,6]}),children:s.jsx(R,{children:s.jsxs("div",{className:"text-xs",children:["Point ",a+1]})})},`ed-${a}`))]})}),r&&s.jsxs("div",{className:"mb-3 flex gap-2",children:[s.jsx("button",{className:"btn-primary",onClick:D,children:"Save Geometry"}),s.jsx("button",{className:"btn-secondary",onClick:I,children:"Cancel"})]}),s.jsx("h4",{className:"font-medium mb-2",children:"Sections"}),s.jsx("div",{className:"space-y-2 max-h-[40vh] overflow-auto",children:(i.sections||[]).map(e=>{var a,t,l,m,x;return s.jsxs("div",{className:"p-2 border rounded flex justify-between items-center",children:[s.jsxs("div",{children:[s.jsx("div",{className:"font-medium text-sm",children:e.name}),s.jsxs("div",{className:"text-xs text-gray-600",children:[(e.area||0).toLocaleString()," sq ft"]}),s.jsxs("div",{className:"mt-1 flex items-center gap-2",children:[e.captureMethod&&s.jsx("span",{className:`px-1.5 py-0.5 text-[10px] rounded ${e.captureMethod==="gps_points"?"bg-blue-100 text-blue-800":e.captureMethod==="gps_trace"?"bg-yellow-100 text-yellow-800":"bg-gray-100 text-gray-700"}`,children:e.captureMethod}),((a=e.captureMeta)==null?void 0:a.pointsCount)&&s.jsxs("span",{className:"text-[10px] text-gray-600",children:[e.captureMeta.pointsCount," pts"]}),((t=e.captureMeta)==null?void 0:t.accuracyLast)&&s.jsxs("span",{className:"text-[10px] text-gray-600",children:["±",Math.round(e.captureMeta.accuracyLast)," m"]}),((l=e.captureMeta)==null?void 0:l.totalDistanceMeters)&&s.jsxs("span",{className:"text-[10px] text-gray-600",children:[Math.round(e.captureMeta.totalDistanceMeters*3.28084)," ft walked"]})]}),(((m=e.grassTypes)==null?void 0:m.length)>0||e.grassType)&&s.jsx("div",{className:"mt-1 flex flex-wrap gap-1",children:((x=e.grassTypes)!=null&&x.length?e.grassTypes:(e.grassType||"").split(",").map(c=>c.trim()).filter(Boolean)).map((c,j)=>s.jsx("span",{className:"px-1.5 py-0.5 text-[10px] rounded bg-green-100 text-green-800",children:c},j))})]}),s.jsxs("div",{className:"flex gap-2",children:[s.jsx("button",{className:"btn-secondary",onClick:()=>G(e),children:"Edit"}),s.jsx("button",{className:"btn-secondary",onClick:()=>L(e),children:"Edit Geometry"})]})]},e.id)})})]}):s.jsx("div",{className:"text-gray-500",children:"Select a property to view details"})})]}),d&&s.jsx("div",{className:"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50",children:s.jsxs("div",{className:"bg-white rounded-lg p-6 w-full max-w-lg",children:[s.jsx("h3",{className:"font-semibold mb-3",children:"Edit Section"}),s.jsxs("div",{className:"space-y-3",children:[s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Name"}),s.jsx("input",{className:"input",value:b,onChange:e=>N(e.target.value)})]}),s.jsxs("div",{children:[s.jsx("label",{className:"label",children:"Grass Types (comma separated)"}),s.jsx("input",{className:"input",value:f,onChange:e=>w(e.target.value),placeholder:"e.g., Kentucky Bluegrass, Perennial Ryegrass"})]})]}),s.jsxs("div",{className:"mt-4 flex justify-end gap-2",children:[s.jsx("button",{className:"btn-secondary",onClick:()=>h(null),children:"Cancel"}),s.jsx("button",{className:"btn-primary",onClick:A,children:"Save"})]})]})})]})};export{K as default};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{j as t,N as a}from"./index-9FS9bw8D.js";const e=()=>t.jsx(a,{to:"/applications?action=log",replace:!0});export{e as default};
+1
View File
@@ -0,0 +1 @@
import{j as a,N as t}from"./index-9FS9bw8D.js";const p=()=>a.jsx(t,{to:"/applications?new=plan",replace:!0});export{p as default};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{r as e}from"./index-9FS9bw8D.js";function a({title:r,titleId:o,...t},n){return e.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:n,"aria-labelledby":o},t),r?e.createElement("title",{id:o},r):null,e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4.5 10.5 12 3m0 0 7.5 7.5M12 3v18"}))}const i=e.forwardRef(a);export{i as F};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
import{r as e}from"./index-9FS9bw8D.js";function a({title:r,titleId:t,...o},n){return e.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:n,"aria-labelledby":t},o),r?e.createElement("title",{id:t},r):null,e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"}))}const i=e.forwardRef(a);export{i as F};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{r as e}from"./index-9FS9bw8D.js";function a({title:r,titleId:t,...n},o){return e.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:o,"aria-labelledby":t},n),r?e.createElement("title",{id:t},r):null,e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"}))}const i=e.forwardRef(a);export{i as F};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{r as e}from"./index-9FS9bw8D.js";function a({title:r,titleId:t,...o},n){return e.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:n,"aria-labelledby":t},o),r?e.createElement("title",{id:t},r):null,e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"m20.25 7.5-.625 10.632a2.25 2.25 0 0 1-2.247 2.118H6.622a2.25 2.25 0 0 1-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125Z"}))}const i=e.forwardRef(a);function c({title:r,titleId:t,...o},n){return e.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:n,"aria-labelledby":t},o),r?e.createElement("title",{id:t},r):null,e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.347a1.125 1.125 0 0 1 0 1.972l-11.54 6.347a1.125 1.125 0 0 1-1.667-.986V5.653Z"}))}const s=e.forwardRef(c);export{s as F,i as a};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{r as e}from"./index-9FS9bw8D.js";function a({title:r,titleId:t,...o},n){return e.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:n,"aria-labelledby":t},o),r?e.createElement("title",{id:t},r):null,e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4.5 12a7.5 7.5 0 0 0 15 0m-15 0a7.5 7.5 0 1 1 15 0m-15 0H3m16.5 0H21m-1.5 0H12m-8.457 3.077 1.41-.513m14.095-5.13 1.41-.513M5.106 17.785l1.15-.964m11.49-9.642 1.149-.964M7.501 19.795l.75-1.3m7.5-12.99.75-1.3m-6.063 16.658.26-1.477m2.605-14.772.26-1.477m0 17.726-.26-1.477M10.698 4.614l-.26-1.477M16.5 19.794l-.75-1.299M7.5 4.205 12 12m6.894 5.785-1.149-.964M6.256 7.178l-1.15-.964m15.352 8.864-1.41-.513M4.954 9.435l-1.41-.514M12.002 12l-3.75 6.495"}))}const i=e.forwardRef(a);function l({title:r,titleId:t,...o},n){return e.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor","aria-hidden":"true","data-slot":"icon",ref:n,"aria-labelledby":t},o),r?e.createElement("title",{id:t},r):null,e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"}))}const m=e.forwardRef(l);export{m as F,i as a};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{r as h,j as e,O as f,p as S,w}from"./index-9FS9bw8D.js";const L=()=>{const[j,v]=h.useState([]),[s,p]=h.useState({}),[N,x]=h.useState(!0),[u,g]=h.useState(null);return h.useEffect(()=>{(async()=>{var d,l;try{x(!0);const r=((l=(d=(await S.getAll()).data)==null?void 0:d.data)==null?void 0:l.properties)||[];v(r);const i=r.filter(a=>a.latitude&&a.longitude).map(a=>a.id),y=await Promise.allSettled(i.map(a=>w.getCurrent(a))),o={};y.forEach((a,m)=>{const n=i[m];a.status==="fulfilled"&&(o[n]={weather:a.value.data.data.weather})}),(await Promise.allSettled(i.map(a=>w.getForecast(a)))).forEach((a,m)=>{const n=i[m];a.status==="fulfilled"&&(o[n]=o[n]||{},o[n].forecast=a.value.data.data.forecast)}),p(o),g(null)}catch(c){console.error("Failed to load weather:",c),g("Failed to load weather")}finally{x(!1)}})()},[]),e.jsxs("div",{className:"p-6",children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-6",children:"Weather"}),N?e.jsx("div",{className:"card",children:"Loading…"}):u?e.jsx("div",{className:"card text-red-700",children:u}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:j.map(t=>{var d,l,c;return e.jsxs("div",{className:"bg-white rounded-lg shadow p-4",children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsx("div",{className:"font-semibold",children:t.name}),e.jsx("div",{className:"text-xs text-gray-500",children:t.address})]}),!t.latitude||!t.longitude?e.jsx("div",{className:"text-sm text-gray-600",children:"No coordinates set"}):(d=s[t.id])!=null&&d.weather?e.jsxs("div",{className:"flex items-center",children:[e.jsx("img",{alt:"",width:"50",height:"50",src:`${f.apiBaseUrl}/weather/icon/${s[t.id].weather.current.icon}?size=2x`}),e.jsxs("div",{className:"ml-3",children:[e.jsxs("div",{className:"text-xl font-bold",children:[s[t.id].weather.current.temperature,"°F"]}),e.jsx("div",{className:"text-sm text-gray-700",children:s[t.id].weather.current.conditions}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1",children:["Humidity ",s[t.id].weather.current.humidity,"% • Wind ",Math.round(s[t.id].weather.current.windSpeed)," mph"]})]})]}):e.jsx("div",{className:"text-sm text-gray-600",children:"Loading weather…"}),((c=(l=s[t.id])==null?void 0:l.forecast)==null?void 0:c.daily)&&e.jsx("div",{className:"mt-3 grid grid-cols-5 gap-2 text-center",children:s[t.id].forecast.daily.map((r,i)=>e.jsxs("div",{className:"text-xs text-gray-700",children:[e.jsx("div",{className:"font-medium",children:new Date(r.date).toLocaleDateString(void 0,{weekday:"short"})}),e.jsx("img",{alt:"",className:"mx-auto",width:"40",height:"40",src:`${f.apiBaseUrl}/weather/icon/${r.icon}?size=2x`}),e.jsxs("div",{children:[r.temperatureHigh,"° / ",r.temperatureLow,"°"]})]},i))})]},t.id)})})]})};export{L as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

+40
View File
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/png" href="/brand/logo.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/brand/favicon-32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/brand/favicon-16.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#059669" />
<meta
name="description"
content="TurfTracking - Professional lawn care management and tracking application"
/>
<link rel="apple-touch-icon" href="/brand/apple-touch-icon.png" />
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
rel="stylesheet"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="TurfTracking" />
<title>TurfTracking - Lawn Care Management</title>
<script type="module" crossorigin src="/assets/index-9FS9bw8D.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DG9A8wSV.css">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="loading-indicator" class="fixed inset-0 flex items-center justify-center bg-green-50 z-50">
<div class="text-center">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-green-600 mx-auto mb-4"></div>
<h2 class="text-xl font-semibold text-green-800">TurfTracking</h2>
<p class="text-green-600">Loading your lawn care dashboard...</p>
</div>
</div>
</body>
</html>
+20
View File
@@ -0,0 +1,20 @@
{
"short_name": "TurfTracking",
"name": "TurfTracking",
"icons": [
{
"src": "/brand/logo.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "/brand/logo.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "/",
"display": "standalone",
"theme_color": "#059669",
"background_color": "#ffffff"
}
+39
View File
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/png" href="/brand/logo.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/brand/favicon-32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/brand/favicon-16.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#059669" />
<meta
name="description"
content="TurfTracking - Professional lawn care management and tracking application"
/>
<link rel="apple-touch-icon" href="/brand/apple-touch-icon.png" />
<link rel="manifest" href="/manifest.json" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
rel="stylesheet"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="TurfTracking" />
<title>TurfTracking - Lawn Care Management</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="loading-indicator" class="fixed inset-0 flex items-center justify-center bg-green-50 z-50">
<div class="text-center">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-green-600 mx-auto mb-4"></div>
<h2 class="text-xl font-semibold text-green-800">TurfTracking</h2>
<p class="text-green-600">Loading your lawn care dashboard...</p>
</div>
</div>
<script type="module" src="/src/index.js"></script>
</body>
</html>
+16
View File
@@ -0,0 +1,16 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
}
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../atob/bin/atob.js
+1
View File
@@ -0,0 +1 @@
../autoprefixer/bin/autoprefixer
+1
View File
@@ -0,0 +1 @@
../baseline-browser-mapping/dist/cli.cjs
+1
View File
@@ -0,0 +1 @@
../browserslist/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../btoa/bin/btoa.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../cssesc/bin/cssesc
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../esbuild/bin/esbuild
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../topojson-server/bin/geo2topo
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../jiti/bin/jiti.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../jsesc/bin/jsesc
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../json5/lib/cli.js
+1
View File
@@ -0,0 +1 @@
../loose-envify/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../lz-string/bin/bin.js
+1
View File
@@ -0,0 +1 @@
../mini-svg-data-uri/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../@babel/parser/bin/babel-parser.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../resolve/bin/resolve
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../rimraf/bin.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../rollup/dist/bin/rollup
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../semver/bin/semver.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../sucrase/bin/sucrase
+1
View File
@@ -0,0 +1 @@
../sucrase/bin/sucrase-node
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../tailwindcss/lib/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../tailwindcss/lib/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../topojson-client/bin/topo2geo
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../topojson-client/bin/topomerge
+1
View File
@@ -0,0 +1 @@
../topojson-client/bin/topoquantize
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../typescript/bin/tsc
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../typescript/bin/tsserver
+1
View File
@@ -0,0 +1 @@
../update-browserslist-db/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vite/bin/vite.js
+6803
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+41493
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+118
View File
@@ -0,0 +1,118 @@
{
"hash": "669f2079",
"configHash": "204a67eb",
"lockfileHash": "19491142",
"browserHash": "f00de744",
"optimized": {
"react": {
"src": "../../react/index.js",
"file": "react.js",
"fileHash": "916ecdfe",
"needsInterop": true
},
"react-dom": {
"src": "../../react-dom/index.js",
"file": "react-dom.js",
"fileHash": "b187c794",
"needsInterop": true
},
"react/jsx-dev-runtime": {
"src": "../../react/jsx-dev-runtime.js",
"file": "react_jsx-dev-runtime.js",
"fileHash": "6c382da3",
"needsInterop": true
},
"react/jsx-runtime": {
"src": "../../react/jsx-runtime.js",
"file": "react_jsx-runtime.js",
"fileHash": "b6b2a22a",
"needsInterop": true
},
"@heroicons/react/24/outline": {
"src": "../../@heroicons/react/24/outline/esm/index.js",
"file": "@heroicons_react_24_outline.js",
"fileHash": "898cd2a8",
"needsInterop": false
},
"@heroicons/react/24/solid": {
"src": "../../@heroicons/react/24/solid/esm/index.js",
"file": "@heroicons_react_24_solid.js",
"fileHash": "dedf98cc",
"needsInterop": false
},
"@turf/turf": {
"src": "../../@turf/turf/dist/es/index.js",
"file": "@turf_turf.js",
"fileHash": "f7dc9246",
"needsInterop": false
},
"axios": {
"src": "../../axios/index.js",
"file": "axios.js",
"fileHash": "c0136b55",
"needsInterop": false
},
"clsx": {
"src": "../../clsx/dist/clsx.mjs",
"file": "clsx.js",
"fileHash": "2a4868e1",
"needsInterop": false
},
"leaflet": {
"src": "../../leaflet/dist/leaflet-src.js",
"file": "leaflet.js",
"fileHash": "97859145",
"needsInterop": true
},
"react-dom/client": {
"src": "../../react-dom/client.js",
"file": "react-dom_client.js",
"fileHash": "3785c943",
"needsInterop": true
},
"react-hook-form": {
"src": "../../react-hook-form/dist/index.esm.mjs",
"file": "react-hook-form.js",
"fileHash": "0bb780a8",
"needsInterop": false
},
"react-hot-toast": {
"src": "../../react-hot-toast/dist/index.mjs",
"file": "react-hot-toast.js",
"fileHash": "3c168d08",
"needsInterop": false
},
"react-leaflet": {
"src": "../../react-leaflet/lib/index.js",
"file": "react-leaflet.js",
"fileHash": "99c829d9",
"needsInterop": false
},
"react-query": {
"src": "../../react-query/es/index.js",
"file": "react-query.js",
"fileHash": "9a503e2a",
"needsInterop": false
},
"react-router-dom": {
"src": "../../react-router-dom/dist/index.js",
"file": "react-router-dom.js",
"fileHash": "20032dc4",
"needsInterop": false
}
},
"chunks": {
"chunk-NB5MQSEJ": {
"file": "chunk-NB5MQSEJ.js"
},
"chunk-PJEEZAML": {
"file": "chunk-PJEEZAML.js"
},
"chunk-DRWLMN53": {
"file": "chunk-DRWLMN53.js"
},
"chunk-G3PMV62Z": {
"file": "chunk-G3PMV62Z.js"
}
}
}
+2789
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+36
View File
@@ -0,0 +1,36 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
export {
__commonJS,
__export,
__toESM
};
//# sourceMappingURL=chunk-G3PMV62Z.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+21628
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+22
View File
@@ -0,0 +1,22 @@
import "./chunk-G3PMV62Z.js";
// node_modules/clsx/dist/clsx.mjs
function r(e) {
var t, f, n = "";
if ("string" == typeof e || "number" == typeof e) n += e;
else if ("object" == typeof e) if (Array.isArray(e)) {
var o = e.length;
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
} else for (f in e) e[f] && (n && (n += " "), n += f);
return n;
}
function clsx() {
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
return n;
}
var clsx_default = clsx;
export {
clsx,
clsx_default as default
};
//# sourceMappingURL=clsx.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../clsx/dist/clsx.mjs"],
"sourcesContent": ["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;"],
"mappings": ";;;AAAA,SAAS,EAAE,GAAE;AAAC,MAAI,GAAE,GAAE,IAAE;AAAG,MAAG,YAAU,OAAO,KAAG,YAAU,OAAO,EAAE,MAAG;AAAA,WAAU,YAAU,OAAO,EAAE,KAAG,MAAM,QAAQ,CAAC,GAAE;AAAC,QAAI,IAAE,EAAE;AAAO,SAAI,IAAE,GAAE,IAAE,GAAE,IAAI,GAAE,CAAC,MAAI,IAAE,EAAE,EAAE,CAAC,CAAC,OAAK,MAAI,KAAG,MAAK,KAAG;AAAA,EAAE,MAAM,MAAI,KAAK,EAAE,GAAE,CAAC,MAAI,MAAI,KAAG,MAAK,KAAG;AAAG,SAAO;AAAC;AAAQ,SAAS,OAAM;AAAC,WAAQ,GAAE,GAAE,IAAE,GAAE,IAAE,IAAG,IAAE,UAAU,QAAO,IAAE,GAAE,IAAI,EAAC,IAAE,UAAU,CAAC,OAAK,IAAE,EAAE,CAAC,OAAK,MAAI,KAAG,MAAK,KAAG;AAAG,SAAO;AAAC;AAAC,IAAO,eAAQ;",
"names": []
}
+6
View File
@@ -0,0 +1,6 @@
import {
require_leaflet_src
} from "./chunk-NB5MQSEJ.js";
import "./chunk-G3PMV62Z.js";
export default require_leaflet_src();
//# sourceMappingURL=leaflet.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}
+3
View File
@@ -0,0 +1,3 @@
{
"type": "module"
}
+7
View File
@@ -0,0 +1,7 @@
import {
require_react_dom
} from "./chunk-PJEEZAML.js";
import "./chunk-DRWLMN53.js";
import "./chunk-G3PMV62Z.js";
export default require_react_dom();
//# sourceMappingURL=react-dom.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}
+39
View File
@@ -0,0 +1,39 @@
import {
require_react_dom
} from "./chunk-PJEEZAML.js";
import "./chunk-DRWLMN53.js";
import {
__commonJS
} from "./chunk-G3PMV62Z.js";
// node_modules/react-dom/client.js
var require_client = __commonJS({
"node_modules/react-dom/client.js"(exports) {
var m = require_react_dom();
if (false) {
exports.createRoot = m.createRoot;
exports.hydrateRoot = m.hydrateRoot;
} else {
i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
exports.createRoot = function(c, o) {
i.usingClientEntryPoint = true;
try {
return m.createRoot(c, o);
} finally {
i.usingClientEntryPoint = false;
}
};
exports.hydrateRoot = function(c, h, o) {
i.usingClientEntryPoint = true;
try {
return m.hydrateRoot(c, h, o);
} finally {
i.usingClientEntryPoint = false;
}
};
}
var i;
}
});
export default require_client();
//# sourceMappingURL=react-dom_client.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../react-dom/client.js"],
"sourcesContent": ["'use strict';\n\nvar m = require('react-dom');\nif (process.env.NODE_ENV === 'production') {\n exports.createRoot = m.createRoot;\n exports.hydrateRoot = m.hydrateRoot;\n} else {\n var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n exports.createRoot = function(c, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.createRoot(c, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n exports.hydrateRoot = function(c, h, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.hydrateRoot(c, h, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n}\n"],
"mappings": ";;;;;;;;;AAAA;AAAA;AAEA,QAAI,IAAI;AACR,QAAI,OAAuC;AACzC,cAAQ,aAAa,EAAE;AACvB,cAAQ,cAAc,EAAE;AAAA,IAC1B,OAAO;AACD,UAAI,EAAE;AACV,cAAQ,aAAa,SAAS,GAAG,GAAG;AAClC,UAAE,wBAAwB;AAC1B,YAAI;AACF,iBAAO,EAAE,WAAW,GAAG,CAAC;AAAA,QAC1B,UAAE;AACA,YAAE,wBAAwB;AAAA,QAC5B;AAAA,MACF;AACA,cAAQ,cAAc,SAAS,GAAG,GAAG,GAAG;AACtC,UAAE,wBAAwB;AAC1B,YAAI;AACF,iBAAO,EAAE,YAAY,GAAG,GAAG,CAAC;AAAA,QAC9B,UAAE;AACA,YAAE,wBAAwB;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAjBM;AAAA;AAAA;",
"names": []
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More