-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #173 from Frnn4268/Frnn
Creating new ParkingPriceComponent.jsx components and fixing some iss…
- Loading branch information
Showing
6 changed files
with
194 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React from 'react'; | ||
import { Card, Statistic } from 'antd'; | ||
import { ArrowUpOutlined } from '@ant-design/icons'; | ||
import moment from 'moment'; | ||
|
||
const LastParkingPriceCard = ({ lastSavedParkingPrice, lastDateParkingPrice }) => ( | ||
<Card bordered={false}> | ||
<Statistic | ||
title="Último precio de Estacionamiento" | ||
value={`Q ${lastSavedParkingPrice}/hora`} | ||
precision={2} | ||
valueStyle={{ color: '#3f8600' }} | ||
prefix={<ArrowUpOutlined />} | ||
/> | ||
<Statistic | ||
title="Fecha y Hora" | ||
value={lastDateParkingPrice ? moment(lastDateParkingPrice).format('YYYY-MM-DD HH:mm:ss') : '-'} | ||
/> | ||
</Card> | ||
); | ||
|
||
export default LastParkingPriceCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from 'react'; | ||
import { Form, InputNumber, Button } from 'antd'; | ||
|
||
const ParkingPriceForm = ({ form, handleSubmit }) => ( | ||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column' }}> | ||
<Form layout="vertical" onFinish={handleSubmit} form={form} style={{ width: '100%', maxWidth: '400px' }}> | ||
<Form.Item | ||
label='Precio:' | ||
name='price' | ||
rules={[{ required: true, message: 'Por favor ingresa el precio' }]} | ||
style={{ marginTop: 15, textAlign: 'center' }} | ||
> | ||
<InputNumber | ||
size='large' | ||
placeholder='Ingresa el precio' | ||
defaultValue={0} | ||
formatter={(value) => `Q ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} | ||
parser={(value) => value.replace(/\Q\s?|(,*)/g, '')} | ||
style={{ width: '100%' }} | ||
/> | ||
</Form.Item> | ||
<Form.Item | ||
label='Tiempo:' | ||
name='time_in_hours' | ||
rules={[{ required: true, message: 'Por favor ingresa la cantidad en horas' }]} | ||
style={{ marginTop: 15, textAlign: 'center' }} | ||
> | ||
<InputNumber | ||
size='large' | ||
placeholder='Ingresa la cantidad en horas' | ||
defaultValue={0} | ||
formatter={value => `${value} horas`} | ||
parser={value => value.replace(' horas', '')} | ||
style={{ width: '100%' }} | ||
/> | ||
</Form.Item> | ||
<Form.Item style={{ textAlign: 'center' }}> | ||
<Button type='primary' size='large' className='btn' htmlType="submit" style={{ width: '100%' }}> | ||
Guardar | ||
</Button> | ||
</Form.Item> | ||
</Form> | ||
</div> | ||
); | ||
|
||
export default ParkingPriceForm; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import React from 'react'; | ||
import { Layout } from 'antd'; | ||
import TopMenu from '../../src/pages/dashboard/TopMenu.jsx'; | ||
|
||
const { Header } = Layout; | ||
|
||
const ParkingPriceHeader = () => ( | ||
<Header className='parking-price-header-dashboard'> | ||
<TopMenu /> | ||
</Header> | ||
); | ||
|
||
export default ParkingPriceHeader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// ParkingPriceLayout.jsx | ||
import React from 'react'; | ||
import { Layout } from 'antd'; | ||
import LeftMenu from '../../src/pages/dashboard/LeftMenu.jsx'; | ||
|
||
const ParkingPriceLayout = ({ children }) => ( | ||
<Layout> | ||
<Layout.Sider> | ||
<LeftMenu /> | ||
</Layout.Sider> | ||
<Layout.Content> | ||
{children} | ||
</Layout.Content> | ||
</Layout> | ||
); | ||
|
||
export default ParkingPriceLayout; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,171 +1,111 @@ | ||
// ParkingPriceComponent.jsx | ||
import React, { useState, useEffect } from 'react'; | ||
import { Row, Col, Button, Form, Layout, Card, Typography, message, InputNumber, Statistic } from 'antd'; | ||
import { ArrowUpOutlined } from '@ant-design/icons'; | ||
import { Row, Col, Layout, Card, Typography, message, Form } from 'antd'; | ||
import moment from 'moment'; | ||
|
||
import TopMenu from '../dashboard/TopMenu.jsx' | ||
import LeftMenu from '../dashboard/LeftMenu.jsx'; | ||
import ParkingPriceHeader from '../../../components//parkingPrice/ParkingPriceHeader'; | ||
import ParkingPriceLayout from '../../../components//parkingPrice/ParkingPriceLayout'; | ||
import ParkingPriceForm from '../../../components//parkingPrice/ParkingPriceForm'; | ||
import LastParkingPriceCard from '../../../components//parkingPrice/LastParkingPriceCard'; | ||
|
||
import '../../css/DashboardMenu.css' | ||
import '../../css/DashboardMenu.css'; | ||
import '../../css/ParkingPriceComponent.css'; | ||
|
||
const { Header } = Layout; | ||
const { useForm } = Form; | ||
|
||
const ParkingPriceComponent = () => { | ||
const [form] = useForm(); | ||
const [messageApi, contextHolder] = message.useMessage(); | ||
const [parkingPrice, setParkingPrice] = useState(0); | ||
const [lastSavedParkingPrice, setLastSavedParkingPrice] = useState(0); | ||
const [lastDateParkingPrice, setLastDateParkingPrice] = useState(null); | ||
const [form] = useForm(); | ||
const [messageApi, contextHolder] = message.useMessage(); | ||
const [parkingPrice, setParkingPrice] = useState(0); | ||
const [lastSavedParkingPrice, setLastSavedParkingPrice] = useState(0); | ||
const [lastDateParkingPrice, setLastDateParkingPrice] = useState(null); | ||
|
||
const success = async () => { | ||
messageApi | ||
.loading('Guardando precio de parqueo...', 2.5) | ||
.then(async () => { | ||
message.success('Precio de parqueo guardado correctamente', 2.5); | ||
form.resetFields(); | ||
setLastSavedParkingPrice(parkingPrice); | ||
await fetchLastParkingIncome(); | ||
}) | ||
.catch(() => message.error('Error al guardar el precio de parqueo', 2.5)); | ||
}; | ||
const success = async () => { | ||
messageApi | ||
.loading('Guardando precio de parqueo...', 2.5) | ||
.then(async () => { | ||
message.success('Precio de parqueo guardado correctamente', 2.5); | ||
form.resetFields(); | ||
setLastSavedParkingPrice(parkingPrice); | ||
await fetchLastParkingIncome(); | ||
}) | ||
.catch(() => message.error('Error al guardar el precio de parqueo', 2.5)); | ||
}; | ||
|
||
useEffect(() => { | ||
fetchLastParkingIncome(); | ||
}, []); | ||
useEffect(() => { | ||
fetchLastParkingIncome(); | ||
}, []); | ||
|
||
const fetchLastParkingIncome = async () => { | ||
try { | ||
const response = await fetch(`${import.meta.env.VITE_APP_API_URL}/parking-price/last-parking-price`); | ||
const data = await response.json(); | ||
if (data.status === 'success') { | ||
setParkingPrice(data.data.price); | ||
setLastSavedParkingPrice(data.data.price); | ||
setLastDateParkingPrice(moment(data.data.hour_date).format('YYYY-MM-DD HH:mm:ss')); | ||
} else { | ||
throw new Error('Error al obtener el último precio de parqueo'); | ||
} | ||
} catch (error) { | ||
message.error(error.message); | ||
} | ||
}; | ||
const fetchLastParkingIncome = async () => { | ||
try { | ||
const response = await fetch(`${import.meta.env.VITE_APP_API_URL}/parking-price/last-parking-price`); | ||
const data = await response.json(); | ||
if (data.status === 'success') { | ||
setParkingPrice(data.data.price); | ||
setLastSavedParkingPrice(data.data.price); | ||
setLastDateParkingPrice(moment(data.data.hour_date).format('YYYY-MM-DD HH:mm:ss')); | ||
} else { | ||
throw new Error('Error al obtener el último precio de parqueo'); | ||
} | ||
} catch (error) { | ||
message.error(error.message); | ||
} | ||
}; | ||
|
||
const handleSubmit = async (values) => { | ||
try { | ||
const { price, time_in_hours } = values; | ||
const handleSubmit = async (values) => { | ||
try { | ||
const { price, time_in_hours } = values; | ||
|
||
const response = await fetch(`${import.meta.env.VITE_APP_API_URL}/parking-price`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
price: price, | ||
time_in_hours: time_in_hours, | ||
}), | ||
}); | ||
const response = await fetch(`${import.meta.env.VITE_APP_API_URL}/parking-price`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
price: price, | ||
time_in_hours: time_in_hours, | ||
}), | ||
}); | ||
|
||
if (response.ok) { | ||
success(); | ||
} else { | ||
throw new Error('Error al guardar el ingreso de dinero'); | ||
} | ||
} catch (error) { | ||
message.error(error.message); | ||
} | ||
}; | ||
if (response.ok) { | ||
success(); | ||
} else { | ||
throw new Error('Error al guardar el ingreso de dinero'); | ||
} | ||
} catch (error) { | ||
message.error(error.message); | ||
} | ||
}; | ||
|
||
return ( | ||
<Layout> | ||
<Header className='parking-price-header-dashboard'> | ||
<TopMenu /> | ||
</Header> | ||
<Layout> | ||
<Layout.Sider> | ||
<LeftMenu /> | ||
</Layout.Sider> | ||
<Layout.Content> | ||
<Card className="parking-price-block-section"> | ||
<Typography.Title level={2} strong className='parking-price-title' style={{textAlign: 'center'}}> | ||
Precio de Tiempo de Estacionamiento | ||
</Typography.Title> | ||
<Row justify="space-around"> | ||
<Col xs={22} sm={18} md={16} lg={8}> | ||
<Form layout="vertical" onFinish={handleSubmit} form={form}> | ||
<Form.Item | ||
label='Precio:' | ||
name='price' | ||
rules={[ | ||
{ | ||
required: true, | ||
message: 'Por favor ingresa el precio' | ||
} | ||
]} | ||
style={{ marginTop: 15 }} | ||
> | ||
<InputNumber | ||
size='large' | ||
placeholder='Ingresa el precio' | ||
defaultValue={0} | ||
formatter={(value) => `Q ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} | ||
parser={(value) => value.replace(/\Q\s?|(,*)/g, '')} | ||
style={{ width: '100%' }} | ||
/> | ||
</Form.Item> | ||
<Form.Item | ||
label='Tiempo:' | ||
name='time_in_hours' | ||
rules={[ | ||
{ | ||
required: true, | ||
message: 'Por favor ingresa la cantidad en horas' | ||
} | ||
]} | ||
style={{ marginTop: 15 }} | ||
> | ||
<InputNumber | ||
size='large' | ||
placeholder='Ingresa la cantidad en horas' | ||
defaultValue={0} | ||
formatter={value => `${value} horas`} | ||
parser={value => value.replace(' horas', '')} | ||
style={{ width: '100%' }} | ||
/> | ||
</Form.Item> | ||
<Form.Item> | ||
<Button type='primary' size='large' className='btn' htmlType="submit"> | ||
Guardar | ||
</Button> | ||
</Form.Item> | ||
</Form> | ||
</Col> | ||
</Row> | ||
</Card> | ||
<Row gutter={10} style={{ marginLeft: '4.5%', width: '100%' }}> | ||
<Col span={6}> | ||
<Card bordered={false}> | ||
<Statistic | ||
title="Último precio de Estacionamiento" | ||
value={`Q ${lastSavedParkingPrice}/hora`} | ||
precision={2} | ||
valueStyle={{ | ||
color: '#3f8600', | ||
}} | ||
prefix={<ArrowUpOutlined />} | ||
/> | ||
<Statistic | ||
title="Fecha y Hora" | ||
value={lastDateParkingPrice ? moment(lastDateParkingPrice).format('YYYY-MM-DD HH:mm:ss') : '-'} | ||
/> | ||
</Card> | ||
</Col> | ||
</Row> | ||
</Layout.Content> | ||
</Layout> | ||
{contextHolder} | ||
</Layout> | ||
); | ||
return ( | ||
<Layout> | ||
<ParkingPriceHeader /> | ||
<ParkingPriceLayout> | ||
<Card className="parking-price-block-section"> | ||
<Typography.Title level={2} strong className='parking-price-title' style={{textAlign: 'center'}}> | ||
Precio de Tiempo de Estacionamiento | ||
</Typography.Title> | ||
<Row justify="space-around"> | ||
<Col xs={22} sm={18} md={16} lg={8}> | ||
<ParkingPriceForm | ||
form={form} | ||
handleSubmit={handleSubmit} | ||
/> | ||
</Col> | ||
</Row> | ||
</Card> | ||
<Row gutter={10} style={{ marginLeft: '4.5%', width: '100%' }}> | ||
<Col span={6}> | ||
<LastParkingPriceCard | ||
lastSavedParkingPrice={lastSavedParkingPrice} | ||
lastDateParkingPrice={lastDateParkingPrice} | ||
/> | ||
</Col> | ||
</Row> | ||
</ParkingPriceLayout> | ||
{contextHolder} | ||
</Layout> | ||
); | ||
} | ||
|
||
export default ParkingPriceComponent; | ||
export default ParkingPriceComponent; |