130 lines
2.9 KiB
TypeScript
130 lines
2.9 KiB
TypeScript
'use server'
|
|
|
|
import {Meta, ProductLocale, ProductToStore} from '@prisma/client'
|
|
import sanitizeHtml from 'sanitize-html'
|
|
import {z} from 'zod'
|
|
|
|
import {i18nLocalesCodes} from '@/i18n-config'
|
|
import {STORE_ID} from '@/lib/config/constants'
|
|
import {getProductBySlug} from '@/lib/data/models/product'
|
|
import {db} from '@/lib/db/prisma/client'
|
|
import {createProductFormSchema} from '@/lib/schemas/admin/product'
|
|
import {
|
|
cleanEmptyParams,
|
|
dbErrorHandling,
|
|
isEmptyObj,
|
|
slug as slugger
|
|
} from '@/lib/utils'
|
|
|
|
export const onProductCreateAction = async (
|
|
formData: z.infer<typeof createProductFormSchema>
|
|
) => {
|
|
const validatedData = createProductFormSchema.parse(formData)
|
|
|
|
if (!validatedData) return {error: 'Недійсні вхідні дані'}
|
|
|
|
if (validatedData.locales.length < i18nLocalesCodes.length) {
|
|
return {error: 'Заповніть всі мови'}
|
|
}
|
|
|
|
const {published, image} = validatedData
|
|
const price = parseFloat(validatedData.price).toFixed(2)
|
|
const price_promotional = parseFloat(
|
|
validatedData.pricePromotional as string
|
|
).toFixed(2)
|
|
|
|
if (parseFloat(price) < 1) {
|
|
return {error: 'Ціна не може бути нижчою за одну гривню'}
|
|
}
|
|
|
|
const meta: Meta[] = []
|
|
|
|
for (const i in validatedData.meta) {
|
|
const normalizedMeta: any = cleanEmptyParams(validatedData.meta[i])
|
|
|
|
//if (!isEmptyObj(normalizedMeta)) {}
|
|
meta.push(normalizedMeta)
|
|
}
|
|
|
|
const locales: ProductLocale[] = []
|
|
|
|
for (const i in validatedData.locales) {
|
|
const locale = validatedData.locales[i]
|
|
const {title, lang} = locale
|
|
const slug = slugger(title, lang)
|
|
|
|
const result = await getProductBySlug({slug, lang})
|
|
|
|
if (!result) {
|
|
const normalized: any = cleanEmptyParams({slug, ...locale})
|
|
|
|
//locales.push({...normalized, meta: {create: meta[i]}})
|
|
locales.push(normalized)
|
|
} else {
|
|
return {error: `Продукт з такою назвою ${title} вже існує`}
|
|
}
|
|
}
|
|
|
|
try {
|
|
const newProduct = await db.product.create({
|
|
data: {
|
|
image,
|
|
toStore: {
|
|
create: {
|
|
published,
|
|
price,
|
|
pricePromotional: price_promotional,
|
|
storeId: STORE_ID
|
|
}
|
|
},
|
|
locales: {
|
|
create: locales
|
|
}
|
|
}
|
|
})
|
|
|
|
return {success: 'JSON.stringify(newProduct, null, 2)'}
|
|
} catch (error) {
|
|
return dbErrorHandling(error)
|
|
}
|
|
}
|
|
|
|
// const result = sanitizeHtml(description, {
|
|
// allowedTags: [
|
|
// 'p',
|
|
// 'b',
|
|
// 'i',
|
|
// 'h1',
|
|
// 'h2',
|
|
// 'h3',
|
|
// 'h4',
|
|
// 'h5',
|
|
// 'h6',
|
|
// 'em',
|
|
// 'strong',
|
|
// 'a',
|
|
// 'blockquote',
|
|
// 'div',
|
|
// 'li',
|
|
// 'ol',
|
|
// 'ul',
|
|
// 'cite',
|
|
// 'code',
|
|
// 'small',
|
|
// 'sub',
|
|
// 'sup'
|
|
// ],
|
|
// nonBooleanAttributes: [],
|
|
// allowedAttributes: {
|
|
// a: ['href', 'name', 'target'],
|
|
// img: ['src', 'srcset', 'alt', 'title', 'width', 'height', 'loading'],
|
|
// selfClosing: ['img', 'hr']
|
|
// },
|
|
// allowedIframeHostnames: [],
|
|
// parser: {
|
|
// lowerCaseTags: true
|
|
// }
|
|
// })
|
|
//
|
|
// console.log(result)
|