View difference between Paste ID: P07CLKFF and cdV8caTw
SHOW: | | - or go back to the newest paste.
1-
// pages/cms/products/CMSProductsPage.tsx
1+
// pages/cms/products/components/CMSProductForm.tsx
2-
import { useEffect } from 'react';
2+
import clsx from 'clsx';
3-
import { useProductsService } from '@/services/products';
3+
import { ChangeEvent, FormEvent, useEffect, useState } from 'react';
4-
import { ServerError, Spinner } from '@/shared/';
4+
import { Product } from '@/model/product';
5-
import { CMSProductForm } from './components/CMSProductForm';
5+
6-
import { CMSProductsList } from './components/CMSProductsList';
6+
export interface CMSProductFormProps {
7
  activeItem: Partial<Product> | null;
8-
export function CMSProductsPage() {
8+
  onClose: () => void;
9-
  const { state, actions } = useProductsService();
9+
  onAdd: (product: Partial<Product>) => void;
10
  onEdit: (product: Partial<Product>) => void;
11
}
12-
    actions.getProducts()
12+
13-
  }, [])
13+
const initialState: Partial<Product> = {
14
  name: '', cost: 0, description: ''
15
}
16-
    <div>
16+
17-
      <h1 className="title">CMS</h1>
17+
export function CMSProductForm(props: CMSProductFormProps) {
18
  const [formData, setFormData] = useState(initialState);
19-
      {state.pending && <Spinner />}
19+
20-
      {state.error && <ServerError message={state.error} />}
20+
21
    if (props.activeItem?.id) {
22-
      <CMSProductForm
22+
      setFormData({ ...props.activeItem })
23-
        activeItem={state.activeItem}
23+
    } else {
24-
        onClose={actions.resetActiveItem}
24+
      setFormData(initialState)
25-
        onAdd={actions.addProduct}
25+
    }
26-
        onEdit={actions.editProduct}
26+
  }, [props.activeItem])
27-
      />
27+
28
  function changeHandler(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
29-
      <CMSProductsList
29+
    const value = e.currentTarget.value;
30-
        items={state.products}
30+
    const name = e.currentTarget.name;
31-
        activeItem={state.activeItem}
31+
    setFormData(s => ({ ...s, [name]: value }))
32-
        onEditItem={actions.setActiveItem}
32+
  }
33-
        onDeleteItem={actions.deleteProduct}
33+
34-
      />
34+
  function saveHandler(e: FormEvent<HTMLFormElement>) {
35
    e.preventDefault();
36-
      <button
36+
    if (props.activeItem?.id) {
37-
        className="btn primary"
37+
      props.onEdit(formData);
38-
        onClick={() => actions.setActiveItem({})}
38+
    } else {
39-
      >
39+
      props.onAdd(formData);
40-
        ADD NEW
40+
    }
41-
      </button>
41+
  }
42
43
  const isNameValid = formData.name?.length;
44
  const isCostValid = formData.cost! > 0;
45
  const isDescValid = formData.description?.length;
46
47
  const isValid = isNameValid && isCostValid && isDescValid;
48
49
  return (
50
    <div className={clsx(
51
      'fixed bg-slate-200 z-10 text-black top-0 w-96  h-full transition-all',
52
      {'-right-96': !props.activeItem, 'right-0': props.activeItem}
53
    )}>
54
55
      <form onSubmit={saveHandler}>
56
        <div className="flex justify-around h-16">
57
          <button
58
            className="text-white w-1/2 bg-green-500 hover:bg-green-600 disabled:opacity-30"
59
            disabled={!isValid}
60
            type="submit"
61
          >SAVE</button>
62
          <button
63
            className="text-white w-1/2 bg-slate-500 hover:bg-slate-600"
64
            onClick={props.onClose}
65
            type="button"
66
          >CLOSE</button>
67
        </div>
68
69
        <div className="flex flex-col gap-3 mx-3 mt-16">
70
          Product Name:
71
          <input
72
            className={clsx({ 'error': !isNameValid})}
73
            type="text" value={formData?.name} name="name" onChange={changeHandler}
74
          />
75
76
          Product Cost:
77
          <input
78
            className={clsx({ 'error': !isCostValid})}
79
            type="number" value={formData?.cost} name="cost" onChange={changeHandler}
80
          />
81
82
          Description
83
          <textarea
84
            className={clsx({ 'error': !isDescValid})}
85
            value={formData.description} name="description" onChange={changeHandler}
86
          ></textarea>
87
88
        </div>
89
      </form>
90
91
92
    </div>
93
  )
94
}
95