summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2021-03-26 01:56:04 +0300
committereug-vs <eug-vs@keemail.me>2021-03-26 01:56:04 +0300
commitef742ea9b2f246f74eae74169675a331679ad41c (patch)
tree693e92f3e6c2897038875550a12bbc1191b6d5c0
parent865b41114060765308d560181f4996c0aa7a3e74 (diff)
downloadcommercel-ui-ef742ea9b2f246f74eae74169675a331679ad41c.tar.gz
feat: add strong typing where possible
-rw-r--r--src/components/Input.tsx4
-rw-r--r--src/components/ListTable.tsx4
-rw-r--r--src/hooks/useAPIClient.ts22
-rw-r--r--src/hooks/useQuery.ts2
-rw-r--r--src/lib/ServiceContext.tsx16
-rw-r--r--src/services/contractors/ContractorPanel.tsx3
-rw-r--r--src/services/contractors/index.ts3
-rw-r--r--src/services/products/index.ts5
-rw-r--r--src/services/transfers/TransferForm.tsx5
-rw-r--r--src/services/transfers/TransfersUpload.tsx12
-rw-r--r--src/services/transfers/index.ts4
-rw-r--r--src/services/types.ts40
-rw-r--r--src/services/waybills/WaybillForm.tsx7
-rw-r--r--src/services/waybills/WaybillPanel.tsx5
-rw-r--r--src/services/waybills/index.ts3
15 files changed, 81 insertions, 54 deletions
diff --git a/src/components/Input.tsx b/src/components/Input.tsx
index a8a6f31..298d14c 100644
--- a/src/components/Input.tsx
+++ b/src/components/Input.tsx
@@ -3,17 +3,19 @@ import { Field } from 'formik';
export interface Props extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
+ ref?: React.Ref<HTMLInputElement>
}
const focusStyles = 'focus:outline-none focus:shadow focus:border-gray-400';
const baseStyles = 'p-2 border bg-white border-gray-300 rounded-sm';
-const InputBase: React.FC<Props> = ({ label, ...props }) => {
+const InputBase: React.FC<Props> = ({ label, ref, ...props }) => {
return (
<div className="m-2 mb-4 flex flex-col">
<label htmlFor={props?.name} className="mb-1 text-sm text-gray-600">{label}</label>
<input
id={props?.name}
+ ref={ref}
placeholder={label}
className={`${baseStyles} ${focusStyles}`}
{...props}
diff --git a/src/components/ListTable.tsx b/src/components/ListTable.tsx
index 79e1ecd..89a2e06 100644
--- a/src/components/ListTable.tsx
+++ b/src/components/ListTable.tsx
@@ -7,8 +7,8 @@ export interface Field {
transform?: (value: string) => JSX.Element | string;
}
-interface Props {
- items?: any[];
+interface Props<T = any> {
+ items?: T[];
fields: Field[];
handleRowClick?: (index: number) => void;
}
diff --git a/src/hooks/useAPIClient.ts b/src/hooks/useAPIClient.ts
index b523d1f..e992b42 100644
--- a/src/hooks/useAPIClient.ts
+++ b/src/hooks/useAPIClient.ts
@@ -28,28 +28,6 @@ const registerServiceHooks = <Item = any>(service: string): void => {
hooks[service] = { useItem, useList };
};
-// Products
-export interface Product {
- _id: string;
- name: string;
- description: string;
- price: number;
- quantity: number;
- specs: any;
- createdAt: string;
- updatedAt: string;
-}
-
-// Contractors
-export interface Contractor {
- _id: string;
- name: string;
- fullName: string;
- vatId: string;
- type: string;
- debt: number;
-}
-
hooks.account = {
useList: () => {
const { data: transfers } = useSWR('/transfers', fetcher);
diff --git a/src/hooks/useQuery.ts b/src/hooks/useQuery.ts
index b2cb628..f025a46 100644
--- a/src/hooks/useQuery.ts
+++ b/src/hooks/useQuery.ts
@@ -1,6 +1,6 @@
import { useLocation } from 'react-router-dom';
-const useQuery = () => {
+const useQuery = (): Record<string, string> => {
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
return Object.fromEntries(searchParams);
diff --git a/src/lib/ServiceContext.tsx b/src/lib/ServiceContext.tsx
index 93cac4e..f7170d1 100644
--- a/src/lib/ServiceContext.tsx
+++ b/src/lib/ServiceContext.tsx
@@ -7,22 +7,22 @@ export interface Action extends ButtonProps {
name: string;
}
-export interface PanelProps {
- item: any;
- mutate: (item: any) => void;
+export interface PanelProps<T> {
+ item: T;
+ mutate: (item: T) => void;
}
-export interface ServiceParams {
+export interface ServiceParams<T = any> {
route: string;
name: string;
tableFields: Field[];
nameSingular?: string;
- default?: Record<string, any>;
+ default?: Partial<T>;
routes?: Record<string, React.FC>;
actions?: Action[];
- rowLink?: (item: any) => string;
- Form?: React.FC<FormikProps<any>>;
- Panel?: React.FC<PanelProps>;
+ rowLink?: (item: T) => string;
+ Form?: React.FC<FormikProps<T>>;
+ Panel?: React.FC<PanelProps<T>>;
}
const ServiceContext = React.createContext<ServiceParams>({
diff --git a/src/services/contractors/ContractorPanel.tsx b/src/services/contractors/ContractorPanel.tsx
index f7ed8ad..6e703b5 100644
--- a/src/services/contractors/ContractorPanel.tsx
+++ b/src/services/contractors/ContractorPanel.tsx
@@ -1,9 +1,10 @@
import React from 'react';
import Button from '../../components/Button';
import { PanelProps } from '../../lib/ServiceContext';
+import { Contractor } from '../types';
-const ContractorPanel: React.FC<PanelProps> = ({ item }) => {
+const ContractorPanel: React.FC<PanelProps<Contractor>> = ({ item }) => {
return (
<div className="lg:m-4 p-4 flex flex-col lg:pl-16 lg:border-l">
<span className="text-lg mb-10">
diff --git a/src/services/contractors/index.ts b/src/services/contractors/index.ts
index 2341f3a..9730eff 100644
--- a/src/services/contractors/index.ts
+++ b/src/services/contractors/index.ts
@@ -1,8 +1,9 @@
import Form from './ContractorForm';
import Panel from './ContractorPanel';
import { ServiceParams } from '../../lib/ServiceContext';
+import { Contractor } from '../types';
-const service: ServiceParams = {
+const service: ServiceParams<Contractor> = {
route: 'contractors',
name: 'Контрагенты',
nameSingular: 'Контрагент',
diff --git a/src/services/products/index.ts b/src/services/products/index.ts
index c869541..8e09eb2 100644
--- a/src/services/products/index.ts
+++ b/src/services/products/index.ts
@@ -1,7 +1,8 @@
import Form from './ProductForm';
import { ServiceParams } from '../../lib/ServiceContext';
+import { Product } from '../types';
-const service: ServiceParams = {
+const service: ServiceParams<Product> = {
route: 'products',
name: 'Товары',
nameSingular: 'Товар',
@@ -12,7 +13,7 @@ const service: ServiceParams = {
],
default: {
name: '',
- price: '',
+ price: 0,
quantity: 0,
},
Form,
diff --git a/src/services/transfers/TransferForm.tsx b/src/services/transfers/TransferForm.tsx
index 3502609..92846a3 100644
--- a/src/services/transfers/TransferForm.tsx
+++ b/src/services/transfers/TransferForm.tsx
@@ -4,12 +4,13 @@ import moment from 'moment';
import Input from '../../components/Input';
import Select from '../../components/Select';
import hooks from '../../hooks/useAPIClient';
+import { Contractor, Transfer } from '../types';
-const mapper = (item: any) => ({ key: item._id, label: item.name });
+const mapper = (item: Contractor) => ({ key: item._id, label: item.name });
-const TransferForm: React.FC<FormikProps<any>> = ({ setFieldValue, values }) => {
+const TransferForm: React.FC<FormikProps<Transfer>> = ({ setFieldValue, values }) => {
const { data: contractors } = hooks.contractors.useList();
if (!values.date) setFieldValue('date', moment().format('YYYY-MM-DD'));
diff --git a/src/services/transfers/TransfersUpload.tsx b/src/services/transfers/TransfersUpload.tsx
index c14a5c1..56bcd7e 100644
--- a/src/services/transfers/TransfersUpload.tsx
+++ b/src/services/transfers/TransfersUpload.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useRef } from 'react';
import { useHistory } from 'react-router-dom';
import { Form, Formik } from 'formik';
import Input from '../../components/Input';
@@ -8,15 +8,15 @@ import { post } from '../../requests';
const TransfersUpload: React.FC = () => {
const history = useHistory();
+ const inputRef = useRef<HTMLInputElement>(null);
const handleSubmitFile = () => {
const reader = new FileReader();
- const element = document.getElementById('file') as HTMLInputElement;
- const file = element?.files?.[0];
+ const file = inputRef?.current?.files?.[0];
if (file) {
reader.readAsDataURL(file);
- reader.onload = (e: any) => {
- const uri = e.target.result;
+ reader.onload = (event: ProgressEvent<FileReader>) => {
+ const uri = event.target?.result;
post('/uploads', { uri }).then(history.goBack);
};
}
@@ -34,7 +34,7 @@ const TransfersUpload: React.FC = () => {
>
<Formik onSubmit={handleSubmitFile} initialValues={{}}>
<Form id="form">
- <Input name="file" type="file" accept=".pdf" label="Прикрепите файл" id="file" />
+ <Input name="file" type="file" accept=".pdf" label="Прикрепите файл" ref={inputRef} />
</Form>
</Formik>
</Page>
diff --git a/src/services/transfers/index.ts b/src/services/transfers/index.ts
index 37f7b11..1782103 100644
--- a/src/services/transfers/index.ts
+++ b/src/services/transfers/index.ts
@@ -2,9 +2,10 @@ import Form from './TransferForm';
import UploadPage from './TransfersUpload';
import { transformOperation } from '../transforms';
import { ServiceParams } from '../../lib/ServiceContext';
+import { Transfer } from '../types';
-const service: ServiceParams = {
+const service: ServiceParams<Transfer> = {
route: 'transfers',
name: 'Переводы',
nameSingular: 'Перевод',
@@ -27,7 +28,6 @@ const service: ServiceParams = {
],
default: {
operation: 'in',
- records: [],
},
routes: { upload: UploadPage },
Form,
diff --git a/src/services/types.ts b/src/services/types.ts
new file mode 100644
index 0000000..e6e01db
--- /dev/null
+++ b/src/services/types.ts
@@ -0,0 +1,40 @@
+interface BaseModel {
+ _id: string;
+ createdAt: string;
+ updatedAt: string;
+}
+
+export interface Contractor extends BaseModel {
+ name: string;
+ vatId: string;
+ debt: number;
+}
+
+export interface Product extends BaseModel {
+ name: string;
+ description: string;
+ price: number;
+ quantity: number;
+}
+
+export interface Transfer extends BaseModel {
+ date: string;
+ operation: 'in' | 'out';
+ contractorId: string;
+ amount: number;
+ contractor?: Contractor;
+}
+
+export interface Waybill extends BaseModel {
+ date: string;
+ operation: 'in' | 'out';
+ status: 'waiting' | 'executed' | 'cancelled';
+ contractorId: string;
+ contractor?: Contractor;
+ records: {
+ productId: string;
+ price: number;
+ quantity: number;
+ }[];
+ total: number;
+}
diff --git a/src/services/waybills/WaybillForm.tsx b/src/services/waybills/WaybillForm.tsx
index c11ab9e..613989f 100644
--- a/src/services/waybills/WaybillForm.tsx
+++ b/src/services/waybills/WaybillForm.tsx
@@ -7,12 +7,13 @@ import Button from '../../components/Button';
import Select from '../../components/Select';
import Paper from '../../components/Paper';
import hooks from '../../hooks/useAPIClient';
+import { Product, Contractor, Waybill } from '../types';
-const mapper = (item: any) => ({ key: item._id, label: item.name });
+const mapper = (item: Product | Contractor) => ({ key: item._id, label: item.name });
-const WaybillForm: React.FC<FormikProps<any>> = ({ setFieldValue, values }) => {
+const WaybillForm: React.FC<FormikProps<Waybill>> = ({ setFieldValue, values }) => {
const { data: products } = hooks.products.useList();
const { data: contractors } = hooks.contractors.useList();
@@ -51,7 +52,7 @@ const WaybillForm: React.FC<FormikProps<any>> = ({ setFieldValue, values }) => {
/>
<Input name="date" type="date" label="Дата" />
</div>
- {values.records.map((record: any, index: number) => (
+ {values.records.map((record, index) => (
<Paper variant="outlined" className="my-4 md:mx-4" key={`${index}-${record.productId}`}>
<Select
name={`records.${index}.productId`}
diff --git a/src/services/waybills/WaybillPanel.tsx b/src/services/waybills/WaybillPanel.tsx
index 1d1701d..c501fc2 100644
--- a/src/services/waybills/WaybillPanel.tsx
+++ b/src/services/waybills/WaybillPanel.tsx
@@ -3,12 +3,13 @@ import { useHistory } from 'react-router-dom';
import Button from '../../components/Button';
import { patch, baseURL } from '../../requests';
import { PanelProps } from '../../lib/ServiceContext';
+import { Waybill } from '../types';
-const WaybillPanel: React.FC<PanelProps> = ({ item, mutate }) => {
+const WaybillPanel: React.FC<PanelProps<Waybill>> = ({ item, mutate }) => {
const history = useHistory();
- const handleChangeStatus = (status: any) => patch(`/waybills/${item._id}`, { status })
+ const handleChangeStatus = (status: Waybill['status']) => patch(`/waybills/${item._id}`, { status })
.then(() => {
history.push('/waybills');
mutate({ ...item, status });
diff --git a/src/services/waybills/index.ts b/src/services/waybills/index.ts
index 8cd6c0c..a26318b 100644
--- a/src/services/waybills/index.ts
+++ b/src/services/waybills/index.ts
@@ -2,8 +2,9 @@ import Form from './WaybillForm';
import Panel from './WaybillPanel';
import { transformOperation, transformStatus } from '../transforms';
import { ServiceParams } from '../../lib/ServiceContext';
+import { Waybill } from '../types';
-const service: ServiceParams = {
+const service: ServiceParams<Waybill> = {
route: 'waybills',
name: 'Накладные',
nameSingular: 'Накладная',