summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2021-03-25 23:09:49 +0300
committereug-vs <eug-vs@keemail.me>2021-03-25 23:09:49 +0300
commit062f10a25d43b875d187cf582b2ecf96d075ec26 (patch)
treec6b43379325ba22a051827e6a461a8f8fed98402
parent77ac1549e2ab5ac68a1a7464ada9be7e2a2aad92 (diff)
downloadcommercel-ui-062f10a25d43b875d187cf582b2ecf96d075ec26.tar.gz
refactor: move services to separate folder
-rw-r--r--src/containers/Page.tsx2
-rw-r--r--src/containers/Service/ServiceContext.tsx9
-rw-r--r--src/hooks/useAPIClient.ts15
-rw-r--r--src/hooks/useOptions.ts30
-rw-r--r--src/index.tsx16
-rw-r--r--src/services.js104
-rw-r--r--src/services/account/index.ts17
-rw-r--r--src/services/constants.ts11
-rw-r--r--src/services/contractors/ContractorForm.tsx (renamed from src/containers/ContractorForm.tsx)2
-rw-r--r--src/services/contractors/ContractorPanel.tsx (renamed from src/containers/ContractorPanel.tsx)6
-rw-r--r--src/services/contractors/index.ts22
-rw-r--r--src/services/index.ts20
-rw-r--r--src/services/products/ProductForm.tsx (renamed from src/containers/ProductForm.tsx)2
-rw-r--r--src/services/products/index.ts20
-rw-r--r--src/services/transfers/TransferForm.tsx (renamed from src/containers/TransferForm.tsx)8
-rw-r--r--src/services/transfers/TransfersUpload.tsx (renamed from src/containers/TransfersUpload.tsx)23
-rw-r--r--src/services/transfers/index.ts35
-rw-r--r--src/services/waybills/WaybillForm.tsx (renamed from src/containers/WaybillForm.tsx)14
-rw-r--r--src/services/waybills/WaybillPanel.tsx (renamed from src/containers/WaybillPanel.tsx)8
-rw-r--r--src/services/waybills/index.ts27
20 files changed, 197 insertions, 194 deletions
diff --git a/src/containers/Page.tsx b/src/containers/Page.tsx
index c4d4efd..d3a087a 100644
--- a/src/containers/Page.tsx
+++ b/src/containers/Page.tsx
@@ -16,7 +16,7 @@ const style = 'mb-2 flex justify-between md:flex-row md:items-center';
const Page: React.FC<Props> = ({ title, actions, className, children }) => (
<Paper className="xl:m-5">
- <div className={`${style} ${actions?.length > 1 ? 'flex-col items-start' : 'flex-row items-center'}`}>
+ <div className={`${style} ${(actions?.length || 0) > 1 ? 'flex-col items-start' : 'flex-row items-center'}`}>
<span className="text-2xl font-bold">{title}</span>
<div>
{actions?.map(action => (<Button {...action} key={action.name} size="sm">{action.name}</Button>))}
diff --git a/src/containers/Service/ServiceContext.tsx b/src/containers/Service/ServiceContext.tsx
index 68ff907..75ac0fb 100644
--- a/src/containers/Service/ServiceContext.tsx
+++ b/src/containers/Service/ServiceContext.tsx
@@ -1,21 +1,22 @@
import React from 'react';
import { FormikProps } from 'formik';
+import { Action } from '../Page';
export interface PanelProps {
item: any;
mutate: (item: any) => void;
}
-type Route = Record<string, React.FC>;
-
export interface ServiceParams {
route: string;
name: string;
nameSingular: string;
tableFields: any[];
default: Record<string, any>;
- routes?: Route[];
- Form?: React.FC<FormikProps>;
+ routes?: Record<string, React.FC>;
+ actions?: Action[];
+ rowLink?: (item: any) => string;
+ Form?: React.FC<FormikProps<any>>;
Panel?: React.FC<PanelProps>;
}
diff --git a/src/hooks/useAPIClient.ts b/src/hooks/useAPIClient.ts
index 1fa9896..adb6d3f 100644
--- a/src/hooks/useAPIClient.ts
+++ b/src/hooks/useAPIClient.ts
@@ -1,13 +1,14 @@
import useSWR, { responseInterface } from 'swr';
import _ from 'lodash';
import { get } from '../requests';
-import services from '../services';
type Response<T> = responseInterface<T, Error>;
const fetcher = (endpoint: string) => get(endpoint).then(response => response.data);
-const createServiceHooks = <Item = any>(service: string) => {
+const hooks: any = {};
+
+const registerServiceHooks = <Item = any>(service: string) => {
const useList = (query = '', options = {}): Response<Item[]> => {
return useSWR(`/${service}${query}`, fetcher, options);
};
@@ -24,7 +25,7 @@ const createServiceHooks = <Item = any>(service: string) => {
return result;
};
- return { useItem, useList };
+ hooks[service] = { useItem, useList };
};
// Products
@@ -49,11 +50,6 @@ export interface Contractor {
debt: number;
}
-const hooks = services.reduce((acc, { route }) => {
- return _.set(acc, route, createServiceHooks(route));
-}, {});
-
-
hooks.account = {
useList: () => {
const { data: transfers } = useSWR('/transfers', fetcher);
@@ -70,4 +66,5 @@ hooks.account = {
};
-export default hooks as any;
+export { registerServiceHooks };
+export default hooks;
diff --git a/src/hooks/useOptions.ts b/src/hooks/useOptions.ts
deleted file mode 100644
index 2a5aee6..0000000
--- a/src/hooks/useOptions.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { useEffect } from 'react';
-import _ from 'lodash';
-import { Option } from '../components/Select';
-import hooks from './useAPIClient';
-
-// Load service entities and map them into select options
-// setting the default value in formik
-const useOptions = (
- service: string,
- fields: string[],
- values: Record<string, any>,
- setFieldValue: (any) => void,
- mapper = item => ({ key: item._id, label: item.name }),
-): Option[] => {
- const { data: items } = hooks[service].useList();
-
- const options = items?.map(mapper);
-
- useEffect(() => {
- // Initialize all empty fields
- if (items?.length) fields.forEach(field => {
- if (!_.get(values, field)) setFieldValue(field, items[0]._id);
- });
- }, [items, values, setFieldValue]);
-
- return options;
-};
-
-
-export default useOptions;
diff --git a/src/index.tsx b/src/index.tsx
index ffc7ae4..1005a9d 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -11,22 +11,6 @@ import Home from './containers/Home';
import Service from './containers/Service/Service';
import { ServiceProvider } from './containers/Service/ServiceContext';
import services from './services';
-import WaybillForm from './containers/WaybillForm';
-import WaybillPanel from './containers/WaybillPanel';
-import ContractorForm from './containers/ContractorForm';
-import ContractorPanel from './containers/ContractorPanel';
-import ProductForm from './containers/ProductForm';
-import TransferForm from './containers/TransferForm';
-import TransfersUpload from './containers/TransfersUpload';
-
-services[0].Form = ProductForm;
-services[1].Form = ContractorForm;
-services[1].Panel = ContractorPanel;
-services[2].Form = WaybillForm;
-services[2].Panel = WaybillPanel;
-services[3].Form = TransferForm;
-services[3].routes = { upload: TransfersUpload };
-
const navigation = [
{ name: 'Главная', route: '/' },
diff --git a/src/services.js b/src/services.js
deleted file mode 100644
index dfb166e..0000000
--- a/src/services.js
+++ /dev/null
@@ -1,104 +0,0 @@
-import { ServiceParams } from './containers/Service/ServiceContext';
-
-
-const waybillStatusNames = {
- waiting: 'Ожидание',
- executed: 'Проведена',
- cancelled: 'Отменена',
-};
-
-const operationNames = {
- in: 'Приход',
- out: 'Расход',
-};
-
-const services: ServiceParams[] = [
- {
- route: 'products',
- name: 'Товары',
- nameSingular: 'Товар',
- tableFields: [
- { key: 'name', label: 'Название' },
- { key: 'price', label: 'Цена' },
- { key: 'quantity', label: 'На складе' },
- ],
- default: {
- name: '',
- price: '',
- quantity: 0,
- },
- },
- {
- route: 'contractors',
- name: 'Контрагенты',
- nameSingular: 'Контрагент',
- tableFields: [
- { key: 'vatId', label: 'УНП' },
- { key: 'name', label: 'Название' },
- { key: 'debt', label: 'Долг' },
- ],
- default: {
- name: '',
- vatId: '',
- debt: 0,
- },
- },
- {
- route: 'waybills',
- name: 'Накладные',
- nameSingular: 'Накладная',
- tableFields: [
- { key: 'status', label: 'Статус', transform: status => waybillStatusNames[status] },
- { key: 'operation', label: 'Операция', transform: op => operationNames[op] },
- { key: 'total', label: 'Сумма' },
- { key: 'contractor.name', label: 'Контрагент' },
- ],
- default: {
- operation: 'in',
- records: [],
- },
- },
- {
- route: 'transfers',
- name: 'Переводы',
- nameSingular: 'Перевод',
- tableFields: [
- { key: 'date', label: 'Дата', transform: date => new Date(date).toLocaleDateString() },
- { key: 'contractor.name', label: 'Контрагент' },
- { key: 'operation', label: 'Операция', transform: op => operationNames[op] },
- { key: 'amount', label: 'Сумма' },
- ],
- actions: [
- {
- name: 'Загрузить выписку',
- route: '/transfers/upload',
- variant: 'outlined',
- },
- {
- name: 'Добавить',
- route: '/transfers/add',
- },
- ],
- default: {
- operation: 'in',
- records: [],
- },
- },
- {
- route: 'account',
- name: 'Рассчётный счёт',
- tableFields: [
- { key: 'date', label: 'Дата', transform: date => new Date(date).toLocaleDateString() },
- { key: 'amount', label: 'Сумма' },
- ],
- actions: [
- {
- name: 'Загрузить выписку',
- route: '/transfers/upload',
- },
- ],
- rowLink: item => `/transfers?date=${item.date}`,
- },
-];
-
-export default services;
diff --git a/src/services/account/index.ts b/src/services/account/index.ts
new file mode 100644
index 0000000..5b5eb10
--- /dev/null
+++ b/src/services/account/index.ts
@@ -0,0 +1,17 @@
+const service = {
+ route: 'account',
+ name: 'Рассчётный счёт',
+ tableFields: [
+ { key: 'date', label: 'Дата', transform: (date: string) => new Date(date).toLocaleDateString() },
+ { key: 'amount', label: 'Сумма' },
+ ],
+ actions: [
+ {
+ name: 'Загрузить выписку',
+ route: '/transfers/upload',
+ },
+ ],
+ rowLink: (item: any) => `/transfers?date=${item.date}`,
+};
+
+export default service;
diff --git a/src/services/constants.ts b/src/services/constants.ts
new file mode 100644
index 0000000..1461d9c
--- /dev/null
+++ b/src/services/constants.ts
@@ -0,0 +1,11 @@
+export const operationNames = {
+ in: 'Приход',
+ out: 'Расход',
+};
+
+export const waybillStatusNames = {
+ waiting: 'Ожидание',
+ executed: 'Проведена',
+ cancelled: 'Отменена',
+};
+
diff --git a/src/containers/ContractorForm.tsx b/src/services/contractors/ContractorForm.tsx
index 56d38be..d300efc 100644
--- a/src/containers/ContractorForm.tsx
+++ b/src/services/contractors/ContractorForm.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { Form } from 'formik';
-import Input from '../components/Input';
+import Input from '../../components/Input';
const ContractorForm: React.FC = () => {
return (
diff --git a/src/containers/ContractorPanel.tsx b/src/services/contractors/ContractorPanel.tsx
index 6a209c3..ce94c48 100644
--- a/src/containers/ContractorPanel.tsx
+++ b/src/services/contractors/ContractorPanel.tsx
@@ -1,8 +1,8 @@
import React from 'react';
import { useHistory } from 'react-router-dom';
-import Button from '../components/Button';
-import { patch, baseURL } from '../requests';
-import { PanelProps } from './Service/ServiceContext';
+import Button from '../../components/Button';
+import { patch, baseURL } from '../../requests';
+import { PanelProps } from '../../containers/Service/ServiceContext';
const ContractorPanel: React.FC<PanelProps> = ({ item, mutate }) => {
diff --git a/src/services/contractors/index.ts b/src/services/contractors/index.ts
new file mode 100644
index 0000000..124e338
--- /dev/null
+++ b/src/services/contractors/index.ts
@@ -0,0 +1,22 @@
+import Form from './ContractorForm';
+import Panel from './ContractorPanel';
+
+const service = {
+ route: 'contractors',
+ name: 'Контрагенты',
+ nameSingular: 'Контрагент',
+ tableFields: [
+ { key: 'vatId', label: 'УНП' },
+ { key: 'name', label: 'Название' },
+ { key: 'debt', label: 'Долг' },
+ ],
+ default: {
+ name: '',
+ vatId: '',
+ debt: 0,
+ },
+ Form,
+ Panel,
+};
+
+export default service;
diff --git a/src/services/index.ts b/src/services/index.ts
new file mode 100644
index 0000000..7f559f2
--- /dev/null
+++ b/src/services/index.ts
@@ -0,0 +1,20 @@
+import contractors from './contractors';
+import waybills from './waybills';
+import transfers from './transfers';
+import products from './products';
+import account from './account';
+import { registerServiceHooks } from '../hooks/useAPIClient';
+import { ServiceParams } from '../containers/Service/ServiceContext';
+
+const services = [
+ contractors,
+ products,
+ waybills,
+ transfers,
+ account,
+] as ServiceParams[];
+
+services.forEach((service: any) => registerServiceHooks(service.route));
+
+export default services;
+
diff --git a/src/containers/ProductForm.tsx b/src/services/products/ProductForm.tsx
index 6957916..62f0e70 100644
--- a/src/containers/ProductForm.tsx
+++ b/src/services/products/ProductForm.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { Form } from 'formik';
-import Input from '../components/Input';
+import Input from '../../components/Input';
const ProductForm: React.FC = () => {
diff --git a/src/services/products/index.ts b/src/services/products/index.ts
new file mode 100644
index 0000000..7e1509a
--- /dev/null
+++ b/src/services/products/index.ts
@@ -0,0 +1,20 @@
+import Form from './ProductForm';
+
+const service = {
+ route: 'products',
+ name: 'Товары',
+ nameSingular: 'Товар',
+ tableFields: [
+ { key: 'name', label: 'Название' },
+ { key: 'price', label: 'Цена' },
+ { key: 'quantity', label: 'На складе' },
+ ],
+ default: {
+ name: '',
+ price: '',
+ quantity: 0,
+ },
+ Form,
+};
+
+export default service;
diff --git a/src/containers/TransferForm.tsx b/src/services/transfers/TransferForm.tsx
index 801150e..3502609 100644
--- a/src/containers/TransferForm.tsx
+++ b/src/services/transfers/TransferForm.tsx
@@ -1,15 +1,15 @@
import React from 'react';
import { Form, FormikProps } from 'formik';
import moment from 'moment';
-import Input from '../components/Input';
-import Select from '../components/Select';
-import hooks from '../hooks/useAPIClient';
+import Input from '../../components/Input';
+import Select from '../../components/Select';
+import hooks from '../../hooks/useAPIClient';
const mapper = (item: any) => ({ key: item._id, label: item.name });
-const TransferForm: React.FC<FormikProps> = ({ setFieldValue, values }) => {
+const TransferForm: React.FC<FormikProps<any>> = ({ setFieldValue, values }) => {
const { data: contractors } = hooks.contractors.useList();
if (!values.date) setFieldValue('date', moment().format('YYYY-MM-DD'));
diff --git a/src/containers/TransfersUpload.tsx b/src/services/transfers/TransfersUpload.tsx
index bddd0ad..1c81b08 100644
--- a/src/containers/TransfersUpload.tsx
+++ b/src/services/transfers/TransfersUpload.tsx
@@ -1,22 +1,25 @@
import React from 'react';
import { useHistory } from 'react-router-dom';
import { Form, Formik } from 'formik';
-import Button from '../components/Button';
-import Input from '../components/Input';
-import Page, { Action } from './Page';
-import { post } from '../requests';
+import Button from '../../components/Button';
+import Input from '../../components/Input';
+import Page, { Action } from '../../containers/Page';
+import { post } from '../../requests';
const TransfersUpload: React.FC = () => {
const history = useHistory();
const handleSubmitFile = () => {
const reader = new FileReader();
- const file = document.getElementById('file').files[0];
- reader.readAsDataURL(file);
- reader.onload = (e: any) => {
- const uri = e.target.result;
- post('/uploads', { uri }).then(history.goBack);
- };
+ const element = document.getElementById('file') as HTMLInputElement;
+ const file = element?.files?.[0];
+ if (file) {
+ reader.readAsDataURL(file);
+ reader.onload = (e: any) => {
+ const uri = e.target.result;
+ post('/uploads', { uri }).then(history.goBack);
+ };
+ }
};
const actions: Action[] = [
diff --git a/src/services/transfers/index.ts b/src/services/transfers/index.ts
new file mode 100644
index 0000000..09f6e04
--- /dev/null
+++ b/src/services/transfers/index.ts
@@ -0,0 +1,35 @@
+import Form from './TransferForm';
+import UploadPage from './TransfersUpload';
+
+import { operationNames } from '../constants';
+
+const service = {
+ route: 'transfers',
+ name: 'Переводы',
+ nameSingular: 'Перевод',
+ tableFields: [
+ { key: 'date', label: 'Дата', transform: (date: string) => new Date(date).toLocaleDateString() },
+ { key: 'contractor.name', label: 'Контрагент' },
+ { key: 'operation', label: 'Операция', transform: (op: 'in' | 'out') => operationNames[op] },
+ { key: 'amount', label: 'Сумма' },
+ ],
+ actions: [
+ {
+ name: 'Загрузить выписку',
+ route: '/transfers/upload',
+ variant: 'outlined',
+ },
+ {
+ name: 'Добавить',
+ route: '/transfers/add',
+ },
+ ],
+ default: {
+ operation: 'in',
+ records: [],
+ },
+ routes: { upload: UploadPage },
+ Form,
+};
+
+export default service;
diff --git a/src/containers/WaybillForm.tsx b/src/services/waybills/WaybillForm.tsx
index a924cc5..c11ab9e 100644
--- a/src/containers/WaybillForm.tsx
+++ b/src/services/waybills/WaybillForm.tsx
@@ -2,17 +2,17 @@ import React from 'react';
import { Form, FormikProps } from 'formik';
import _ from 'lodash';
import moment from 'moment';
-import Input from '../components/Input';
-import Button from '../components/Button';
-import Select from '../components/Select';
-import Paper from '../components/Paper';
-import hooks from '../hooks/useAPIClient';
+import Input from '../../components/Input';
+import Button from '../../components/Button';
+import Select from '../../components/Select';
+import Paper from '../../components/Paper';
+import hooks from '../../hooks/useAPIClient';
const mapper = (item: any) => ({ key: item._id, label: item.name });
-const WaybillForm: React.FC<FormikProps> = ({ setFieldValue, values }) => {
+const WaybillForm: React.FC<FormikProps<any>> = ({ setFieldValue, values }) => {
const { data: products } = hooks.products.useList();
const { data: contractors } = hooks.contractors.useList();
@@ -51,7 +51,7 @@ const WaybillForm: React.FC<FormikProps> = ({ setFieldValue, values }) => {
/>
<Input name="date" type="date" label="Дата" />
</div>
- {values.records.map((record, index) => (
+ {values.records.map((record: any, index: number) => (
<Paper variant="outlined" className="my-4 md:mx-4" key={`${index}-${record.productId}`}>
<Select
name={`records.${index}.productId`}
diff --git a/src/containers/WaybillPanel.tsx b/src/services/waybills/WaybillPanel.tsx
index b90447e..101a871 100644
--- a/src/containers/WaybillPanel.tsx
+++ b/src/services/waybills/WaybillPanel.tsx
@@ -1,14 +1,14 @@
import React from 'react';
import { useHistory } from 'react-router-dom';
-import Button from '../components/Button';
-import { patch, baseURL } from '../requests';
-import { PanelProps } from './Service/ServiceContext';
+import Button from '../../components/Button';
+import { patch, baseURL } from '../../requests';
+import { PanelProps } from '../../containers/Service/ServiceContext';
const WaybillPanel: React.FC<PanelProps> = ({ item, mutate }) => {
const history = useHistory();
- const handleChangeStatus = status => patch(`/waybills/${item._id}`, { status })
+ const handleChangeStatus = (status: any) => 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
new file mode 100644
index 0000000..f8a4be6
--- /dev/null
+++ b/src/services/waybills/index.ts
@@ -0,0 +1,27 @@
+import Form from './WaybillForm';
+import Panel from './WaybillPanel';
+import { waybillStatusNames, operationNames } from '../constants';
+
+const service = {
+ route: 'waybills',
+ name: 'Накладные',
+ nameSingular: 'Накладная',
+ tableFields: [
+ {
+ key: 'status',
+ label: 'Статус',
+ transform: (status: 'waiting' | 'executed' | 'cancelled') => waybillStatusNames[status],
+ },
+ { key: 'operation', label: 'Операция', transform: (op: 'in' | 'out') => operationNames[op] },
+ { key: 'total', label: 'Сумма' },
+ { key: 'contractor.name', label: 'Контрагент' },
+ ],
+ default: {
+ operation: 'in',
+ records: [],
+ },
+ Form,
+ Panel,
+};
+
+export default service;