@@ -4,17 +4,22 @@ import React, { useEffect, useMemo, useState } from 'react'
44import styled from 'styled-components'
55
66// import React Router Dom Library for Routing..
7- import { Link , useLocation } from 'react-router-dom'
7+ import { Link , useLocation , useNavigate } from 'react-router-dom'
88
99// import required components...
1010import Charts from '../components/Charts'
1111
1212// import produts data from dummyData.js file...
1313import { productsData } from '../Data/dummyData'
1414import { AddOutlined , Publish } from '@mui/icons-material'
15- import { useSelector } from 'react-redux'
15+ import { useDispatch , useSelector } from 'react-redux'
1616import { userRequest } from '../requestAxiosMethod'
1717
18+ // firebase requires functions from firebase library...
19+ import { getStorage , ref , uploadBytesResumable , getDownloadURL } from "firebase/storage" ;
20+ import app from '../firebase'
21+ import { updateProductFailure , updateProductStart , updateProductSuccess } from '../redux/productSlice'
22+
1823// Styling...
1924const Container = styled . div `
2025 flex: 4;
@@ -197,7 +202,82 @@ export default function ProductSinglePage() {
197202 }
198203 getOrderedProductInfo ( )
199204 } , [ months , productId ] )
200- console . log ( product )
205+ // #################################################
206+ // handle update product...
207+ const [ inputs , setInputs ] = useState ( { } )
208+ const [ categories , setCategories ] = useState ( [ ] )
209+ const [ file , setFile ] = useState ( )
210+ const dispatch = useDispatch ( )
211+ const navigate = useNavigate ( )
212+
213+ // handleChange of inputs in group in onetime...
214+ const handleChange = ( e ) => {
215+ setInputs ( ( previous ) => {
216+ return { ...previous , [ e . target . name ] : e . target . value }
217+ } )
218+ }
219+
220+ // handle state of categories and split categories by split method...
221+ const handleCategories = ( e ) => {
222+ setCategories ( e . target . value . split ( ',' ) )
223+ }
224+
225+ // send payload to server by axios post method...
226+ const handleClick = ( e ) => {
227+ // prevent default event (reloading page) when click create...
228+ e . preventDefault ( )
229+ // upload image & inputs to database throght api post request ...
230+ const fileName = new Date ( ) . getTime + file ?. name ;
231+ const storage = getStorage ( app ) ;
232+ const storageRef = ref ( storage , fileName ) ;
233+
234+ const uploadTask = uploadBytesResumable ( storageRef , file ) ;
235+
236+ // Register three observers:
237+ // 1. 'state_changed' observer, called any time the state changes
238+ // 2. Error observer, called on failure
239+ // 3. Completion observer, called on successful completion
240+ uploadTask . on ( 'state_changed' ,
241+ ( snapshot ) => {
242+ // Observe state change events such as progress, pause, and resume
243+ // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
244+ const progress = ( snapshot . bytesTransferred / snapshot . totalBytes ) * 100 ;
245+ console . log ( 'Upload is ' + progress + '% done' ) ;
246+ switch ( snapshot . state ) {
247+ case 'paused' :
248+ console . log ( 'Upload is paused' ) ;
249+ break ;
250+ case 'running' :
251+ console . log ( 'Upload is running' ) ;
252+ break ;
253+ }
254+ } ,
255+ ( error ) => {
256+ // Handle unsuccessful uploads
257+ } ,
258+ ( ) => {
259+ // Handle successful uploads on complete
260+ // For instance, get the download URL: https://firebasestorage.googleapis.com/...
261+ getDownloadURL ( uploadTask . snapshot . ref ) . then ( ( downloadURL ) => {
262+ const product = { ...inputs , image : downloadURL , category : categories }
263+ console . log ( product ) ;
264+ const updateProducts = async ( ) => {
265+ dispatch ( updateProductStart ( ) )
266+ try {
267+ const response = await userRequest . put ( `/products/${ productId } ` , product )
268+ dispatch ( updateProductSuccess ( response . data ) )
269+ . then ( navigate ( '/products' ) )
270+ } catch ( error ) {
271+ dispatch ( updateProductFailure ( ) )
272+ }
273+ }
274+
275+ updateProducts ( ) ;
276+ } ) ;
277+ }
278+ ) ;
279+ }
280+
201281 return (
202282 < Container >
203283 < ProductTitleContainer >
@@ -239,20 +319,23 @@ export default function ProductSinglePage() {
239319 < ProductFormLeft >
240320 < ProductFormLeftItem >
241321 < ProductItemLabel > Product Name</ ProductItemLabel >
242- < ProductItemInput type = "text" placeholder = { product . title } />
322+ < ProductItemInput name = "title" type = "text" placeholder = { product . title } onChange = { handleChange } />
243323 </ ProductFormLeftItem >
244324 < ProductFormLeftItem >
245325 < ProductItemLabel > Product Description</ ProductItemLabel >
246- < ProductItemInput type = "text" placeholder = { product . description } />
326+ < ProductItemInput type = "text" placeholder = { product . description } name = "description" onChange = { handleChange } />
247327 </ ProductFormLeftItem >
248328 < ProductFormLeftItem >
249329 < ProductItemLabel > Price</ ProductItemLabel >
250- < ProductItemInput type = "text" placeholder = { product . price } />
330+ < ProductItemInput type = "number" placeholder = { product . price } name = "price" onChange = { handleChange } />
331+ </ ProductFormLeftItem >
332+ < ProductFormLeftItem >
333+ < ProductItemLabel > Categories</ ProductItemLabel >
334+ < ProductItemInput type = "text" placeholder = { product . category } name = "category" onChange = { handleCategories } />
251335 </ ProductFormLeftItem >
252-
253336 < ProductFormLeftItem >
254337 < ProductItemLabel > In Stock</ ProductItemLabel >
255- < ProductItemSelect name = "inStock" id = "inStock" >
338+ < ProductItemSelect name = "inStock" id = "inStock" onChange = { handleChange } >
256339 < ProductItemOption value = "true" > Yes</ ProductItemOption >
257340 < ProductItemOption value = "false" > No</ ProductItemOption >
258341 </ ProductItemSelect >
@@ -262,9 +345,9 @@ export default function ProductSinglePage() {
262345 < ProductFormImageUpload >
263346 < ProductImage src = { product . image } alt = "" />
264347 < ProductImageUploadLabel for = "file" > < Publish /> </ ProductImageUploadLabel >
265- < ProductImageUploadInput type = "file" id = "file" style = { { display : 'none' } } />
348+ < ProductImageUploadInput type = "file" id = "file" style = { { display : 'none' } } onChange = { ( e ) => setFile ( e . target . files [ 0 ] ) } />
266349 </ ProductFormImageUpload >
267- < ProductUpdateButton > Update</ ProductUpdateButton >
350+ < ProductUpdateButton onClick = { handleClick } > Update</ ProductUpdateButton >
268351 </ ProductFormRight >
269352 </ ProductBottomForm >
270353 </ ProductBottom >
0 commit comments