From 39c23eef2f0268f50ae1ca342208870b3ea8a58d Mon Sep 17 00:00:00 2001 From: anibilag Date: Sun, 29 Jun 2025 17:37:49 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D1=8B=D0=B9=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BC=D0=B8=D1=82=20-=20=D1=80=D1=83=D1=81=D1=81=D0=B8?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lawn_scheduler.db | Bin 0 -> 12288 bytes package-lock.json | 9 +-- package.json | 18 +++--- src/components/Dashboard.tsx | 46 +++++++------- src/components/Icons.tsx | 117 +++++++++++++++++++++++++++++++++++ src/components/SitePlan.tsx | 18 +++--- src/components/ZoneCard.tsx | 18 +++--- src/components/ZoneForm.tsx | 28 ++++----- 8 files changed, 186 insertions(+), 68 deletions(-) create mode 100644 lawn_scheduler.db create mode 100644 src/components/Icons.tsx diff --git a/lawn_scheduler.db b/lawn_scheduler.db new file mode 100644 index 0000000000000000000000000000000000000000..c50dcb36b3823bb7b9d0b6230bd7eb231d91d25f GIT binary patch literal 12288 zcmeI&&u`N(6bEoSnP{0ryIZ(n#AVaAs!P=Uk`T>Sx2j0HlDZP*GI@=GiZ<1fzyud0 z_%pchXYgn6k8tFUlaQiJLfp~!sZJaF`Q`ODW5WTA};zvy=%aSVlT@~pTY!xF4*uw zkBR5y^Yf*ArA9J&oh{~b3mGSa)r|@|QXjt4O}}%)L`Co9q9fnO>*p5bSciAri6_`m zo-89Jnf~A2dZC#w%=AK{0yoLqDYl(Yd|!8aDf$CG7VcoA+uljf=4QP?>fh=&`U?R8 z2tWV=5P$##AOHafKmY;|fB@;4Rq}{DrWI#A4;1UkC{Ur@v|Ibl!+rZi95|{MxlWw#M zlTroSE?20uum0Lddj6;NpG1EU5P$##AOHafKmY;|fB*y_009X6PXc$TY0>O02lE#n C=cD}q literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index 39ebf45..f746c89 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2102,9 +2102,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", "dev": true, "funding": [ { @@ -2119,7 +2119,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "2.4.2", diff --git a/package.json b/package.json index 73fe7c4..b8de5bd 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,14 @@ "preview": "vite preview" }, "dependencies": { + "@libsql/client": "^0.4.0", + "cors": "^2.8.5", + "express": "^4.18.2", "lucide-react": "^0.344.0", + "multer": "^1.4.5-lts.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^6.26.0", - "@libsql/client": "^0.4.0", - "express": "^4.18.2", - "cors": "^2.8.5", - "multer": "^1.4.5-lts.1" + "react-router-dom": "^6.26.0" }, "devDependencies": { "@eslint/js": "^9.9.1", @@ -27,16 +27,16 @@ "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.18", + "concurrently": "^8.2.2", "eslint": "^9.9.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.11", "globals": "^15.9.0", + "nodemon": "^3.0.2", "postcss": "^8.4.35", "tailwindcss": "^3.4.1", "typescript": "^5.5.3", "typescript-eslint": "^8.3.0", - "vite": "^5.4.2", - "concurrently": "^8.2.2", - "nodemon": "^3.0.2" + "vite": "^5.4.2" } -} \ No newline at end of file +} diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx index e2cc58c..3b58c04 100644 --- a/src/components/Dashboard.tsx +++ b/src/components/Dashboard.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { Plus, Filter, Calendar, Scissors, AlertTriangle, Square, CheckCircle, Clock, Map } from 'lucide-react'; +import { Plus, Filter, Calendar, Scissors, AlertTriangle, Square, CheckCircle, Clock, Map } from './Icons'; import { Zone } from '../types/zone'; import { api } from '../services/api'; import ZoneCard from './ZoneCard'; @@ -128,9 +128,9 @@ const Dashboard: React.FC = () => {

- Lawn Care Manager + Менеджер по уходу за газоном

-

Keep track of your lawn mowing schedule

+

Следите за своим графиком стрижки газона

