Added product update endpoint #28
@@ -1,45 +1,53 @@
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
import {Formik, Form} from 'formik'
|
||||
import * as Yup from "yup";
|
||||
import InputText from '../InputText'
|
||||
import {addCustomTemplate} from '../../services/siteServices'
|
||||
import queryKeys from '../../services/queryKeys';
|
||||
// import InputText from '../InputText'
|
||||
import {updateProduct} from '../../services/siteServices'
|
||||
// import queryKeys from '../../services/queryKeys';
|
||||
|
||||
|
||||
const initialValues = {
|
||||
custom_id: "",
|
||||
provision_name: "",
|
||||
};
|
||||
|
||||
// To get the validation schema
|
||||
const validationSchema = Yup.object().shape({
|
||||
custom_id: Yup.string().required("custom_id is required").min(6, 'must be upto 6 characters').max(25, 'must not exceed 25 characters'),
|
||||
provision_name: Yup.string().required("provision_name is required").min(6, 'must be upto 6 characters').max(200, 'must not exceed 200 characters'),
|
||||
details: Yup.string().required("details text is required").min(6, 'must be upto 6 characters').max(500, 'must not exceed 500 characters'),
|
||||
sale_text: Yup.string().required("sales text is required").min(6, 'must be upto 6 characters').max(500, 'must not exceed 500 characters'),
|
||||
});
|
||||
|
||||
export default function ProductDetails() {
|
||||
export default function ProductDetails({productDetails}) {
|
||||
|
||||
const initialValues = {
|
||||
details: productDetails?.details,
|
||||
sale_text: productDetails?.sale_text,
|
||||
};
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const customTemplate = useMutation({
|
||||
const productUpdate = useMutation({
|
||||
mutationFn: (fields) => {
|
||||
if (!fields.custom_id || !fields.provision_name) {
|
||||
throw new Error('Please provide all fields marked *')
|
||||
}
|
||||
return addCustomTemplate(fields)
|
||||
return updateProduct(fields)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.refetchQueries({
|
||||
queryKey: [...queryKeys.custom_template],
|
||||
// type: 'active',
|
||||
// exact: true,
|
||||
})
|
||||
// queryClient.refetchQueries({
|
||||
// queryKey: [...queryKeys.custom_template],
|
||||
// // type: 'active',
|
||||
// // exact: true,
|
||||
// })
|
||||
},
|
||||
onSettled: ()=>{
|
||||
setTimeout(()=>{
|
||||
productUpdate.reset()
|
||||
}, 3000)
|
||||
}
|
||||
})
|
||||
|
||||
//FUNCTION TO HANDLE ADD TEMPLATE
|
||||
const handleSubmit = (values, helper) => {
|
||||
// customTemplate.mutate(values)
|
||||
const reqData = {
|
||||
details: values.details,
|
||||
product_detail_id: productDetails?.product_detail_id,
|
||||
product_id: productDetails?.product_id,
|
||||
sale_text: values.sale_text,
|
||||
}
|
||||
productUpdate.mutate(reqData)
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -54,50 +62,50 @@ export default function ProductDetails() {
|
||||
className='flex flex-col w-full bg-white dark:bg-black-box text-black-body dark:text-white-body rounded-xl p-16 sm:px-20 sm:py-16 shadow'>
|
||||
<div className='w-full flex flex-col gap-4'>
|
||||
<div className='relative text-input flex flex-col sm:flex-row gap-2 sm:items-center'>
|
||||
<label className={`text-base min-w-36 text-end sm:text-left ${(props.errors.custom_id && props.touched.custom_id) && 'text-red-500'}`}>
|
||||
<label className={`text-base min-w-36 text-end sm:text-left ${(props.errors.details && props.touched.details) && 'text-red-500'}`}>
|
||||
Details
|
||||
</label>
|
||||
<textarea
|
||||
className='p-4 w-full resize-none border outline-none ring-0 dark:bg-transparent dark:border-white-light'
|
||||
rows={4}
|
||||
id='custom_id'
|
||||
id='details'
|
||||
placeholder='Enter your description text here ...'
|
||||
name='custom_id'
|
||||
value={props.values.custom_id}
|
||||
handleChange={props.handleChange}
|
||||
name='details'
|
||||
value={props.values.details}
|
||||
onChange={props.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div className='relative text-input flex flex-col sm:flex-row gap-2 sm:items-center'>
|
||||
<label className={`text-base min-w-36 text-end sm:text-left ${(props.errors.provision_name && props.touched.provision_name) && 'text-red-500'}`}>
|
||||
<label className={`text-base min-w-36 text-end sm:text-left ${(props.errors.sale_text && props.touched.sale_text) && 'text-red-500'}`}>
|
||||
Sales Text
|
||||
</label>
|
||||
<textarea
|
||||
className='p-4 w-full resize-none border outline-none ring-0 dark:bg-transparent dark:border-white-light'
|
||||
rows={4}
|
||||
id='provision_name'
|
||||
id='sale_text'
|
||||
placeholder='Enter your description text here ...'
|
||||
name='provision_name'
|
||||
value={props.values.provision_name}
|
||||
handleChange={props.handleChange}
|
||||
name='sale_text'
|
||||
value={props.values.sale_text}
|
||||
onChange={props.handleChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='h-10 my-5 text-end'>
|
||||
<button type='submit' disabled={customTemplate.isPending}
|
||||
className='px-4 h-full bg-primary text-white font-bold rounded-md'>{customTemplate.isPending ? 'loading...' : 'Update'}</button>
|
||||
<button type='submit' disabled={productUpdate.isPending}
|
||||
className='px-4 h-full bg-primary text-white font-bold rounded-md'>{productUpdate.isPending ? 'loading...' : 'Update'}</button>
|
||||
</div>
|
||||
|
||||
{customTemplate.error &&
|
||||
{productUpdate.error &&
|
||||
<>
|
||||
<div className="w-full text-center">
|
||||
<p className='text-red-500 text-sm'>{customTemplate.error.message}</p>
|
||||
<p className='text-red-500 text-sm'>{productUpdate.error.message}</p>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
{customTemplate.isSuccess &&
|
||||
{productUpdate.isSuccess &&
|
||||
<>
|
||||
<div className="w-full text-center">
|
||||
<p className='text-emerald-500 text-sm'>{'Template Added'}</p>
|
||||
<p className='text-emerald-500 text-sm'>{'Product Details Updated'}</p>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import queryKeys from '../../services/queryKeys'
|
||||
import { getProductView } from "../../services/siteServices";
|
||||
import ProductDetails from './ProductDetails';
|
||||
import RouteLinks from './../../RouteLinks'
|
||||
import getDateTimeFromDateString from '../../helpers/getDateTimeFromDateString';
|
||||
|
||||
export default function ProductView() {
|
||||
|
||||
@@ -30,136 +31,143 @@ export default function ProductView() {
|
||||
},
|
||||
staleTime: 0 // 0 mins
|
||||
})
|
||||
const countryData = data?.data // PRODUCT VIEW LIST
|
||||
console.log('DATA', countryData)
|
||||
const productConfig = data?.data?.product_configuration // PRODUCT CONFIG
|
||||
const productDetails = data?.data?.product_details // PRODUCT DETAILS
|
||||
|
||||
return (
|
||||
<div className='w-full flex flex-col gap-8'>
|
||||
<BreadcrumbCom title={`Product View [${state?.productID}]`} paths={['Dashboard', 'Product View']}/>
|
||||
|
||||
<div className='flex flex-col gap-4'>
|
||||
<div className='flex flex-col gap-2'>
|
||||
<p className='text-lg dark:text-white-light'>Product Configuration</p>
|
||||
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
|
||||
|
||||
<table className="py-2 w-full text-sm">
|
||||
<thead className="py-2 text-sm text-slate-500 text-left">
|
||||
<tr>
|
||||
<th scope="col" className="px-2 py-2" style={{width: '150px'}}>
|
||||
Item
|
||||
</th>
|
||||
<th scope="col" className="px-2">
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
ProductID
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
P000008
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
Description
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
Get Open EMR for practice management
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
Status
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
1
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
Added
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
2025-06-14T23:00:12.43598
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
Banner
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
p5.jpg
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
UID
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
5c45eadb-b8b9-4d20-aaec-4fca5bcc93d3
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<p className='text-lg'>Product Details</p>
|
||||
<ProductDetails />
|
||||
|
||||
<div className='box bg-[aliceblue] dark:bg-black-box text-black-body dark:text-white-body'>
|
||||
{isFetching ?
|
||||
<>
|
||||
<p className='text-slate-800'>Loading...</p>
|
||||
</>
|
||||
: isError ?
|
||||
<p className='text-red-500'>{error.message}</p>
|
||||
:
|
||||
<div className='flex flex-col gap-4'>
|
||||
<div className='flex flex-col gap-2'>
|
||||
<p className='text-lg dark:text-white-light'>Product Configuration</p>
|
||||
<div className='box bg-white dark:bg-black-box text-black-body dark:text-white-body'>
|
||||
|
||||
<table className="py-2 w-full text-sm">
|
||||
<thead className="py-2 text-sm text-slate-500 text-left">
|
||||
<tr>
|
||||
<th scope="col" className="px-2 py-2" style={{width: '150px'}}>
|
||||
Item
|
||||
</th>
|
||||
<th scope="col" className="px-2">
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
ProductID
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
{productConfig?.product_id}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
Description
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
{productConfig?.description}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
Status
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
{productConfig?.status}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
Added
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
{getDateTimeFromDateString(productConfig?.added)}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
Banner
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
{productConfig?.banner}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="py-2 border-t border-dashed border-slate-300">
|
||||
<td className="px-2 py-2">
|
||||
<div
|
||||
className='w-full min-w-48 flex items-center gap-2 whitespace-nowrap'>
|
||||
<div className="text-left">
|
||||
UID
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-2">
|
||||
<div className="text-left">
|
||||
{productConfig?.uid}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<p className='text-lg'>Product Details</p>
|
||||
<ProductDetails productDetails={productDetails} />
|
||||
|
||||
<div className='box bg-[aliceblue] dark:bg-black-box text-black-body dark:text-white-body'>
|
||||
<div className='flex flex-col gap-2'>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -148,6 +148,14 @@ export const addCustomTemplate = (reqData) => {
|
||||
return postAuxEnd('/template/custom-add', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO ADD CUSTOM TEMPLATE
|
||||
export const updateProduct = (reqData) => {
|
||||
let postData = {
|
||||
...reqData
|
||||
}
|
||||
return postAuxEnd('/product-update', postData, false)
|
||||
}
|
||||
|
||||
// FUNCTION TO GET CUSTOM TEMPLATE DATA
|
||||
export const getCustomTemplate = (reqData) => {
|
||||
const postData = { ...reqData }
|
||||
|
||||
Reference in New Issue
Block a user