refactor: extract billfrom component

This commit is contained in:
Ruidy 2021-07-15 18:38:37 +02:00
parent 9b418efb77
commit 2b948f8271
4 changed files with 196 additions and 154 deletions

View file

@ -0,0 +1,99 @@
import { Button, Form, Input, Switch } from 'antd';
import { BaseSyntheticEvent } from 'react';
import { Control, Controller, UseFormRegister } from 'react-hook-form';
import { BillFormType } from '../types/bill';
import { InputSelect } from './inputSelect';
type Props = {
onFinish: (e?: BaseSyntheticEvent) => Promise<void>;
control: Control<BillFormType>;
register: UseFormRegister<BillFormType>;
};
export function BillForm({ onFinish, control, register }: Props) {
return (
<Form layout="vertical" onFinish={onFinish}>
<Form.Item label="Customer name">
<Input placeholder="Cameron Doe" {...register('name')} />
</Form.Item>
<Form.Item label="Customer phone number">
<Input placeholder="06 12 34 56 78" {...register('phoneNumber')} />
</Form.Item>
<Form.Item label="Price">
<Input placeholder="75.00" addonAfter="€" {...register('price')} />
</Form.Item>
<Form.Item label="Start">
<Input type="date" {...register('start')} />
</Form.Item>
<Form.Item label="End">
<Input type="date" {...register('end')} />
</Form.Item>
<InputSelect
control={control}
name="room"
label="Room"
placeholder="Choose a room to stay"
options={['T2 Corail', 'T3 Azur']}
/>
<Form.Item label="Customers number">
<Input type="number" {...register('customers')} placeholder="1" />
</Form.Item>
<InputSelect
control={control}
name="platform"
label="Booking Platform"
placeholder="Select a booking platform"
options={['Site', 'Booking.com', 'AirBnB', 'TripAdvisor', 'Perso']}
/>
<Controller
control={control}
name="taxes"
defaultValue={true}
render={({ field }) => {
const { value, ...props } = field;
return (
<Form.Item label="Include taxes">
<Switch
checkedChildren="yes"
unCheckedChildren="no"
defaultChecked
checked={value}
{...props}
/>
</Form.Item>
);
}}
/>
<InputSelect
control={control}
name="paymentMethod"
label="Payment method"
placeholder="How do you want to pay?"
options={['Card', 'Cash', 'Cheque', 'Transfer']}
/>
<InputSelect
control={control}
name="paymentStatus"
label="Payment status"
placeholder="What is the current payment status?"
options={['Pending', 'Canceled', 'Completed', 'Refunded']}
/>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
}

View file

@ -1,61 +0,0 @@
import { Button, message, Space, Typography } from 'antd';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { fetchOneBill, sendBillAsPDF } from '../api';
import { withLayout } from '../layouts/main';
import { Bill } from '../types/bill';
import NotFoundPage from './notFound';
export type QueryParams = { id: string };
const BillPage = () => {
// Hooks
const { id } = useParams<QueryParams>();
const [sent, setSent] = useState(false);
// Local State
const [bill, setBill] = useState<Bill>({} as Bill);
// Effects
useEffect(() => {
const loadBIllById = async (id: string) => {
const billID = parseInt(id);
const { data: loadedBill, error } = await fetchOneBill(billID);
if (!loadedBill || error) {
return <NotFoundPage />;
}
setBill(() => loadedBill);
return;
};
loadBIllById(id);
}, [id]);
// Logic
const handleSendPDF = (id: number) => {
sendBillAsPDF(id);
message.success('The bill will be sent to the customer');
setSent(() => true);
};
return (
<main>
<Typography.Title>Facture #VFNI{`${bill.id}`.padStart(4, '0')}</Typography.Title>
<Space>
<Button type="primary" onClick={() => handleSendPDF(bill.id)} disabled={sent}>
{sent ? 'The bill is on its way to your customer' : 'Send Bill'}
</Button>
</Space>
<Space>
<Typography.Text>{bill?.name}</Typography.Text>
<Typography.Text>{bill?.price} </Typography.Text>
<Typography.Text>
from {bill?.start} to {bill?.end}
</Typography.Text>
</Space>
</main>
);
};
export default withLayout(BillPage);

89
src/pages/bill/index.tsx Normal file
View file

@ -0,0 +1,89 @@
import { Button, Col, Divider, message, PageHeader, Space, Typography } from 'antd';
import { useEffect, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom';
import { fetchOneBill, sendBillAsPDF } from '../../api';
import { withLayout } from '../../layouts/main';
import { Bill } from '../../types/bill';
import NotFoundPage from '../notFound';
import { BillSent } from './billSent';
import { EditBillForm } from './editBillForm';
export type QueryParams = { id: string };
const BillPage = () => {
// Hooks
const { id } = useParams<QueryParams>();
const history = useHistory();
// Local State
const [sent, setSent] = useState(false);
const [edit, setEdit] = useState(false);
const [bill, setBill] = useState<Bill>({} as Bill);
// Effects
useEffect(() => {
const loadBIllById = async (id: string) => {
const billID = parseInt(id);
const { data: loadedBill, error } = await fetchOneBill(billID);
if (!loadedBill || error) {
return <NotFoundPage />;
}
setBill(() => loadedBill);
return;
};
loadBIllById(id);
}, [id]);
// Logic
const handleSendPDF = (id: number) => {
sendBillAsPDF(id);
message.success('The bill will be sent to the customer');
setSent(() => true);
};
const content = edit ? (
<EditBillForm />
) : sent ? (
<BillSent />
) : (
<Col>
<Typography.Text>{bill?.name}</Typography.Text>
<Typography.Text>{bill?.price} </Typography.Text>
<Typography.Text>
from {bill?.start} to {bill?.end}
</Typography.Text>
</Col>
);
return (
<>
<PageHeader
onBack={() => history.goBack()}
title={`Facture #VFNI${bill.id?.toString().padStart(4, '0')}`}
subTitle={bill.name}
/>
{content}
<Divider />
<Space>
<Button type="primary" onClick={() => handleSendPDF(bill.id)} disabled={sent || edit}>
Send Bill
</Button>
<Button
type="dashed"
onClick={() => {
setSent(() => false);
setEdit(() => true);
}}
>
Edit
</Button>
</Space>
</>
);
};
export default withLayout(BillPage);

View file

@ -1,14 +1,13 @@
import { Button, Form, Input, Switch } from 'antd';
import { Controller, useForm } from 'react-hook-form';
import { useForm } from 'react-hook-form';
import { useHistory } from 'react-router-dom';
import { createBill } from '../api';
import { InputSelect } from '../components/inputSelect';
import { BillForm } from '../components/billForm';
import { withLayout } from '../layouts/main';
import { BillForm } from '../types/bill';
import { BillFormType } from '../types/bill';
const HomePage = () => {
// Hooks
const { register, handleSubmit, control } = useForm<BillForm>();
const { register, handleSubmit, control } = useForm<BillFormType>();
const history = useHistory();
// Logic
@ -18,95 +17,11 @@ const HomePage = () => {
});
return (
<main>
<section>
<h1>Create a new bill</h1>
<>
<h1>Create a new bill</h1>
<Form layout="vertical" onFinish={onSubmit}>
<Form.Item label="Customer name">
<Input placeholder="Cameron Doe" {...register('name')} />
</Form.Item>
<Form.Item label="Customer phone number">
<Input placeholder="06 12 34 56 78" {...register('phoneNumber')} />
</Form.Item>
<Form.Item label="Price">
<Input placeholder="75.00" addonAfter="€" {...register('price')} />
</Form.Item>
<Form.Item label="Start">
<Input type="date" {...register('start')} />
</Form.Item>
<Form.Item label="End">
<Input type="date" {...register('end')} />
</Form.Item>
<InputSelect
control={control}
name="room"
label="Room"
placeholder="Choose a room to stay"
options={['T2 Corail', 'T3 Azur']}
/>
<Form.Item label="Customers number">
<Input type="number" {...register('customers')} placeholder="1" />
</Form.Item>
<InputSelect
control={control}
name="platform"
label="Booking Platform"
placeholder="Select a booking platform"
options={['Site', 'Booking.com', 'AirBnB', 'TripAdvisor', 'Perso']}
/>
<Controller
control={control}
name="taxes"
defaultValue={true}
render={({ field }) => {
const { value, ...props } = field;
return (
<Form.Item label="Include taxes">
<Switch
checkedChildren="yes"
unCheckedChildren="no"
defaultChecked
checked={value}
{...props}
/>
</Form.Item>
);
}}
/>
<InputSelect
control={control}
name="paymentMethod"
label="Payment method"
placeholder="How do you want to pay?"
options={['Card', 'Cash', 'Cheque', 'Transfer']}
/>
<InputSelect
control={control}
name="paymentStatus"
label="Payment status"
placeholder="What is the current payment status?"
options={['Pending', 'Canceled', 'Completed', 'Refunded']}
/>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
</section>
</main>
<BillForm onFinish={onSubmit} control={control} register={register} />
</>
);
};