Add multi_value technical inputs and FA AI prompts.

Support duplicatable list fields in form builder and value UIs, and guide fill prompts to put leftover specs in سایر ویژگی‌ها.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-19 13:50:13 +03:30
co-authored by Cursor
parent 0bbc5bbc12
commit 592540cc7e
17 changed files with 527 additions and 76 deletions
@@ -24,6 +24,7 @@ import {
createUserProduct,
getUserProduct,
getUserProductCategoryTechnicalForm,
hydrateTechnicalFormValues,
listUserProductCategories,
updateUserProduct,
type TechnicalFormField,
@@ -36,6 +37,7 @@ import {
import { galleryMediaIdsAfterChange, resolveDataUrlToMediaId, resolveDataUrlsToMediaIds } from '../services/mediaService'
import { formatIrtInput, parseIrtInput } from '../utils/irtPrice'
import { seoMetaPayload } from '../utils/seoMeta'
import { TechnicalMultiValueEditor } from '../components/TechnicalMultiValueEditor'
import styles from './AddCustomerProductPage.module.css'
type StepId = 1 | 2 | 3
@@ -266,7 +268,12 @@ export function AddCustomerProductPage() {
if (controller.signal.aborted) return
setTechnicalFields(response.form?.fields ?? [])
if (pendingTechnicalValuesRef.current) {
setTechnicalValues(pendingTechnicalValuesRef.current)
setTechnicalValues(
hydrateTechnicalFormValues(
response.form?.fields ?? [],
pendingTechnicalValuesRef.current,
),
)
pendingTechnicalValuesRef.current = null
}
})
@@ -321,8 +328,9 @@ export function AddCustomerProductPage() {
if (!field.isRequired) continue
const value = technicalValues[field.id]
const ok =
field.type === 'multi_select'
? Array.isArray(value) && value.length > 0
field.type === 'multi_select' || field.type === 'multi_value'
? Array.isArray(value) &&
value.some((item) => String(item).trim().length > 0)
: typeof value === 'string' && value.trim().length > 0
if (!ok) {
return t('customerProducts.form.error.technicalRequired')
@@ -483,6 +491,19 @@ export function AddCustomerProductPage() {
)
}
if (field.type === 'multi_value') {
const items = Array.isArray(value) ? value.map(String) : []
return (
<TechnicalMultiValueEditor
id={id}
values={items}
onChange={(next) => setTechnicalField(field.id, next)}
addLabel={t('customerProducts.form.technical.addValue')}
removeLabel={t('customerProducts.form.technical.removeValue')}
/>
)
}
return (
<input
id={id}