so i just learing react redux for a while, i want to push select title instead of the select option value after dispatching a post request but i dont know how. can anyone help me?
so here's the problem here
this is my product.js slice:
import {createSlice,createAsyncThunk} from "@reduxjs/toolkit";
import ProductService from "../../../services/ProductService";
const initialState=[];
export const getProducts = createAsyncThunk(
"product/get",
async () =>{
const res = await ProductService.getAll();
return res.data;
}
)
export const saveProduct = createAsyncThunk(
"product/post",
async ({name,category,price,timestamp})=>{
const res = await ProductService.saveProduct({name,category,price,timestamp});
return res.data;
}
)
const productSlice = createSlice({
name:"products",
initialState,
extraReducers:{
[getProducts.fulfilled]:(state,action)=>{
return [...action.payload]
},
[saveProduct.fulfilled]:(state,action)=>{
state.unshift(action.payload);
}
}
})
const {reducer} = productSlice;
export default reducer;
this is my category.js slice :
import {createSlice,createAsyncThunk} from "@reduxjs/toolkit";
import categoryService from "../../../services/CategoryService";
const initialState=[];
export const getCategories = createAsyncThunk(
"category/get",
async ()=>{
const res= await categoryService.getAll()
return res.data;
}
)
const categorySlice = createSlice({
name:"categories",
initialState,
extraReducers:{
[getCategories.fulfilled]:(state,action)=>{
return [...action.payload]
}
}
})
const {reducer} = categorySlice;
export default reducer;
and this is my product component :
import React, {Fragment, useCallback, useEffect, useState} from 'react';
import { Dialog, Transition } from '@headlessui/react'
import {useDispatch, useSelector} from "react-redux";
import {getProducts, saveProduct} from "../public/src/features/productSlice";
import {getCategories} from "../public/src/features/categorySlice";
import {data} from "autoprefixer";
const Products = () => {
const [openModal, setOpenModal] = useState(false);
const toggleOpenModal = () => {
setOpenModal(true)
}
const toggleCloseModal = () => {
setOpenModal(false)
}
const products = useSelector(state=> state.products)
const categories = useSelector(state => state.categories)
const dispatch = useDispatch();
const initFetch = useCallback(() => {
dispatch(getProducts());
dispatch(getCategories());
}, [dispatch])
useEffect(() => {
initFetch()
}, [initFetch])
const initialProductState = {
id:null,
name:"",
category:"",
price:0,
timestamp:""
}
const [productState, setProduct] = useState(initialProductState);
const [submitted, setSubmitted] = useState(false);
const handleInputChange = event => {
const { id, value } = event.target;
setProduct({ ...productState, [id]: value });
};
const saveProductConst = ()=>{
const {name,category,price,timestamp} = productState;
dispatch(saveProduct({name,category,price,timestamp}))
.unwrap()
.then(data=>{
setProduct({
id:data.id,
name: data.name,
category: data.category,
price: data.price,
timestamp: ""
})
setSubmitted(true);
}).catch(e=>{
console.log(e)
})
}
const newProduct = ()=>{
setProduct(initialProductState);
setSubmitted(false)
}
return (
<div className={"bg-gray-200 flex-grow h-screen pt-6 mr-6 overflow-y-auto"}>
<Transition appear show={openModal} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={toggleCloseModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel as={"div"} className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900 border-b border-gray-600"
>
Input Product
</Dialog.Title>
<form>
<div className="mt-2 ">
<div className="mb-6">
<label htmlFor="default-input"
className="block mb-2 text-sm font-medium text-gray-900">Product Name</label>
<input type="text" id="name" value={productState.name||""} onChange={handleInputChange}
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" />
</div>
<div className="mb-6">
<label htmlFor="countries"
className="block mb-2 text-sm font-medium text-gray-900">Select
Category</label>
<select id="category" value={productState.category||""} onChange={handleInputChange}
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
<option defaultValue={"-"}>Choose Option</option>
{categories.map((category)=>(
<option key={category.id} value={category.id}>{category.name}</option>
))}
</select>
</div>
<div className="mb-6">
<label htmlFor="default-input"
className="block mb-2 text-sm font-medium text-gray-900">Price</label>
<input type="number" id="price" value={productState.price||""} onChange={handleInputChange}
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" />
</div>
</div>
<div className="mt-4 border-t dark:border-gray-600">
<button
type="button"
className="inline-flex mt-2 justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={saveProductConst}
>
Submit
</button>
</div>
</form>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
<div className={"flex ml-5 mb-2"}>
<button className={"w-full md:w-auto bg-gray-900 text-white font-medium py-2 px-3 rounded"} onClick={toggleOpenModal} >Create new</button>
</div>
<div className="ml-5 overflow-x-auto relative shadow-md rounded-lg">
<table id={"table"} className="w-full text-sm text-left text-gray-500 ">
<thead className="text-xs text-white uppercase dark:bg-gray-900 dark:border-gray-700">
<tr>
<th scope="col" className="py-3 px-6">
Product name
</th>
<th scope="col" className="py-3 px-6">
Category
</th>
<th scope="col" className="py-3 px-6">
Price
</th>
<th scope="col" className="py-3 px-6">
Action
</th>
</tr>
</thead>
<tbody>
{products.map((product)=>(
<tr className="bg-white border-b" key={product.id}>
<th scope="row"
className="py-4 px-6 font-medium text-gray-900 whitespace-nowrap">
{product.name}
</th>
<td className="py-4 px-6">
{product.category}
</td>
<td className="py-4 px-6">
{product.price}
</td>
<td className="py-4 px-6">
<a href="#"
className="font-medium text-blue-600 hover:underline">Edit</a>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
};
export default Products;
is there's a way to do it? thank you in advance