front #8
@ -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>
|
||||
|
||||
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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;
|
52
cucumber-frontend/src/core/services/greenhouse-service.ts
Normal file
52
cucumber-frontend/src/core/services/greenhouse-service.ts
Normal 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);
|
||||
}
|
39
cucumber-frontend/src/pages/GreenHousePage.tsx
Normal file
39
cucumber-frontend/src/pages/GreenHousePage.tsx
Normal 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;
|
Loading…
Reference in New Issue
Block a user