{/* View Toggle */} @@ -144,7 +144,7 @@ const Dashboard: React.FC = () => { }`} > - Dashboard + Панель
@@ -164,7 +164,7 @@ const Dashboard: React.FC = () => { className="bg-green-600 hover:bg-green-700 text-white px-6 py-3 rounded-lg flex items-center gap-2 transition-colors duration-200 shadow-lg hover:shadow-xl" > - Add Zone + Новая зона @@ -183,7 +183,7 @@ const Dashboard: React.FC = () => {
-

Total Zones

+

Количество зон

{zones.length}

@@ -193,9 +193,9 @@ const Dashboard: React.FC = () => {
-

Total Area

+

Общая площадь

{totalArea.toLocaleString()}

-

sq ft

+

м2

@@ -204,9 +204,9 @@ const Dashboard: React.FC = () => {
-

Mowed Area

+

Скошенная площадь

{mowedArea.toLocaleString()}

-

sq ft ({mowedPercentage.toFixed(1)}%)

+

м2 ({mowedPercentage.toFixed(1)}%)

@@ -215,9 +215,9 @@ const Dashboard: React.FC = () => {
-

Needs Mowing

+

Нужно скосить

{remainingArea.toLocaleString()}

-

sq ft ({(100 - mowedPercentage).toFixed(1)}%)

+

м2 ({(100 - mowedPercentage).toFixed(1)}%)

@@ -226,7 +226,7 @@ const Dashboard: React.FC = () => {
-

Due Today

+

Срок - сегодня

{dueCount}

@@ -236,7 +236,7 @@ const Dashboard: React.FC = () => {
-

Overdue

+

Срок прошел

{overdueCount}

@@ -248,9 +248,9 @@ const Dashboard: React.FC = () => { {totalArea > 0 && (
-

Mowing Progress

+

Ход скашивания

- {mowedArea.toLocaleString()} / {totalArea.toLocaleString()} sq ft + {mowedArea.toLocaleString()} / {totalArea.toLocaleString()} м2
@@ -262,11 +262,11 @@ const Dashboard: React.FC = () => {
- {mowedPercentage.toFixed(1)}% Complete + {mowedPercentage.toFixed(1)}% Завершено - {(100 - mowedPercentage).toFixed(1)}% Remaining + {(100 - mowedPercentage).toFixed(1)}% Осталось
@@ -276,12 +276,12 @@ const Dashboard: React.FC = () => {
- Filter: + Фильтр:
{[ - { key: 'all' as FilterType, label: 'All Zones', count: zones.length }, - { key: 'due' as FilterType, label: 'Due Today', count: dueCount }, - { key: 'overdue' as FilterType, label: 'Overdue', count: overdueCount }, + { key: 'all' as FilterType, label: 'Все зоны', count: zones.length }, + { key: 'due' as FilterType, label: 'Срок - сегодня', count: dueCount }, + { key: 'overdue' as FilterType, label: 'Срок прошел', count: overdueCount }, ].map(({ key, label, count }) => ( = ({ zones, onZoneSelect, selectedZoneId />

- Supported formats: JPG, PNG, GIF (max 10MB) + Поддерживаемые форматы: JPG, PNG, GIF (максимально 10MB)

@@ -137,7 +137,7 @@ const SitePlan: React.FC = ({ zones, onZoneSelect, selectedZoneId
-

Site Plan

+

План участка

({zoneMarkers.length} of {zones.length} zones marked) @@ -199,7 +199,7 @@ const SitePlan: React.FC = ({ zones, onZoneSelect, selectedZoneId Site Plan = ({ zones, onZoneSelect, selectedZoneId
{zone.name}
- {zone.isOverdue ? 'Overdue' : zone.isDueToday ? 'Due today' : `${zone.daysUntilNext} days`} + {zone.isOverdue ? 'Срок прошел' : zone.isDueToday ? 'Срок - сегодня' : `${zone.daysUntilNext} дней`}
@@ -280,7 +280,7 @@ const SitePlan: React.FC = ({ zones, onZoneSelect, selectedZoneId
- Due today + Срок - сегодня
diff --git a/src/components/ZoneCard.tsx b/src/components/ZoneCard.tsx index bf47c2a..982feff 100644 --- a/src/components/ZoneCard.tsx +++ b/src/components/ZoneCard.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Scissors, Edit, Trash2, Calendar, Camera, Square } from 'lucide-react'; +import { Scissors, Edit, Trash2, Calendar, Camera, Square } from './Icons'; import { Zone } from '../types/zone'; interface ZoneCardProps { @@ -28,11 +28,11 @@ const ZoneCard: React.FC = ({ const getStatusText = (zone: Zone) => { if (zone.isOverdue) { - return `${Math.abs(zone.daysUntilNext)} days overdue`; + return `${Math.abs(zone.daysUntilNext)} дней посроченно`; } else if (zone.isDueToday) { - return 'Due today'; + return 'Срок - сегодня'; } else { - return `${zone.daysUntilNext} days remaining`; + return `${zone.daysUntilNext} дней осталось`; } }; @@ -57,7 +57,7 @@ const ZoneCard: React.FC = ({ const formatArea = (area: number) => { if (area === 0) return 'Not specified'; - return `${area.toLocaleString()} sq ft`; + return `${area.toLocaleString()} м2`; }; return ( @@ -94,15 +94,15 @@ const ZoneCard: React.FC = ({
- Last mowed: {formatDate(zone.lastMowedDate)} + Было скошенно: {formatDate(zone.lastMowedDate)}
- Every {zone.intervalDays} days + Каждые {zone.intervalDays} дней
- Area: {formatArea(zone.area)} + Площадь: {formatArea(zone.area)}
@@ -118,7 +118,7 @@ const ZoneCard: React.FC = ({ }`} > - Mowed + Скошенно