상품 업로드 가즈아

This commit is contained in:
익희 김 2024-12-06 03:07:22 +09:00
parent ff2c1ee2ee
commit 11f7cdf425
11 changed files with 94 additions and 69 deletions

14
package-lock.json generated
View File

@ -62,6 +62,7 @@
"stripe": "^14.9.0",
"stylis": "^4.3.0",
"stylis-plugin-rtl": "^2.1.1",
"uuid": "^11.0.3",
"yup": "^1.3.2"
},
"devDependencies": {
@ -7902,6 +7903,19 @@
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
"license": "ISC"
},
"node_modules/uuid": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz",
"integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/vite-compatible-readable-stream": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/vite-compatible-readable-stream/-/vite-compatible-readable-stream-3.6.1.tgz",

View File

@ -64,6 +64,7 @@
"stripe": "^14.9.0",
"stylis": "^4.3.0",
"stylis-plugin-rtl": "^2.1.1",
"uuid": "^11.0.3",
"yup": "^1.3.2"
},
"devDependencies": {

View File

@ -4,7 +4,7 @@ import { useMutation } from 'react-query';
import axios from 'axios';
import toast from 'react-hot-toast';
import PropTypes from 'prop-types';
import { v4 as uuidv4 } from 'uuid';
// mui
import { styled } from '@mui/material/styles';
import { LoadingButton } from '@mui/lab';
@ -107,7 +107,7 @@ export default function AdminShopForm({ data: currentShop, isLoading: shopLoadin
initialValues: {
title: currentShop?.title || '',
// metaTitle: currentShop?.metaTitle || '',
// cover: currentShop?.cover || null,
cover: currentShop?.cover || null,
logo: currentShop?.logo || null,
description: currentShop?.description || '',
metaDescription: currentShop?.metaDescription || '',
@ -153,6 +153,7 @@ export default function AdminShopForm({ data: currentShop, isLoading: shopLoadin
}
}
});
console.log('formik', formik);
const { errors, values, touched, handleSubmit, setFieldValue, getFieldProps } = formik;
// handle drop logo
const handleDropLogo = async (acceptedFiles) => {
@ -227,9 +228,12 @@ export default function AdminShopForm({ data: currentShop, isLoading: shopLoadin
});
};
const handleTitleChange = (event) => {
const title = event.target.value;
const slug = title.toLowerCase().replace(/\s+/g, '-'); // convert to lowercase, remove special characters, and replace spaces with hyphens
formik.setFieldValue('slug', slug); // set the value of slug in the formik state
// const title = event.target.value;
// UUID
const uniqueKey = uuidv4().replaceAll('-', '');
formik.setFieldValue('slug', uniqueKey); // slug
formik.handleChange(event); // handle the change in formik
};
@ -311,7 +315,7 @@ export default function AdminShopForm({ data: currentShop, isLoading: shopLoadin
{shopLoading ? (
<Skeleton variant="text" width={70} />
) : (
<LabelStyle component={'label'} htmlFor="slug">
<LabelStyle component={'label'} htmlFor="slug" sx={{ display: 'none' }}>
{' '}
{'Slug'}
</LabelStyle>
@ -320,6 +324,7 @@ export default function AdminShopForm({ data: currentShop, isLoading: shopLoadin
<Skeleton variant="rectangular" width="100%" height={56} />
) : (
<TextField
sx={{ display: 'none' }}
fullWidth
id="slug"
{...getFieldProps('slug')}

View File

@ -81,11 +81,11 @@ export default function CategoryForm({ data: currentCategory, isLoading: categor
});
const NewCategorySchema = Yup.object().shape({
name: Yup.string().required('Name is required'),
cover: Yup.mixed().required('Cover is required'),
slug: Yup.string().required('Slug is required'),
description: Yup.string().required('Description is required'),
metaTitle: Yup.string().required('Meta title is required'),
metaDescription: Yup.string().required('Meta description is required')
// cover: Yup.mixed().required('Cover is required'),
slug: Yup.string().required('Slug is required')
// description: Yup.string().required('Description is required'),
// metaTitle: Yup.string().required('Meta title is required'),
// metaDescription: Yup.string().required('Meta description is required')
});
const formik = useFormik({

View File

@ -42,7 +42,6 @@ const STATUS_OPTIONS = ['sale', 'new', 'regular', 'disabled'];
const LabelStyle = styled(Typography)(({ theme }) => ({
...theme.typography.subtitle2,
color: theme.palette.text.secondary,
lineHeight: 2.5
}));
@ -82,25 +81,25 @@ export default function ProductForm({
const NewProductSchema = Yup.object().shape({
name: Yup.string().required('Product name is required'),
code: Yup.string().required('Product code is required'),
tags: Yup.array().min(1, 'Tags is required'),
// tags: Yup.array().min(1, 'Tags is required'),
status: Yup.string().required('Status is required'),
description: Yup.string().required('Description is required'),
// description: Yup.string().required('Description is required'),
category: Yup.string().required('Category is required'),
shop: isVendor ? Yup.string().nullable().notRequired() : Yup.string().required('Shop is required'),
subCategory: Yup.string().required('Sub Category is required'),
slug: Yup.string().required('Slug is required'),
brand: Yup.string().required('brand is required'),
metaTitle: Yup.string().required('Meta title is required'),
metaDescription: Yup.string().required('Meta description is required'),
// brand: Yup.string().required('brand is required'),
// metaTitle: Yup.string().required('Meta title is required'),
// metaDescription: Yup.string().required('Meta description is required'),
images: Yup.array().min(1, 'Images is required'),
sku: Yup.string().required('Sku is required'),
available: Yup.number().required('Quantaty is required'),
colors: Yup.array().required('Color is required'),
sizes: Yup.array().required('Size is required'),
price: Yup.number().required('Price is required'),
priceSale: Yup.number()
.required('Sale price is required')
.lessThan(Yup.ref('price'), 'Sale price should be smaller than price')
// sku: Yup.string().required('Sku is required'),
available: Yup.number().required('Quantaty is required')
// colors: Yup.array().required('Color is required'),
// sizes: Yup.array().required('Size is required')
// price: Yup.number().required('Price is required'),
// priceSale: Yup.number()
// .required('Sale price is required')
// .lessThan(Yup.ref('price'), 'Sale price should be smaller than price')
});
const formik = useFormik({
@ -112,7 +111,7 @@ export default function ProductForm({
slug: currentProduct?.slug || '',
metaTitle: currentProduct?.metaTitle || '',
metaDescription: currentProduct?.metaDescription || '',
brand: currentProduct?.brand || brands[0]?._id || '',
brand: currentProduct?.brand || brands[0]?._id || 'brand',
tags: currentProduct?.tags || [],
gender: currentProduct?.gender || '',
category: currentProduct?.category || (categories.length && categories[0]?._id) || '',
@ -195,7 +194,7 @@ export default function ProductForm({
const title = event.target.value;
const slug = title
.toLowerCase()
.replace(/[^a-zA-Z0-9\s]+/g, '')
// .replace(/[^a-zA-Z0-9\s]+/g, '')
.replace(/\s+/g, '-'); // convert to lowercase, remove special characters, and replace spaces with hyphens
formik.setFieldValue('slug', slug); // set the value of slug in the formik state
formik.handleChange(event); // handle the change in formik

View File

@ -94,9 +94,9 @@ export default function SubCategoryForm({
name: Yup.string().required('Name is required'),
cover: Yup.mixed().required('Cover is required'),
slug: Yup.string().required('Slug is required'),
description: Yup.string().required('Description is required'),
metaTitle: Yup.string().required('Meta title is required'),
metaDescription: Yup.string().required('Meta description is required'),
// description: Yup.string().required('Description is required'),
// metaTitle: Yup.string().required('Meta title is required'),
// metaDescription: Yup.string().required('Meta description is required'),
parentCategory: Yup.string().required('Category is required')
});

View File

@ -68,12 +68,13 @@ export default function BrandsRow({ isLoading, row, handleClickOpen }) {
{isLoading ? (
<Skeleton variant="text" />
) : (
<Label
variant={theme.palette.mode === 'light' ? 'ghost' : 'filled'}
color={row?.status?.toLowerCase() === 'active' ? 'success' : 'error'}
>
{capitalize(row?.status)}
</Label>
// <Label
// variant={theme.palette.mode === 'light' ? 'ghost' : 'filled'}
// color={row?.status?.toLowerCase() === 'active' ? 'success' : 'error'}
// >
// {capitalize(row?.status)}
// </Label>
capitalize(row?.status)
)}
</TableCell>
<TableCell>{isLoading ? <Skeleton variant="text" /> : <> {fDateShort(row.createdAt)} </>}</TableCell>

View File

@ -82,12 +82,13 @@ export default function Category({ isLoading, row, handleClickOpen }) {
{isLoading ? (
<Skeleton variant="text" />
) : (
<Label
variant={theme.palette.mode === 'light' ? 'ghost' : 'filled'}
color={row?.status?.toLowerCase() === 'active' ? 'success' : 'error'}
>
{capitalize(row?.status)}
</Label>
// <Label
// variant={theme.palette.mode === 'light' ? 'ghost' : 'filled'}
// color={row?.status?.toLowerCase() === 'active' ? 'success' : 'error'}
// >
// {capitalize(row?.status)}
// </Label>
capitalize(row?.status)
)}
</TableCell>
<TableCell>{isLoading ? <Skeleton variant="text" /> : <> {fDateShort(row.createdAt)} </>}</TableCell>

View File

@ -80,19 +80,22 @@ export default function ProductRow({ isLoading, row, handleClickOpen, isVendor }
{isLoading ? (
<Skeleton variant="text" />
) : (
<Label
variant={'filled'}
color={
(row?.available < 1 && 'error') ||
(row?.available < 20 && 'warning') ||
(row?.available >= 20 && 'success') ||
'primary'
}
>
{(row?.available < 1 && 'Out of stock') ||
(row?.available < 20 && 'Low stock') ||
(row?.available >= 20 && 'In stock')}
</Label>
// <Label
// variant={'filled'}
// color={
// (row?.available < 1 && 'error') ||
// (row?.available < 20 && 'warning') ||
// (row?.available >= 20 && 'success') ||
// 'primary'
// }
// >
// {(row?.available < 1 && 'Out of stock') ||
// (row?.available < 20 && 'Low stock') ||
// (row?.available >= 20 && 'In stock')}
// </Label>
(row?.available < 1 && '재고 없음') ||
(row?.available < 20 && '재고 부족') ||
(row?.available >= 20 && '재고 있음')
)}
</TableCell>
<TableCell align="left">

View File

@ -80,12 +80,13 @@ export default function Category({ isLoading, row, handleClickOpen }) {
{isLoading ? (
<Skeleton variant="text" />
) : (
<Label
variant={theme.palette.mode === 'light' ? 'ghost' : 'filled'}
color={row?.status?.toLowerCase() === 'active' ? 'success' : 'error'}
>
{capitalize(row?.status)}
</Label>
// <Label
// variant={theme.palette.mode === 'light' ? 'ghost' : 'filled'}
// color={row?.status?.toLowerCase() === 'active' ? 'success' : 'error'}
// >
// {capitalize(row?.status)}
// </Label>
capitalize(row?.status)
)}
</TableCell>
<TableCell>{isLoading ? <Skeleton variant="text" /> : <> {fDateShort(row.createdAt)} </>}</TableCell>

View File

@ -23,7 +23,7 @@ import MuiDrawer from '@mui/material/Drawer';
// icons
import { IoIosArrowBack, IoIosArrowForward } from 'react-icons/io';
import { LuLayoutDashboard } from 'react-icons/lu';
// import { FaRegBuilding } from 'react-icons/fa';
import { FaRegBuilding } from 'react-icons/fa';
import { TbCategory2 } from 'react-icons/tb';
import { BsShop } from 'react-icons/bs';
import { BsCart3 } from 'react-icons/bs';
@ -61,13 +61,13 @@ export const navlinks = [
icon: <TbCategory2 />,
isSearch: true
},
// {
// id: 3,
// title: 'Brands',
// slug: 'brands',
// icon: <FaRegBuilding />,
// isSearch: true
// },
{
id: 3,
title: 'Brands',
slug: 'brands',
icon: <FaRegBuilding />,
isSearch: true
},
{
id: 4,
title: 'Products',