front #8

Merged
mfnefd merged 14 commits from front into dev 2024-12-25 23:49:21 +04:00
7 changed files with 282 additions and 0 deletions
Showing only changes of commit c1f785eff1 - Show all commits

View File

@ -7,6 +7,7 @@ import {AppLayout} from './components/Layout';
import { ProfilePage } from './pages/Profile';
import { GreenHouseListPage } from './pages/GreenHouseListPage';
import { ReportPage } from './pages/ReportPage';
import GreenHousePage from './pages/GreenHousePage';
function App() {
return (
@ -18,6 +19,7 @@ function App() {
<Route path="/register" element={<RegisterPage />} />
<Route path="/profile" element={<ProfilePage />} />
<Route path="/greenhouses" element={<GreenHouseListPage />} />
<Route path="/greenhouses/:id" element={<GreenHousePage />} />
<Route path="/report" element={<ReportPage />} />
</Route>

View File

@ -0,0 +1,20 @@
import { Table } from "antd";
import { HistoryData } from "../../core/services/greenhouse-service";
export interface GreenhouseCommandTableProps {
history: HistoryData[],
className: string
}
const GreenhouseCommandHistoryTable = (props: GreenhouseCommandTableProps) => {
const { history, className } = props;
return (
<Table columns={[
{ title: 'Действие', dataIndex: 'action' },
{ title: 'Время начала', dataIndex: 'startAt' },
{ title: 'Время конца', dataIndex: 'endAt'}
]} dataSource={history} className={className} />
);
}
export default GreenhouseCommandHistoryTable;

View File

@ -0,0 +1,46 @@
import { GreenhouseInfo } from "../../core/api/data-contracts";
export interface GreehouseDataDisplayProps {
info: GreenhouseInfo
}
const GreenhouseDataDisplay = (props: GreehouseDataDisplayProps) => {
const { info } = props;
return (
<div className="p-8">
<h1 className="text-4xl font-bold mb-4">Данные теплицы</h1>
<div className="bg-white shadow-md rounded-lg p-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<h2 className="text-xl font-semibold mb-2">Процент влажности почвы:</h2>
<p className="text-lg">{info.percentWater}%</p>
</div>
<div>
<h2 className="text-xl font-semibold mb-2">Температура почвы:</h2>
<p className="text-lg">{info.soilTemperature}°C</p>
</div>
<div>
<h2 className="text-xl font-semibold mb-2">Статус вентиля:</h2>
<p className="text-lg">
{info.pumpStatus ? 'Открыт' : 'Закрыт'}
</p>
</div>
<div>
<h2 className="text-xl font-semibold mb-2">Статус нагревателя:</h2>
<p className="text-lg">
{info.heatingStatus ? 'Включен' : 'Выключен'}
</p>
</div>
<div>
<h2 className="text-xl font-semibold mb-2">Статус автополива:</h2>
<p className="text-lg">
{info.autoWateringStatus ? 'Активирован' : 'Деактивирован'}
</p>
</div>
</div>
</div>
</div>
);
}
export default GreenhouseDataDisplay;

View File

@ -0,0 +1,26 @@
import { Switch } from "antd";
import { useState } from "react";
export interface GreenhouseManagerProps {
}
const GreenhouseManager = (props: GreenhouseManagerProps) => {
return (
<div className="p-8">
<h1 className="text-2xl font-bold mb-4">Управление</h1>
<div className="m-4">
<label htmlFor="watering" className="text-xl me-2">Полив</label>
<Switch id="watering" checkedChildren="Вкл" unCheckedChildren="Выкл" />
</div>
<div className="m-4">
<label htmlFor="heating" className="text-xl me-2">Нагрев</label>
<Switch id="heating" checkedChildren="Вкл" unCheckedChildren="Выкл" />
</div>
</div>
);
};
export default GreenhouseManager;

View File

@ -0,0 +1,97 @@
import { useState } from "react";
import { Greenhouse, HeatingMode, WateringMode } from "../../core/api/data-contracts";
import { Select, Button, Form, Input } from "antd";
export interface GreenhouseSettingsFormProps {
updateSettings: (settings: Greenhouse) => void,
id: number
}
const GreenhouseSettingsForm = (props: GreenhouseSettingsFormProps) => {
const { updateSettings, id } = props;
const [settings, setSettings] = useState<Greenhouse>({
id: Number(id!),
wateringMode: WateringMode.Value0,
heatingMode: HeatingMode.Value0,
});
return (
<div className="p-8">
<h1 className="text-2xl font-bold mb-4">Настройки</h1>
<Form
name="basic"
layout="vertical"
initialValues={{ remember: true }}
onFinish={(values: any) => updateSettings({ ...settings, ...values })}
onFinishFailed={(error: any) => console.log(error)}
>
<Form.Item
label="Режим полива"
name="wateringMode"
rules={[{ required: true, message: 'Выберите режим полива' }]}
>
<Select
value={settings.wateringMode}
onChange={(value) => setSettings({ ...settings, wateringMode: value })}
>
<Select.Option value={WateringMode.Value0}>Ручной</Select.Option>
<Select.Option value={WateringMode.Value1}>Автоматический</Select.Option>
</Select>
</Form.Item>
<Form.Item
label="Режим нагрева"
name="heatingMode"
rules={[{ required: true, message: 'Выберите режим нагрева' }]}
>
<Select
value={settings.heatingMode}
onChange={(value) => setSettings({ ...settings, heatingMode: value })}
>
<Select.Option value={HeatingMode.Value0}>Ручной</Select.Option>
<Select.Option value={HeatingMode.Value1}>Автоматический</Select.Option>
</Select>
</Form.Item>
<Form.Item
label="Минимальная температура"
name="minTemperature"
rules={[{ required: true, message: 'Введите минимальную температуру' }]}
>
<Input type="number" />
</Form.Item>
<Form.Item
label="Максимальная температура"
name="maxTemperature"
rules={[{ required: true, message: 'Введите максимальную температуру' }]}
>
<Input type="number" />
</Form.Item>
<Form.Item
label="Минимальная влажность почвы"
name="minHumidity"
rules={[{ required: true, message: 'Введите минимальную влажность почвы' }]}
>
<Input type="number" />
</Form.Item>
<Form.Item
label="Максимальная влажность почвы"
name="maxHumidity"
rules={[{ required: true, message: 'Введите максимальную влажность почвы' }]}
>
<Input type="number" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Обновить настройки
</Button>
</Form.Item>
</Form>
</div>
);
};
export default GreenhouseSettingsForm;

View File

@ -0,0 +1,52 @@
import { Greenhouse, GreenhouseInfo } from "../api/data-contracts";
export type HistoryData = {
id: number,
action: string,
startAt: string,
endAt: string
}
export default class GreenhouseService {
private static _info: GreenhouseInfo = {} as GreenhouseInfo;
public getData(id: number): GreenhouseInfo {
if (GreenhouseService._info.id) return GreenhouseService._info;
let info = {
id: id,
percentWater: randomInt(50, 60),
soilTemperature: randomInt(17, 28),
pumpStatus: randomInt(0, 1) == 1,
heatingStatus: randomInt(0, 1) == 1,
autoWateringStatus: randomInt(0, 1) == 1
};
GreenhouseService._info = info;
return info;
}
public setSettings(settings: Greenhouse): boolean {
let newInfo = {
id: settings.id,
percentWater: randomInt(50, 60),
soilTemperature: randomInt(17, 28),
pumpStatus: randomInt(0, 1) == 1,
heatingStatus: settings.heatingMode,
autoWateringStatus: settings.wateringMode
} as GreenhouseInfo;
GreenhouseService._info = newInfo;
return true;
}
public getCommandsHistory(id: number): HistoryData[] {
return [
{ id: 1, action: "Открыт вентиль", startAt: new Date().toLocaleDateString(), endAt: new Date().toLocaleDateString() },
{ id: 2, action: "Закрыт вентиль", startAt: new Date().toLocaleDateString(), endAt: new Date().toLocaleDateString()},
{ id: 3, action: "Включен нагреватель", startAt: new Date().toLocaleDateString(), endAt: new Date().toLocaleDateString()},
{ id: 3, action: "выключен нагреватель", startAt: new Date().toLocaleDateString(), endAt: new Date().toLocaleDateString()},
]
}
}
function randomInt(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1) + min);
}

View File

@ -0,0 +1,39 @@
import { useState } from 'react';
import GreenhouseService, { HistoryData } from '../core/services/greenhouse-service';
import { Greenhouse, GreenhouseInfo, HeatingMode, WateringMode } from '../core/api/data-contracts';
import { useNavigate, useParams } from 'react-router-dom';
import GreenhouseDataDisplay from '../components/greenhouse/GreenhouseDataDisplay';
import GreenhouseSettingsForm from '../components/greenhouse/GreenhouseSettingsForm';
import GreenhouseManager from '../components/greenhouse/GreenhouseManager';
import GreenhouseCommandHistoryTable from '../components/greenhouse/GreenhouseCommandTable';
const GreenHousePage = () => {
const { id } = useParams();
let service = new GreenhouseService();
const [info, setInfo] = useState<GreenhouseInfo>(service.getData(Number(id!)));
const [history, setHistory] = useState<HistoryData[]>(service.getCommandsHistory(Number(id!)));
const updateSettings = (settings: Greenhouse) => {
const success = service.setSettings(settings);
if (success) {
alert('Настройки успешно обновлены');
} else {
alert('Ошибка обновления настроек');
}
};
return (
<div style={{ display: 'flex', flexDirection: 'column'}}>
<div style={{ display: 'flex', flexDirection: 'row'}}>
<GreenhouseDataDisplay info={info} />
<GreenhouseManager />
<GreenhouseSettingsForm updateSettings={updateSettings} id={info.id!} />
</div>
<GreenhouseCommandHistoryTable history={history} className="m-3" />
</div>
);
}
export default GreenHousePage;