diff options
| author | eug-vs <eug-vs@keemail.me> | 2021-03-14 07:05:45 +0300 | 
|---|---|---|
| committer | eug-vs <eug-vs@keemail.me> | 2021-03-14 07:05:45 +0300 | 
| commit | de4811ce8d2e739901c047f39e9b4b7c18298e74 (patch) | |
| tree | 01450303f497bb6c8433a360efc732f9fb9b4f08 | |
| parent | e615ad0282fa02ce7e81a847b43dd3146f69b769 (diff) | |
| download | commercel-ui-de4811ce8d2e739901c047f39e9b4b7c18298e74.tar.gz | |
feat: add Contractors section
| -rw-r--r-- | src/containers/ContractorForm.tsx | 52 | ||||
| -rw-r--r-- | src/containers/Contractors.tsx | 33 | ||||
| -rw-r--r-- | src/hooks/useAPIClient.ts | 31 | ||||
| -rw-r--r-- | src/index.tsx | 5 | 
4 files changed, 119 insertions, 2 deletions
diff --git a/src/containers/ContractorForm.tsx b/src/containers/ContractorForm.tsx new file mode 100644 index 0000000..7f0d660 --- /dev/null +++ b/src/containers/ContractorForm.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { useParams, useHistory } from 'react-router-dom'; +import { Formik, Form, Field } from 'formik'; +import Page, { Action } from './Page'; +import Input from '../components/Input'; +import { useContractor } from '../hooks/useAPIClient'; +import { post, patch } from '../requests'; + +interface Params { +  id: string; +} + +const actions: Action[] = [ +  { name: 'Назад', variant: 'outlined', route: '..' }, +  { name: 'Сохранить', type: 'submit', form: 'contractorForm' }, +]; + +const ContractorForm: React.FC = () => { +  const history = useHistory(); +  const { id } = useParams<Params>(); +  const { data: contractor } = useContractor(id); + +  const onSubmit = (values: any) => { +    const promise = id +      ? patch(`/contractors/${id}`, values) +      : post('/contractors', values); +    return promise.then(() => history.push('/contractors')); +  }; + +  return ( +    <Page title={id ? contractor?.name : 'Новый контрагент'} actions={actions}> +      {(!id || contractor) && ( +        <Formik +          initialValues={contractor || { name: '', debt: '', vatId: '' }} +          onSubmit={onSubmit} +        > +          {() => ( +            <Form id="contractorForm"> +              <div className="max-w-lg"> +                <Field name="name" label="Название" as={Input} /> +                <Field name="vatId" label="УНП" as={Input} /> +                <Field name="debt" type="number" label="Долг ($)" as={Input} /> +              </div> +            </Form> +          )} +        </Formik> +      )} +    </Page> +  ); +}; + +export default ContractorForm; diff --git a/src/containers/Contractors.tsx b/src/containers/Contractors.tsx new file mode 100644 index 0000000..5d589ea --- /dev/null +++ b/src/containers/Contractors.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useHistory } from 'react-router-dom'; +import Page from './Page'; +import ListTable from '../components/ListTable'; +import { useContractors } from '../hooks/useAPIClient'; + +const fields = [ +  { key: 'vatId', label: 'УНП' }, +  { key: 'name', label: 'Название' }, +  { key: 'debt', label: 'Долг' }, +]; + +const actions = [ +  { name: 'Добавить', route: 'contractors/add' }, +]; + +const Contractors: React.FC = () => { +  const history = useHistory(); +  const { data: contractors } = useContractors(); + +  const handleRowClick = (index: number) => { +    const contractor = contractors && contractors[index]; +    history.push(`/contractors/edit/${contractor?._id}`); +  }; + +  return ( +    <Page title="Контрагенты" actions={actions}> +      <ListTable items={contractors} fields={fields} handleRowClick={handleRowClick} /> +    </Page> +  ); +}; + +export default Contractors; diff --git a/src/hooks/useAPIClient.ts b/src/hooks/useAPIClient.ts index f2f2782..eb427f1 100644 --- a/src/hooks/useAPIClient.ts +++ b/src/hooks/useAPIClient.ts @@ -4,6 +4,9 @@ import { get } from '../requests';  type Response<T> = responseInterface<T, Error>; +const fetcher = (endpoint: string) => get(endpoint).then(response => response.data); + +// Products  export interface Product {    _id: string;    name: string; @@ -15,8 +18,6 @@ export interface Product {    updatedAt: string;  } -const fetcher = (endpoint: string) => get(endpoint).then(response => response.data); -  export const useProducts = (options = {}): Response<Product[]> => {    return useSWR('/products', fetcher, options);  }; @@ -33,3 +34,29 @@ export const useProduct = (_id: string): Response<Product> => {    return result;  }; + +// Contractors +export interface Contractor { +  _id: string; +  name: string; +  fullName: string; +  vatId: string; +  type: string; +  debt: number; +} + +export const useContractors = (options = {}): Response<Product[]> => { +  return useSWR('/contractors', fetcher, options); +}; + +export const useContractor = (_id: string): Response<Product> => { +  const { data: preloadedContractors } = useContractors({ revalidateOnMount: false }); +  const result = useSWR(_id && `/contractors/${_id}`, fetcher); +  if (!result.data && result.isValidating) { +    // If we are waiting for the first result, check if we can maybe +    // get the data from already cached list for the time-being +    const contractor = _.find(preloadedContractors, { _id }); +    return { ...result, data: contractor }; +  } +  return result; +}; diff --git a/src/index.tsx b/src/index.tsx index 8af383e..4ec1db0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -10,6 +10,8 @@ import Header from './components/Header';  import Home from './containers/Home';  import Products from './containers/Products';  import ProductForm from './containers/ProductForm'; +import Contractors from './containers/Contractors'; +import ContractorForm from './containers/ContractorForm';  const navigation = [    { name: 'Главная', route: '/' }, @@ -26,6 +28,9 @@ const App: React.FC = () => (        <Route exact path="/products" component={Products} />        <Route exact path="/products/add" component={ProductForm} />        <Route exact path="/products/edit/:id" component={ProductForm} /> +      <Route exact path="/contractors" component={Contractors} /> +      <Route exact path="/contractors/add" component={ContractorForm} /> +      <Route exact path="/contractors/edit/:id" component={ContractorForm} />      </Switch>    </Router>  );  |