Advertisement
fabiobiondi

React Pro - Real World App - Ch9. 17. Upload Immagini con Cloudinary Widget

Mar 21st, 2023
994
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. declare var cloudinary: any;
  7.  
  8. export interface CMSProductFormProps {
  9.   activeItem: Partial<Product> | null;
  10.   onClose: () => void;
  11.   onAdd: (product: Partial<Product>) => void;
  12.   onEdit: (product: Partial<Product>) => void;
  13. }
  14.  
  15. const initialState: Partial<Product> = {
  16.   name: '', cost: 0, description: '', tmb: '', img: ''
  17. }
  18.  
  19. export function CMSProductForm(props: CMSProductFormProps) {
  20.   const [formData, setFormData] = useState(initialState);
  21.   const [dirty, setDirty] = useState<boolean>(false);
  22.  
  23.   useEffect(() => {
  24.     if (props.activeItem?.id) {
  25.       setFormData({ ...props.activeItem })
  26.     } else {
  27.       setFormData(initialState)
  28.     }
  29.   }, [props.activeItem])
  30.  
  31.   function changeHandler(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
  32.     const value = e.currentTarget.value;
  33.     const name = e.currentTarget.name;
  34.     setFormData(s => ({ ...s, [name]: value }));
  35.     setDirty(true);
  36.   }
  37.  
  38.   function saveHandler(e: FormEvent<HTMLFormElement>) {
  39.     e.preventDefault();
  40.     if (props.activeItem?.id) {
  41.       props.onEdit(formData);
  42.     } else {
  43.       props.onAdd(formData);
  44.     }
  45.   }
  46.  
  47.   function uploadHandler() {
  48.     const uploadWidget = cloudinary.openUploadWidget(
  49.       {
  50.         cloudName: 'dd2shhonr',
  51.         uploadPreset: 'ml_default',
  52.         sources: ['local', 'camera', 'url']
  53.       },
  54.       function(error: any, result: any) {
  55.         if (!error && result.event === 'success') {
  56.           const img = result.info.url;
  57.           const tmb = result.info.thumbnail_url;
  58.           setFormData(s => ({ ...s, img, tmb }))
  59.         }
  60.       }
  61.     )
  62.  
  63.     uploadWidget.open();
  64.   }
  65.  
  66.   const isNameValid = formData.name?.length;
  67.   const isCostValid = formData.cost! > 0;
  68.   const isDescValid = formData.description?.length;
  69.  
  70.   const isValid = isNameValid && isCostValid && isDescValid;
  71.  
  72.   return (
  73.     <div className={clsx(
  74.       'fixed bg-slate-200 z-10 text-black top-0 w-96  h-full transition-all overflow-auto',
  75.       {'-right-96': !props.activeItem, 'right-0': props.activeItem}
  76.     )}>
  77.  
  78.       <form onSubmit={saveHandler}>
  79.         <div className="flex justify-around h-16">
  80.           <button
  81.             className="text-white w-1/2 bg-green-500 hover:bg-green-600 disabled:opacity-30"
  82.             disabled={!isValid}
  83.             type="submit"
  84.           >SAVE</button>
  85.           <button
  86.             className="text-white w-1/2 bg-slate-500 hover:bg-slate-600"
  87.             onClick={props.onClose}
  88.             type="button"
  89.           >CLOSE</button>
  90.         </div>
  91.  
  92.         {
  93.           formData.img &&
  94.           <img src={formData.img} alt={formData.name} className="w-full" />
  95.         }
  96.  
  97.         <div className="flex flex-col gap-3 mx-3 mt-16">
  98.           Product Name:
  99.           <input
  100.             className={clsx({ 'error': !isNameValid && dirty})}
  101.             type="text" value={formData?.name} name="name" onChange={changeHandler}
  102.           />
  103.  
  104.           Product Cost:
  105.           <input
  106.             className={clsx({ 'error': !isCostValid && dirty})}
  107.             type="number" value={formData?.cost} name="cost" onChange={changeHandler}
  108.           />
  109.  
  110.           Description
  111.           <textarea
  112.             className={clsx({ 'error': !isDescValid && dirty})}
  113.             value={formData.description} name="description" onChange={changeHandler}
  114.           ></textarea>
  115.  
  116.           <button className="btn primary" type="button" onClick={uploadHandler}>
  117.             UPLOAD IMAGE
  118.           </button>
  119.         </div>
  120.       </form>
  121.  
  122.       <pre>{JSON.stringify(formData, null, 2)}</pre>
  123.  
  124.  
  125.     </div>
  126.   )
  127. }
  128.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement