feat: implement product save functionality with frontend-backend integration

This commit is contained in:
louiscklaw
2025-05-28 12:32:57 +08:00
parent 964ba3e5b0
commit e7b292338b
7 changed files with 217 additions and 6 deletions

View File

@@ -4,7 +4,7 @@ import type { IProductItem } from 'src/types/product';
import useSWR from 'swr';
import { useMemo } from 'react';
import { fetcher, endpoints } from 'src/lib/axios';
import axiosInstance, { fetcher, endpoints } from 'src/lib/axios';
// ----------------------------------------------------------------------
@@ -90,3 +90,74 @@ export function useSearchProducts(query: string) {
return memoizedValue;
}
// ----------------------------------------------------------------------
type SaveProductData = {
id: string;
sku: string;
name: string;
code: string;
price: number;
taxes: number;
tags: string[];
sizes: string[];
publish: string;
gender: string[];
coverUrl: string;
images: string[];
colors: string[];
quantity: number;
category: string;
available: number;
totalSold: number;
description: string;
totalRatings: number;
totalReviews: number;
inventoryType: string;
subDescription: string;
priceSale: number | null;
newLabel: {
content: string;
enabled: boolean;
};
saleLabel: {
content: string;
enabled: boolean;
};
ratings: {
name: string;
starCount: number;
reviewCount: number;
}[];
};
export async function saveProduct(productId: string, saveProductData: SaveProductData) {
console.log('save product ?');
// const url = productId ? [endpoints.product.details, { params: { productId } }] : '';
const res = await axiosInstance.post('http://localhost:7272/api/product/saveProduct', {
data: saveProductData,
});
return res;
// const url = productId ? [endpoints.product.details, { params: { productId } }] : '';
// const { data, isLoading, error, isValidating } = useSWR<SaveProductData>(
// url,
// fetcher,
// swrOptions
// );
// const memoizedValue = useMemo(
// () => ({
// product: data?.product,
// productLoading: isLoading,
// productError: error,
// productValidating: isValidating,
// }),
// [data?.product, error, isLoading, isValidating]
// );
// return memoizedValue;
}

View File

@@ -6,11 +6,11 @@ import Typography from '@mui/material/Typography';
import { RouterLink } from 'src/routes/components';
import { NavUl } from './nav-elements';
import { Iconify } from '../../iconify';
import { NavSubList } from './nav-sub-list';
import { megaMenuClasses } from '../styles';
import { NavCarousel } from './nav-carousel';
import { NavUl } from './nav-elements';
import type { NavListProps } from '../types';

View File

@@ -13,6 +13,7 @@ export default function Page() {
const { id = '' } = useParams();
const { product } = useGetProduct(id);
console.log({ id });
return (
<>

View File

@@ -1,7 +1,7 @@
import type FullCalendar from '@fullcalendar/react';
import type { EventResizeDoneArg } from '@fullcalendar/interaction/index.js';
import type { EventDropArg, DateSelectArg, EventClickArg } from '@fullcalendar/core/index.js';
import type { ICalendarView, ICalendarRange, ICalendarEvent } from 'src/types/calendar';
import type { EventDropArg, DateSelectArg, EventClickArg } from '@fullcalendar/core/index.js';
import { useRef, useState, useCallback } from 'react';

View File

@@ -2,13 +2,13 @@ import type { Theme, SxProps } from '@mui/material/styles';
import type { ICalendarEvent, ICalendarFilters } from 'src/types/calendar';
import Calendar from '@fullcalendar/react';
import { useEffect, startTransition } from 'react';
import listPlugin from '@fullcalendar/list/index.js';
import dayGridPlugin from '@fullcalendar/daygrid/index.js';
import { useEffect, startTransition } from 'react';
import timeGridPlugin from '@fullcalendar/timegrid/index.js';
import timelinePlugin from '@fullcalendar/timeline/index.js';
import interactionPlugin from '@fullcalendar/interaction/index.js';
import { useBoolean, useSetState } from 'minimal-shared/hooks';
import interactionPlugin from '@fullcalendar/interaction/index.js';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';

View File

@@ -23,6 +23,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';
import { paths } from 'src/routes/paths';
import { useRouter } from 'src/routes/hooks';
import { saveProduct } from 'src/actions/product';
import {
_tags,
PRODUCT_SIZE_OPTIONS,
@@ -44,7 +45,7 @@ export const NewProductSchema = zod.object({
description: schemaHelper
.editor({ message: 'Description is required!' })
.min(100, { message: 'Description must be at least 100 characters' })
.max(500, { message: 'Description must be less than 500 characters' }),
.max(50000, { message: 'Description must be less than 50000 characters' }),
images: schemaHelper.files({ message: 'Images is required!' }),
code: zod.string().min(1, { message: 'Product code is required!' }),
sku: zod.string().min(1, { message: 'Product sku is required!' }),
@@ -127,6 +128,8 @@ export function ProductNewEditForm({ currentProduct }: Props) {
const values = watch();
// const saveProduct = useSaveProduct('e99f09a7-dd88-49d5-b1c8-1daf80c2d7b01');
const onSubmit = handleSubmit(async (data) => {
const updatedData = {
...data,
@@ -136,7 +139,14 @@ export function ProductNewEditForm({ currentProduct }: Props) {
try {
await new Promise((resolve) => setTimeout(resolve, 500));
reset();
if (currentProduct) {
console.log('save product');
await saveProduct(currentProduct.id, values);
}
toast.success(currentProduct ? 'Update success!' : 'Create success!');
router.push(paths.dashboard.product.root);
console.info('DATA', updatedData);
} catch (error) {