mirror of
https://github.com/rjNemo/melon_frontend
synced 2026-06-11 21:06:42 +00:00
feat: request report form
This commit is contained in:
parent
4b800872a6
commit
0463def200
10 changed files with 112 additions and 66 deletions
52
src/api/bills.ts
Normal file
52
src/api/bills.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { client, Response } from '.';
|
||||||
|
import { Bill, BillFormType, billFrom } from '../types/bill';
|
||||||
|
|
||||||
|
export const createBill = async (data: BillFormType) => {
|
||||||
|
try {
|
||||||
|
const { data: response } = await client.post<number>('/bills', data);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateBill = async (id: number, data: BillFormType): Promise<Response<void>> => {
|
||||||
|
try {
|
||||||
|
const { data: response } = await client.put<void>(`/bills/${id}`, data);
|
||||||
|
return { data: response };
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return { error };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchOneBill = async (id: number): Promise<Response<Bill>> => {
|
||||||
|
try {
|
||||||
|
const { data } = await client.get<Bill>(`/bills/${id}`);
|
||||||
|
return { data: billFrom(data) };
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return { error };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchAllBills = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await client.get<Bill[]>('/bills');
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return [] as Bill[];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendBillAsPDF = async (id: number) => {
|
||||||
|
try {
|
||||||
|
const { data } = await client.post<boolean>(`/bills/${id}/send`);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,60 +1,10 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Bill, BillFormType, billFrom } from '../types/bill';
|
|
||||||
|
|
||||||
const BASE_URL = process.env.REACT_APP_API_URL;
|
const BASE_URL = process.env.REACT_APP_API_URL;
|
||||||
const client = axios.create({ baseURL: BASE_URL });
|
|
||||||
|
|
||||||
type Response<T> = {
|
export const client = axios.create({ baseURL: BASE_URL });
|
||||||
|
|
||||||
|
export type Response<T> = {
|
||||||
data?: T;
|
data?: T;
|
||||||
error?: any;
|
error?: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createBill = async (data: BillFormType) => {
|
|
||||||
try {
|
|
||||||
const { data: response } = await client.post<number>('/', data);
|
|
||||||
return response;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateBill = async (id: number, data: BillFormType): Promise<Response<void>> => {
|
|
||||||
try {
|
|
||||||
const { data: response } = await client.put<void>(`/${id}`, data);
|
|
||||||
return { data: response };
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return { error };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fetchOneBill = async (id: number): Promise<Response<Bill>> => {
|
|
||||||
try {
|
|
||||||
const { data } = await client.get<Bill>(`/${id}`);
|
|
||||||
return { data: billFrom(data) };
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return { error };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fetchAllBills = async () => {
|
|
||||||
try {
|
|
||||||
const { data } = await client.get<Bill[]>('/');
|
|
||||||
return data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return [] as Bill[];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sendBillAsPDF = async (id: number) => {
|
|
||||||
try {
|
|
||||||
const { data } = await client.post<boolean>(`/${id}/send`);
|
|
||||||
return data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
||||||
22
src/api/reports.ts
Normal file
22
src/api/reports.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { client, Response } from '.';
|
||||||
|
import { Report, ReportFormType, ReportType } from '../types/report';
|
||||||
|
|
||||||
|
export const fetchReport = async ({
|
||||||
|
type,
|
||||||
|
year,
|
||||||
|
month
|
||||||
|
}: ReportFormType): Promise<Response<Report>> => {
|
||||||
|
const baseQueryURL = `/reports/?report_type=${type}&year=${year}`;
|
||||||
|
const queryURL =
|
||||||
|
type === ReportType.monthly && month
|
||||||
|
? baseQueryURL.concat(`&month=${month + 1}`)
|
||||||
|
: baseQueryURL;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { data } = await client.get<Report>(queryURL);
|
||||||
|
return { data };
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return { error };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -16,7 +16,9 @@ export const RadioInput = ({ control, name, label, options }: RadioInputProps) =
|
||||||
<Form.Item label={label}>
|
<Form.Item label={label}>
|
||||||
<Radio.Group {...field}>
|
<Radio.Group {...field}>
|
||||||
{options.map((label, value) => (
|
{options.map((label, value) => (
|
||||||
<Radio value={value}>{label}</Radio>
|
<Radio key={value} value={label.toLowerCase()}>
|
||||||
|
{label}
|
||||||
|
</Radio>
|
||||||
))}
|
))}
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1 @@
|
||||||
export const enumToList = (enumerable: any) =>
|
export const enumToList = (enumerable: any) => Object.keys(enumerable).filter((v) => !parseInt(v));
|
||||||
Object.keys(enumerable)
|
|
||||||
.filter((v) => !parseInt(v))
|
|
||||||
.slice(1);
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import { Button, Form } from 'antd';
|
import { Button, Form } from 'antd';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { fetchReport } from '../api/reports';
|
||||||
|
import { FormInput } from '../components/formInput';
|
||||||
import { InputSelect } from '../components/inputSelect';
|
import { InputSelect } from '../components/inputSelect';
|
||||||
import { RadioInput } from '../components/radioInput';
|
import { RadioInput } from '../components/radioInput';
|
||||||
import { withLayout } from '../layouts/main';
|
import { withLayout } from '../layouts/main';
|
||||||
|
|
@ -7,10 +9,16 @@ import { monthToList, ReportFormType, ReportType } from '../types/report';
|
||||||
|
|
||||||
function ReportPage() {
|
function ReportPage() {
|
||||||
// hooks
|
// hooks
|
||||||
const { control, handleSubmit, watch } = useForm<ReportFormType>();
|
const { control, handleSubmit, watch } = useForm<ReportFormType>({
|
||||||
|
defaultValues: {
|
||||||
|
type: ReportType.monthly,
|
||||||
|
year: new Date().getFullYear(),
|
||||||
|
month: new Date().getMonth()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Logic
|
// Logic
|
||||||
const onFinish = handleSubmit((data) => console.log(data));
|
const onFinish = handleSubmit((data) => fetchReport(data));
|
||||||
|
|
||||||
const isMonthlyReport = watch('type') === ReportType.monthly;
|
const isMonthlyReport = watch('type') === ReportType.monthly;
|
||||||
|
|
||||||
|
|
@ -24,6 +32,9 @@ function ReportPage() {
|
||||||
label="Report type"
|
label="Report type"
|
||||||
options={['Monthly', 'Yearly']}
|
options={['Monthly', 'Yearly']}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<FormInput control={control} name="year" label="Year" type="number" />
|
||||||
|
|
||||||
{isMonthlyReport && (
|
{isMonthlyReport && (
|
||||||
<InputSelect
|
<InputSelect
|
||||||
control={control}
|
control={control}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { Button, Col, Divider, message, PageHeader, Space, Typography } from 'an
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { useHistory, useParams } from 'react-router-dom';
|
import { useHistory, useParams } from 'react-router-dom';
|
||||||
import { fetchOneBill, sendBillAsPDF, updateBill } from '../../api';
|
import { fetchOneBill, sendBillAsPDF, updateBill } from '../../api/bills';
|
||||||
import { BillForm } from '../../components/billForm';
|
import { BillForm } from '../../components/billForm';
|
||||||
import { withLayout } from '../../layouts/main';
|
import { withLayout } from '../../layouts/main';
|
||||||
import { Bill, BillFormType } from '../../types/bill';
|
import { Bill, BillFormType } from '../../types/bill';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Card, List } from 'antd';
|
import { Card, List } from 'antd';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { fetchAllBills } from '../api';
|
import { fetchAllBills } from '../api/bills';
|
||||||
import { withLayout } from '../layouts/main';
|
import { withLayout } from '../layouts/main';
|
||||||
import { Bill } from '../types/bill';
|
import { Bill } from '../types/bill';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { createBill } from '../../api';
|
import { createBill } from '../../api/bills';
|
||||||
import { BillForm } from '../../components/billForm';
|
import { BillForm } from '../../components/billForm';
|
||||||
import { withLayout } from '../../layouts/main';
|
import { withLayout } from '../../layouts/main';
|
||||||
import { BillFormType } from '../../types/bill';
|
import { BillFormType } from '../../types/bill';
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,29 @@
|
||||||
import { enumToList } from '../../lib/enums';
|
import { enumToList } from '../../lib/enums';
|
||||||
|
import { Bill } from '../bill';
|
||||||
|
|
||||||
export type ReportFormType = {
|
export type ReportFormType = {
|
||||||
type: ReportType;
|
type: ReportType;
|
||||||
month?: Month;
|
month?: Month;
|
||||||
|
year: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface Report {
|
||||||
|
type: ReportType;
|
||||||
|
month?: Month;
|
||||||
|
year: number;
|
||||||
|
revenue: number;
|
||||||
|
profit: number;
|
||||||
|
bookings: number;
|
||||||
|
bills: Bill[];
|
||||||
|
}
|
||||||
|
|
||||||
export enum ReportType {
|
export enum ReportType {
|
||||||
monthly,
|
monthly = 'monthly',
|
||||||
yearly
|
yearly = 'yearly'
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Month {
|
enum Month {
|
||||||
January,
|
January = 1,
|
||||||
February,
|
February,
|
||||||
March,
|
March,
|
||||||
April,
|
April,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue