fuel; nest api
This commit is contained in:
287
client/src/pages/fuel/Limits/LimitEditForm.tsx
Normal file
287
client/src/pages/fuel/Limits/LimitEditForm.tsx
Normal file
@ -0,0 +1,287 @@
|
||||
import { Button, Dialog, DialogBody, DialogContent, DialogSurface, DialogTitle, Field, Input, ProgressBar, Spinner } from '@fluentui/react-components'
|
||||
import { DataPieColor } from '@fluentui/react-icons'
|
||||
import axios from 'axios'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Controller, SubmitHandler, useFieldArray, useForm, useWatch } from 'react-hook-form'
|
||||
import useSWR from 'swr'
|
||||
|
||||
type Month = {
|
||||
month: number
|
||||
value: number
|
||||
}
|
||||
|
||||
type Inputs = {
|
||||
id_boiler: string
|
||||
id_fuel: string
|
||||
year: number
|
||||
months: Month[]
|
||||
}
|
||||
|
||||
const months = [
|
||||
{
|
||||
id: 7,
|
||||
month: 'jul',
|
||||
label: 'Июль'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
month: 'aug',
|
||||
label: 'Август'
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
month: 'sep',
|
||||
label: 'Сентябрь'
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
month: 'nov',
|
||||
label: 'Октябрь'
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
month: 'oct',
|
||||
label: 'Ноябрь'
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
month: 'dec',
|
||||
label: 'Декабрь'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
month: 'jan',
|
||||
label: 'Январь'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
month: 'feb',
|
||||
label: 'Февраль'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
month: 'mar',
|
||||
label: 'Март'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
month: 'apr',
|
||||
label: 'Апрель'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
month: 'may',
|
||||
label: 'Май'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
month: 'jun',
|
||||
label: 'Июнь'
|
||||
},
|
||||
]
|
||||
|
||||
const LimitAddForm = ({
|
||||
cityId,
|
||||
open,
|
||||
setOpen,
|
||||
percentage
|
||||
}: {
|
||||
cityId: number | undefined
|
||||
open: boolean
|
||||
setOpen: (open: boolean) => void
|
||||
percentage?: boolean
|
||||
}) => {
|
||||
const {
|
||||
handleSubmit,
|
||||
control,
|
||||
setValue,
|
||||
formState: { isSubmitting },
|
||||
} = useForm<Inputs>({
|
||||
defaultValues: {
|
||||
months: Array.from({ length: 12 }, (_, i) => ({
|
||||
month: i + 1,
|
||||
value: 0,
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
const { fields } = useFieldArray({
|
||||
control,
|
||||
name: 'months'
|
||||
})
|
||||
|
||||
const onSubmit: SubmitHandler<Inputs> = async (data) => {
|
||||
await axios.post(`/fuel/limits`, {
|
||||
id_boiler: '06407B1C-C23F-44C8-BADF-4653060EB784',
|
||||
id_fuel: 3,
|
||||
year: 2025,
|
||||
months: data.months
|
||||
}, {
|
||||
baseURL: import.meta.env.VITE_API_NEST_URL,
|
||||
})
|
||||
//mutateFuels([...fuels, data])
|
||||
|
||||
// setTimeout(() => {
|
||||
// console.log("done")
|
||||
// }, 1000)
|
||||
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(() => resolve(console.log("done")), 1000);
|
||||
})
|
||||
}
|
||||
|
||||
const [overallLimit, setOverallLimit] = useState(0)
|
||||
|
||||
const watchedMonths = useWatch({
|
||||
control,
|
||||
name: "months",
|
||||
})
|
||||
|
||||
const { data: citySettings } = useSWR(
|
||||
cityId ? `/fuel/city-settings?city_id=${cityId}` : null,
|
||||
() =>
|
||||
axios
|
||||
.get(`/fuel/city-settings?city_id=${cityId}`, {
|
||||
baseURL: import.meta.env.VITE_API_NEST_URL,
|
||||
})
|
||||
.then((res) => res.data)
|
||||
)
|
||||
|
||||
const handlePartition = () => {
|
||||
if (citySettings && Array.isArray(citySettings) && citySettings.length > 0) {
|
||||
citySettings.map(s => {
|
||||
setValue(`months.${Number(s.month - 1)}.value`, Number((Number((overallLimit / 100).toFixed(3)) * s.procent).toFixed(3)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (watchedMonths) {
|
||||
let sum = 0
|
||||
watchedMonths.map(wm => sum = sum + wm.value)
|
||||
setOverallLimit(Number(sum.toFixed(3)))
|
||||
}
|
||||
}, [watchedMonths])
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(_, data) => setOpen(data.open)}>
|
||||
<DialogSurface>
|
||||
<DialogBody>
|
||||
{isSubmitting &&
|
||||
<div style={{ position: 'absolute', inset: 0, zIndex: '1', background: '#00000030', display: 'flex', justifyContent: 'center', alignItems: 'center', width: '100%', height: '100%' }}>
|
||||
<Spinner />
|
||||
</div>
|
||||
}
|
||||
<DialogTitle>Распределение лимитов</DialogTitle>
|
||||
|
||||
<DialogContent
|
||||
style={{
|
||||
display: 'flex', flexDirection: 'column', gap: '1rem',
|
||||
minWidth: 'fit-content', minHeight: 'fit-content'
|
||||
}}
|
||||
>
|
||||
<form onSubmit={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
handlePartition()
|
||||
}} style={{ display: 'flex', width: '100%', gap: '0.25rem', justifyContent: 'flex-end' }}>
|
||||
<Field style={{ display: 'flex' }} label='Лимит расхода котельного топлива за сезон' orientation='horizontal'>
|
||||
<Input type='number' value={overallLimit.toString()} onChange={(_, data) => setOverallLimit(Number(data.value))} />
|
||||
</Field>
|
||||
|
||||
<Button title='Распределить' type='submit' icon={<DataPieColor />}></Button>
|
||||
</form>
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div style={{ display: 'flex', flexDirection: 'row', gap: '1rem', width: '100%' }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', width: '50%', gap: '0.25rem' }}>
|
||||
{fields.map((f, index) => {
|
||||
if (f.month >= 7 && f.month <= 12) {
|
||||
return (
|
||||
<Controller
|
||||
key={f.month}
|
||||
name={`months.${index}.value`}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Field style={{ gridTemplateColumns: '1fr auto' }} key={f.month} validationMessage={percentage ? `${(field.value / (overallLimit / 100)).toFixed(1)}%` : undefined} validationState='none' label={months.find(m => m.id === f.month)?.label} orientation='horizontal'>
|
||||
<Input value={field.value.toString()} onChange={(_, data) => field.onChange(Number(data.value))} />
|
||||
{percentage && <ProgressBar value={field.value / (overallLimit / 100) * 0.01} />}
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
})}
|
||||
|
||||
|
||||
<Field style={{ gridTemplateColumns: '1fr auto' }} validationMessage={percentage ? `${(watchedMonths.filter(month => month.month >= 7 && month.month <= 12)
|
||||
.reduce((sum, month) => {
|
||||
const value = Number(month.value) || 0;
|
||||
return sum + value;
|
||||
}, 0) / (overallLimit / 100)).toFixed(1)}%` : undefined} validationState='none' label={'2 полугодие'} orientation='horizontal'>
|
||||
<Input disabled value={watchedMonths.filter(month => month.month >= 7 && month.month <= 12)
|
||||
.reduce((sum, month) => {
|
||||
const value = Number(month.value) || 0;
|
||||
return sum + value;
|
||||
}, 0).toFixed(3)} />
|
||||
|
||||
{percentage && <ProgressBar value={watchedMonths.filter(month => month.month >= 7 && month.month <= 12)
|
||||
.reduce((sum, month) => {
|
||||
const value = Number(month.value) || 0;
|
||||
return sum + value;
|
||||
}, 0) / (overallLimit / 100) * 0.01} />}
|
||||
</Field>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', width: '50%', gap: '0.25rem' }}>
|
||||
{fields.map((f, index) => {
|
||||
if (f.month >= 1 && f.month <= 6) {
|
||||
return (
|
||||
<Controller
|
||||
key={f.month}
|
||||
name={`months.${index}.value`}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Field style={{ gridTemplateColumns: '1fr auto' }} key={f.month} validationMessage={percentage ? `${(field.value / (overallLimit / 100)).toFixed(1)}%` : undefined} validationState='none' label={months.find(m => m.id === f.month)?.label} orientation='horizontal'>
|
||||
<Input value={field.value.toString()} onChange={(_, data) => field.onChange(Number(data.value))} />
|
||||
{percentage && <ProgressBar value={field.value / (overallLimit / 100) * 0.01} />}
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
})}
|
||||
|
||||
<Field style={{ gridTemplateColumns: '1fr auto' }} validationMessage={percentage ? `${(watchedMonths.filter(month => month.month >= 1 && month.month <= 6)
|
||||
.reduce((sum, month) => {
|
||||
const value = Number(month.value) || 0;
|
||||
return sum + value;
|
||||
}, 0) / (overallLimit / 100)).toFixed(1)}%` : undefined} validationState='none' label={'1 полугодие'} orientation='horizontal'>
|
||||
<Input disabled value={watchedMonths.filter(month => month.month >= 1 && month.month <= 6)
|
||||
.reduce((sum, month) => {
|
||||
const value = Number(month.value) || 0;
|
||||
return sum + value;
|
||||
}, 0).toFixed(3)} />
|
||||
{percentage && <ProgressBar value={watchedMonths.filter(month => month.month >= 1 && month.month <= 6)
|
||||
.reduce((sum, month) => {
|
||||
const value = Number(month.value) || 0;
|
||||
return sum + value;
|
||||
}, 0) / (overallLimit / 100) * 0.01} />}
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', marginTop: '1rem', justifyContent: 'flex-end' }}>
|
||||
<Button type='submit' appearance='primary'>
|
||||
Добавить
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</DialogBody>
|
||||
</DialogSurface>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
export default LimitAddForm
|
||||
Reference in New Issue
Block a user