Advertisement
fabiobiondi

React Pro - Real World App - Ch9. 14. Visualizzazione Immagini

Mar 23rd, 2023
1,308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // pages/cms/products/components/CMSProductForm.tsx
  2. import clsx from 'clsx';
  3. import { ChangeEvent, FormEvent, useEffect, useState } from 'react';
  4. import { Product } from '@/model/product';
  5.  
  6. export interface CMSProductFormProps {
  7.   activeItem: Partial<Product> | null;
  8.   onClose: () => void;
  9.   onAdd: (product: Partial<Product>) => void;
  10.   onEdit: (product: Partial<Product>) => void;
  11. }
  12.  
  13. const initialState: Partial<Product> = {
  14.   name: '', cost: 0, description: ''
  15. }
  16.  
  17. export function CMSProductForm(props: CMSProductFormProps) {
  18.   const [formData, setFormData] = useState(initialState);
  19.   const [dirty, setDirty] = useState<boolean>(false);
  20.  
  21.   useEffect(() => {
  22.     if (props.activeItem?.id) {
  23.       setFormData({ ...props.activeItem })
  24.     } else {
  25.       setFormData(initialState)
  26.     }
  27.   }, [props.activeItem])
  28.  
  29.   function changeHandler(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
  30.     const value = e.currentTarget.value;
  31.     const name = e.currentTarget.name;
  32.     setFormData(s => ({ ...s, [name]: value }));
  33.     setDirty(true);
  34.   }
  35.  
  36.   function saveHandler(e: FormEvent<HTMLFormElement>) {
  37.     e.preventDefault();
  38.     if (props.activeItem?.id) {
  39.       props.onEdit(formData);
  40.     } else {
  41.       props.onAdd(formData);
  42.     }
  43.   }
  44.  
  45.   const isNameValid = formData.name?.length;
  46.   const isCostValid = formData.cost! > 0;
  47.   const isDescValid = formData.description?.length;
  48.  
  49.   const isValid = isNameValid && isCostValid && isDescValid;
  50.  
  51.   return (
  52.     <div className={clsx(
  53.       'fixed bg-slate-200 z-10 text-black top-0 w-96  h-full transition-all',
  54.       {'-right-96': !props.activeItem, 'right-0': props.activeItem}
  55.     )}>
  56.  
  57.       <form onSubmit={saveHandler}>
  58.         <div className="flex justify-around h-16">
  59.           <button
  60.             className="text-white w-1/2 bg-green-500 hover:bg-green-600 disabled:opacity-30"
  61.             disabled={!isValid}
  62.             type="submit"
  63.           >SAVE</button>
  64.           <button
  65.             className="text-white w-1/2 bg-slate-500 hover:bg-slate-600"
  66.             onClick={props.onClose}
  67.             type="button"
  68.           >CLOSE</button>
  69.         </div>
  70.  
  71.         {
  72.           formData.img &&
  73.             <img src={formData.img} alt={formData.name} className="w-full" />
  74.         }
  75.  
  76.         <div className="flex flex-col gap-3 mx-3 mt-16">
  77.           Product Name:
  78.           <input
  79.             className={clsx({ 'error': !isNameValid && dirty})}
  80.             type="text" value={formData?.name} name="name" onChange={changeHandler}
  81.           />
  82.  
  83.           Product Cost:
  84.           <input
  85.             className={clsx({ 'error': !isCostValid && dirty})}
  86.             type="number" value={formData?.cost} name="cost" onChange={changeHandler}
  87.           />
  88.  
  89.           Description
  90.           <textarea
  91.             className={clsx({ 'error': !isDescValid && dirty})}
  92.             value={formData.description} name="description" onChange={changeHandler}
  93.           ></textarea>
  94.  
  95.         </div>
  96.       </form>
  97.  
  98.  
  99.     </div>
  100.   )
  101. }
  102.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement