@licklist/design 0.71.18-dev.4 → 0.71.18-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.js +3 -3
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.d.ts +1 -3
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.d.ts.map +1 -1
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.js +171 -219
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.d.ts +1 -3
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.d.ts.map +1 -1
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.js +77 -35
- package/dist/iframe/ProductWithModifierModal/utils.d.ts +5 -0
- package/dist/iframe/ProductWithModifierModal/utils.d.ts.map +1 -0
- package/dist/iframe/ProductWithModifierModal/utils.js +19 -0
- package/dist/styles/themes/bookedit/index.scss +5 -0
- package/package.json +1 -1
- package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.tsx +3 -3
- package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.tsx +47 -131
- package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.tsx +76 -35
- package/src/iframe/ProductWithModifierModal/utils.ts +28 -0
- package/src/styles/themes/bookedit/index.scss +5 -0
- package/yarn.lock +12 -12
|
@@ -1,44 +1,86 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useEffect } from 'react';
|
|
2
3
|
import { useFormContext, Controller } from 'react-hook-form';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
3
5
|
import { ModifiersSetControl } from './ModifierSetControll.js';
|
|
6
|
+
import { orderProductModifiersQuantity } from '../../utils.js';
|
|
4
7
|
|
|
5
8
|
var ProductControl = function(param) {
|
|
6
|
-
var product = param.product, _param_isLoading = param.isLoading, isLoading = _param_isLoading === void 0 ? false : _param_isLoading, editOrderModifier = param.editOrderModifier
|
|
7
|
-
var
|
|
9
|
+
var product = param.product, _param_isLoading = param.isLoading, isLoading = _param_isLoading === void 0 ? false : _param_isLoading, editOrderModifier = param.editOrderModifier;
|
|
10
|
+
var t = useTranslation() // Added translation hook
|
|
11
|
+
.t;
|
|
12
|
+
var _useFormContext = useFormContext(), control = _useFormContext.control, watch = _useFormContext.watch, isValid = _useFormContext.formState.isValid, clearErrors = _useFormContext.clearErrors;
|
|
8
13
|
var modifiersSet = (product === null || product === void 0 ? void 0 : product.modifiersSet) || [];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
14
|
+
var orderModifiersSets = watch("".concat(product.id, ".orderProductModifiers"));
|
|
15
|
+
useEffect(function() {
|
|
16
|
+
if (!isValid) return;
|
|
17
|
+
clearErrors();
|
|
18
|
+
}, [
|
|
19
|
+
isValid,
|
|
20
|
+
clearErrors
|
|
21
|
+
]);
|
|
22
|
+
return /*#__PURE__*/ jsx("div", {
|
|
23
|
+
className: "mb-8 pt-4",
|
|
24
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
25
|
+
className: "d-flex flex-column",
|
|
26
|
+
children: modifiersSet.map(function(modifierSet) {
|
|
27
|
+
var orderProductModifiersMaxQuantity = orderProductModifiersQuantity(orderModifiersSets, modifierSet);
|
|
28
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
29
|
+
className: "modifier-set-container",
|
|
30
|
+
children: [
|
|
31
|
+
/*#__PURE__*/ jsx("div", {
|
|
32
|
+
className: "modifier-header",
|
|
33
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
34
|
+
className: "title",
|
|
35
|
+
children: modifierSet.name
|
|
36
|
+
})
|
|
37
|
+
}),
|
|
38
|
+
/*#__PURE__*/ jsx(Controller, {
|
|
39
|
+
control: control,
|
|
40
|
+
name: "".concat(product.id, ".").concat(modifierSet.id),
|
|
41
|
+
rules: {
|
|
42
|
+
validate: function() {
|
|
43
|
+
var maxItems = modifierSet.maxItems, minItems = modifierSet.minItems;
|
|
44
|
+
if (!!minItems && orderProductModifiersMaxQuantity < minItems) {
|
|
45
|
+
return t('Validation:quantityMinNumberModifier', {
|
|
46
|
+
min: minItems
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (orderProductModifiersMaxQuantity > maxItems) {
|
|
50
|
+
return t('Validation:quantityMaxNumberModifier', {
|
|
51
|
+
max: maxItems
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
render: function(param) {
|
|
58
|
+
var error = param.fieldState.error;
|
|
59
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
60
|
+
children: [
|
|
61
|
+
/*#__PURE__*/ jsx(ModifiersSetControl, {
|
|
62
|
+
modifierSet: modifierSet,
|
|
63
|
+
productId: product.id,
|
|
64
|
+
modifiers: modifierSet.modifiers,
|
|
65
|
+
isEditMode: !!(editOrderModifier === null || editOrderModifier === void 0 ? void 0 : editOrderModifier.modifiers),
|
|
66
|
+
orderProductModifierSets: editOrderModifier === null || editOrderModifier === void 0 ? void 0 : editOrderModifier.modifiers,
|
|
67
|
+
isLoading: isLoading
|
|
68
|
+
}),
|
|
69
|
+
(error === null || error === void 0 ? void 0 : error.message) && /*#__PURE__*/ jsxs("div", {
|
|
70
|
+
className: "invalid-feedback d-flex pl-4",
|
|
71
|
+
children: [
|
|
72
|
+
error === null || error === void 0 ? void 0 : error.message,
|
|
73
|
+
"!"
|
|
74
|
+
]
|
|
75
|
+
})
|
|
76
|
+
]
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
]
|
|
81
|
+
}, modifierSet.id);
|
|
82
|
+
})
|
|
83
|
+
})
|
|
42
84
|
});
|
|
43
85
|
};
|
|
44
86
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { OrderModifier } from "@licklist/core/dist/DataMapper/Order/OrderModifierDataMapper";
|
|
2
|
+
export type selectModifierType = 'radio' | 'checkbox' | 'selector';
|
|
3
|
+
export declare const filteredOrderModifierSets: (modifiersSet: OrderModifier[]) => OrderModifier[];
|
|
4
|
+
export declare const orderProductModifiersQuantity: (orderModifiersSets: OrderModifier[], modifierSet: any) => number;
|
|
5
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/iframe/ProductWithModifierModal/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAA;AAG5F,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAA;AAElE,eAAO,MAAM,yBAAyB,iBACpB,aAAa,EAAE,KAC5B,aAAa,EAUf,CAAA;AAED,eAAO,MAAM,6BAA6B,uBACpB,aAAa,EAAE,6BAOpC,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { uniqBy } from 'lodash';
|
|
2
|
+
|
|
3
|
+
var filteredOrderModifierSets = function(modifiersSet) {
|
|
4
|
+
if (!modifiersSet) return [];
|
|
5
|
+
var orderModifier = modifiersSet.flat().filter(function(modifier) {
|
|
6
|
+
return !!(modifier === null || modifier === void 0 ? void 0 : modifier.quantity);
|
|
7
|
+
});
|
|
8
|
+
return uniqBy(orderModifier, function(item) {
|
|
9
|
+
return "".concat(item.modifierId, "-").concat(item.modifierSetId);
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var orderProductModifiersQuantity = function(orderModifiersSets, modifierSet) {
|
|
13
|
+
var filteredOrderModifier = filteredOrderModifierSets(orderModifiersSets);
|
|
14
|
+
return filteredOrderModifier.filter(function(item) {
|
|
15
|
+
return (item === null || item === void 0 ? void 0 : item.modifierSetId) === modifierSet.id;
|
|
16
|
+
}).length;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { filteredOrderModifierSets, orderProductModifiersQuantity };
|
package/package.json
CHANGED
|
@@ -54,7 +54,7 @@ export const ProductWithModifierSetForm = ({
|
|
|
54
54
|
const { t } = useTranslation(['App', 'Sale', 'Validation'])
|
|
55
55
|
|
|
56
56
|
const {
|
|
57
|
-
formState: { errors, isSubmitting },
|
|
57
|
+
formState: { errors, isSubmitting, isValid },
|
|
58
58
|
control,
|
|
59
59
|
trigger,
|
|
60
60
|
watch,
|
|
@@ -78,8 +78,9 @@ export const ProductWithModifierSetForm = ({
|
|
|
78
78
|
|
|
79
79
|
const onSubmit = (event) => {
|
|
80
80
|
event.preventDefault()
|
|
81
|
-
trigger()
|
|
81
|
+
trigger(`${product.id}`)
|
|
82
82
|
|
|
83
|
+
if (!isValid) return undefined
|
|
83
84
|
const productOrder: FormOrderItem = {
|
|
84
85
|
id: product.id,
|
|
85
86
|
name: product.name,
|
|
@@ -123,7 +124,6 @@ export const ProductWithModifierSetForm = ({
|
|
|
123
124
|
<div className='manual-booking-form'>
|
|
124
125
|
<ProductControl
|
|
125
126
|
product={product}
|
|
126
|
-
errors={errors}
|
|
127
127
|
editOrderModifier={editOrderModifier}
|
|
128
128
|
/>
|
|
129
129
|
<div className='bg-light m-2 p-2 rounded'>
|
package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.tsx
CHANGED
|
@@ -5,35 +5,27 @@ import { Modifier } from '@licklist/core/dist/DataMapper/Product/ModifierDataMap
|
|
|
5
5
|
import { ModifierSet } from '@licklist/core/dist/DataMapper/Product/ModifierSetDataMapper'
|
|
6
6
|
import { ChangeEvent, useEffect, useMemo } from 'react'
|
|
7
7
|
import { useId } from '@mantine/hooks'
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
FieldErrors,
|
|
11
|
-
FieldValues,
|
|
12
|
-
useFormContext,
|
|
13
|
-
} from 'react-hook-form'
|
|
14
|
-
import { xor, uniqBy } from 'lodash'
|
|
8
|
+
import { Controller, useFormContext } from 'react-hook-form'
|
|
9
|
+
import { xor } from 'lodash'
|
|
15
10
|
import clsx from 'clsx'
|
|
16
11
|
import { Currency } from '@licklist/core/dist/Config'
|
|
17
12
|
import { useIntl } from 'react-intl'
|
|
18
13
|
import { MAX_PRODUCT_NUMBER } from 'src/iframe/order-process/components/CategoryProduct/constants'
|
|
19
14
|
import { NumberInputHorizontal } from 'src/sales'
|
|
15
|
+
import { selectModifierType } from '../../utils'
|
|
20
16
|
|
|
21
17
|
interface ModifiersSetControllProps {
|
|
22
18
|
modifiers?: Modifier[]
|
|
23
19
|
modifierSet: ModifierSet
|
|
24
|
-
modifiersSetWithErrors?: FieldErrors<FieldValues>
|
|
25
20
|
isLoading?: boolean
|
|
26
21
|
isEditMode?: boolean
|
|
27
22
|
productId: number
|
|
28
23
|
orderProductModifierSets?: OrderModifier[]
|
|
29
24
|
}
|
|
30
25
|
|
|
31
|
-
type selectModifierType = 'radio' | 'checkbox' | 'selector'
|
|
32
|
-
|
|
33
26
|
export const ModifiersSetControl = ({
|
|
34
27
|
modifierSet,
|
|
35
28
|
modifiers,
|
|
36
|
-
modifiersSetWithErrors,
|
|
37
29
|
productId,
|
|
38
30
|
isLoading = false,
|
|
39
31
|
isEditMode = false,
|
|
@@ -42,35 +34,12 @@ export const ModifiersSetControl = ({
|
|
|
42
34
|
const { control, watch, setValue, trigger } = useFormContext()
|
|
43
35
|
const { t } = useTranslation('App')
|
|
44
36
|
|
|
45
|
-
const filteredOrderModifierSets = (
|
|
46
|
-
modifiersSet: OrderModifier[],
|
|
47
|
-
): OrderModifier[] => {
|
|
48
|
-
if (!modifiersSet) return []
|
|
49
|
-
const orderModifier = modifiersSet
|
|
50
|
-
.flat()
|
|
51
|
-
.filter((modifier) => !!modifier?.quantity)
|
|
52
|
-
|
|
53
|
-
return uniqBy(
|
|
54
|
-
orderModifier,
|
|
55
|
-
(item) => `${item.modifierId}-${item.modifierSetId}`,
|
|
56
|
-
)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
37
|
const orderModifiersSets = watch(`${productId}.orderProductModifiers`)
|
|
38
|
+
|
|
60
39
|
const { formatNumber } = useIntl()
|
|
61
40
|
const formatToCurrency = (value: number) =>
|
|
62
41
|
formatNumber(value, { style: 'currency', currency: Currency.GBP })
|
|
63
42
|
|
|
64
|
-
const orderProductModifiersQuantity = (orderModifiersSets) => {
|
|
65
|
-
const filteredOrderModifier = filteredOrderModifierSets(orderModifiersSets)
|
|
66
|
-
return filteredOrderModifier
|
|
67
|
-
.flat()
|
|
68
|
-
.filter((item) => item && item.modifierSetId === modifierSet.id).length
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const orderProductModifiersMaxQuantity =
|
|
72
|
-
orderProductModifiersQuantity(orderModifiersSets)
|
|
73
|
-
|
|
74
43
|
const currentOrderModifiersSets = useMemo(
|
|
75
44
|
() =>
|
|
76
45
|
orderProductModifierSets?.filter(
|
|
@@ -141,6 +110,8 @@ export const ModifiersSetControl = ({
|
|
|
141
110
|
orderModifiers,
|
|
142
111
|
)
|
|
143
112
|
}
|
|
113
|
+
|
|
114
|
+
trigger(`${productId}.orderProductModifiers`)
|
|
144
115
|
}
|
|
145
116
|
|
|
146
117
|
useEffect(() => {
|
|
@@ -153,8 +124,6 @@ export const ModifiersSetControl = ({
|
|
|
153
124
|
)
|
|
154
125
|
}, [isEditMode])
|
|
155
126
|
|
|
156
|
-
const modifiersErrors = modifiersSetWithErrors?.modifiers
|
|
157
|
-
|
|
158
127
|
return (
|
|
159
128
|
<>
|
|
160
129
|
{modifierSet?.maxItems === 1 &&
|
|
@@ -162,20 +131,22 @@ export const ModifiersSetControl = ({
|
|
|
162
131
|
!currentOrderModifiersSets?.find((modifier) => !!modifier?.quantity) ? (
|
|
163
132
|
<>
|
|
164
133
|
<Controller
|
|
165
|
-
name={`${modifierSet.id}`}
|
|
166
|
-
data-testid='modifierSet-values-select'
|
|
134
|
+
name={`${productId}.orderProductModifiers.${modifierSet.id}`}
|
|
167
135
|
control={control}
|
|
168
136
|
rules={{
|
|
169
|
-
required:
|
|
137
|
+
required: {
|
|
138
|
+
value: !!modifierSet.minItems,
|
|
139
|
+
message: t('Validation:fieldRequired') as string,
|
|
140
|
+
},
|
|
170
141
|
}}
|
|
171
|
-
render={({ field }) => {
|
|
142
|
+
render={({ field, fieldState }) => {
|
|
172
143
|
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
173
144
|
onChangeModifiers(e, 'radio')
|
|
174
145
|
field.onChange(e.target.id)
|
|
175
146
|
}
|
|
176
147
|
return (
|
|
177
148
|
<>
|
|
178
|
-
{modifiers
|
|
149
|
+
{modifiers.map((modifier) => {
|
|
179
150
|
const selectedOrderModifierId = currentOrderModifiersSets
|
|
180
151
|
?.find(
|
|
181
152
|
(orderModifier) =>
|
|
@@ -184,44 +155,39 @@ export const ModifiersSetControl = ({
|
|
|
184
155
|
?.modifierId?.toString()
|
|
185
156
|
|
|
186
157
|
return (
|
|
187
|
-
<Col key={modifier.id
|
|
188
|
-
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
/>
|
|
202
|
-
</div>
|
|
158
|
+
<Col key={modifier.id}>
|
|
159
|
+
<div className='modifier-container d-flex flex-column p-2'>
|
|
160
|
+
<Form.Check
|
|
161
|
+
className='custom-radio p-2'
|
|
162
|
+
inline
|
|
163
|
+
id={modifier.id.toString()}
|
|
164
|
+
defaultChecked={!!selectedOrderModifierId}
|
|
165
|
+
defaultValue={modifier.id.toString()}
|
|
166
|
+
checked={field.value === modifier.id.toString()}
|
|
167
|
+
onChange={onChange}
|
|
168
|
+
type='radio'
|
|
169
|
+
label={modifier.name}
|
|
170
|
+
name={modifier.name}
|
|
171
|
+
/>
|
|
203
172
|
<div className='mt-3 w-100 pl-2'>
|
|
204
173
|
<p>{modifier.description}</p>
|
|
205
174
|
<div className='price'>
|
|
206
175
|
+ {formatToCurrency(modifier.price)}
|
|
207
176
|
</div>
|
|
208
177
|
</div>
|
|
209
|
-
|
|
178
|
+
</div>
|
|
210
179
|
</Col>
|
|
211
180
|
)
|
|
212
181
|
})}
|
|
182
|
+
{fieldState.error && (
|
|
183
|
+
<div className='invalid-feedback d-block'>
|
|
184
|
+
{fieldState.error.message}
|
|
185
|
+
</div>
|
|
186
|
+
)}
|
|
213
187
|
</>
|
|
214
188
|
)
|
|
215
189
|
}}
|
|
216
190
|
/>
|
|
217
|
-
|
|
218
|
-
{modifiersErrors?.message && (
|
|
219
|
-
<Col>
|
|
220
|
-
<div className='invalid-feedback field-values-error'>
|
|
221
|
-
{modifiersSetWithErrors.message || 'test'}
|
|
222
|
-
</div>
|
|
223
|
-
</Col>
|
|
224
|
-
)}
|
|
225
191
|
</>
|
|
226
192
|
) : (
|
|
227
193
|
<>
|
|
@@ -229,44 +195,20 @@ export const ModifiersSetControl = ({
|
|
|
229
195
|
const selectedOrderModifier = currentOrderModifiersSets?.find(
|
|
230
196
|
(orderModifier) => orderModifier.modifierId === modifier.id,
|
|
231
197
|
)?.quantity
|
|
232
|
-
const requiredModifierSet = modifierSet?.minItems > currentOrderModifiersSets.length
|
|
233
|
-
const errorMessage = (modifiersErrors as FieldError[])?.find(
|
|
234
|
-
(modifier) =>
|
|
235
|
-
modifier.ref && modifier.ref.name === `modifiers[${index}]`,
|
|
236
|
-
)?.message
|
|
237
198
|
|
|
238
199
|
return (
|
|
239
200
|
<>
|
|
240
201
|
{modifier.maxItems === 1 ? (
|
|
241
202
|
<>
|
|
242
203
|
<Controller
|
|
243
|
-
name={
|
|
204
|
+
name={`${productId}.${modifierSet.id}.modifiers[${index}]`}
|
|
244
205
|
control={control}
|
|
245
206
|
rules={{
|
|
246
|
-
required:
|
|
207
|
+
required: {
|
|
208
|
+
value: !!modifier.minItems,
|
|
209
|
+
message: t('Validation:fieldRequired') as string,
|
|
210
|
+
},
|
|
247
211
|
validate: (value) => {
|
|
248
|
-
if (!value) return true
|
|
249
|
-
const {
|
|
250
|
-
maxItems: maxModifierSet,
|
|
251
|
-
minItems: minModifierSet,
|
|
252
|
-
} = modifierSet
|
|
253
|
-
|
|
254
|
-
if (
|
|
255
|
-
orderProductModifiersMaxQuantity < minModifierSet
|
|
256
|
-
) {
|
|
257
|
-
return t('Validation:quantityMinNumberModifier', {
|
|
258
|
-
min: minModifierSet,
|
|
259
|
-
}) as string
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
orderProductModifiersMaxQuantity > maxModifierSet
|
|
264
|
-
) {
|
|
265
|
-
return t('Validation:quantityMaxNumberModifier', {
|
|
266
|
-
max: maxModifierSet,
|
|
267
|
-
}) as string
|
|
268
|
-
}
|
|
269
|
-
|
|
270
212
|
const { maxItems, minItems } = modifier
|
|
271
213
|
if (value?.length > maxItems) {
|
|
272
214
|
return t('Validation:quantityMaxNumberModifier', {
|
|
@@ -283,7 +225,7 @@ export const ModifiersSetControl = ({
|
|
|
283
225
|
return true
|
|
284
226
|
},
|
|
285
227
|
}}
|
|
286
|
-
render={({ field }) => {
|
|
228
|
+
render={({ field, fieldState: { error } }) => {
|
|
287
229
|
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
288
230
|
onChangeModifiers(e, 'checkbox')
|
|
289
231
|
field.onChange(
|
|
@@ -293,10 +235,10 @@ export const ModifiersSetControl = ({
|
|
|
293
235
|
|
|
294
236
|
return (
|
|
295
237
|
<Col
|
|
296
|
-
className='modifier-container pl-
|
|
238
|
+
className='modifier-container pl-4'
|
|
297
239
|
key={modifier.id.toString()}
|
|
298
240
|
>
|
|
299
|
-
<div className='d-flex justify-content-between align-items-center'>
|
|
241
|
+
<div className='d-flex justify-content-between pl-2 align-items-center'>
|
|
300
242
|
<Checkbox
|
|
301
243
|
value={modifier.id}
|
|
302
244
|
onChange={onChange}
|
|
@@ -310,9 +252,9 @@ export const ModifiersSetControl = ({
|
|
|
310
252
|
+ {formatToCurrency(modifier.price)}
|
|
311
253
|
</div>
|
|
312
254
|
</div>
|
|
313
|
-
{
|
|
255
|
+
{error?.message && (
|
|
314
256
|
<div className='invalid-feedback d-flex'>
|
|
315
|
-
{
|
|
257
|
+
{error?.message}
|
|
316
258
|
</div>
|
|
317
259
|
)}
|
|
318
260
|
</Col>
|
|
@@ -329,30 +271,11 @@ export const ModifiersSetControl = ({
|
|
|
329
271
|
control={control}
|
|
330
272
|
name={`${productId}.${modifierSet.id}.modifiers[${index}].quantity`}
|
|
331
273
|
rules={{
|
|
332
|
-
required:
|
|
274
|
+
required: {
|
|
275
|
+
value: !!modifier.minItems,
|
|
276
|
+
message: t('Validation:fieldRequired') as string,
|
|
277
|
+
},
|
|
333
278
|
validate: (value) => {
|
|
334
|
-
// if (!value) return true
|
|
335
|
-
const {
|
|
336
|
-
maxItems: maxModifierSet,
|
|
337
|
-
minItems: minModifierSet,
|
|
338
|
-
} = modifierSet
|
|
339
|
-
if (
|
|
340
|
-
orderProductModifiersMaxQuantity < minModifierSet
|
|
341
|
-
) {
|
|
342
|
-
return t('Validation:quantityMinNumberModifier', {
|
|
343
|
-
min: minModifierSet,
|
|
344
|
-
}) as string
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (
|
|
348
|
-
orderProductModifiersMaxQuantity > maxModifierSet
|
|
349
|
-
) {
|
|
350
|
-
|
|
351
|
-
return t('Validation:quantityMaxNumberModifier', {
|
|
352
|
-
max: maxModifierSet,
|
|
353
|
-
}) as string
|
|
354
|
-
}
|
|
355
|
-
|
|
356
279
|
const { maxItems, minItems } = modifier
|
|
357
280
|
if (value > maxItems) {
|
|
358
281
|
return t('Validation:quantityMaxNumberModifier', {
|
|
@@ -426,13 +349,6 @@ export const ModifiersSetControl = ({
|
|
|
426
349
|
/>
|
|
427
350
|
</>
|
|
428
351
|
)}
|
|
429
|
-
{modifiersErrors?.message && (
|
|
430
|
-
<Col>
|
|
431
|
-
<div className='invalid-feedback field-values-error'>
|
|
432
|
-
{modifiersSetWithErrors.message || 'test'}
|
|
433
|
-
</div>
|
|
434
|
-
</Col>
|
|
435
|
-
)}
|
|
436
352
|
</>
|
|
437
353
|
)
|
|
438
354
|
})}
|
|
@@ -1,55 +1,96 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
Controller,
|
|
4
|
-
FieldErrors,
|
|
5
|
-
FieldValues,
|
|
6
|
-
} from 'react-hook-form'
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
import { useFormContext, Controller } from 'react-hook-form'
|
|
7
3
|
import { OrderModifierByProduct } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
|
|
8
4
|
import { Product } from '@licklist/plugins/dist/types/context/sale/menuSteps'
|
|
5
|
+
import { useTranslation } from 'react-i18next' // Added translation hook
|
|
9
6
|
import { ModifiersSetControl } from './ModifierSetControll'
|
|
7
|
+
import { orderProductModifiersQuantity } from '../../utils'
|
|
10
8
|
|
|
11
9
|
interface ProductControlProps {
|
|
12
10
|
product: Product
|
|
13
11
|
isLoading?: boolean
|
|
14
12
|
editOrderModifier?: OrderModifierByProduct
|
|
15
|
-
errors?: FieldErrors<FieldValues>
|
|
16
13
|
}
|
|
17
14
|
|
|
18
15
|
export const ProductControl = ({
|
|
19
16
|
product,
|
|
20
17
|
isLoading = false,
|
|
21
18
|
editOrderModifier,
|
|
22
|
-
errors,
|
|
23
19
|
}: ProductControlProps) => {
|
|
24
|
-
const {
|
|
20
|
+
const { t } = useTranslation() // Added translation hook
|
|
21
|
+
const {
|
|
22
|
+
control,
|
|
23
|
+
watch,
|
|
24
|
+
formState: { isValid },
|
|
25
|
+
clearErrors,
|
|
26
|
+
} = useFormContext()
|
|
25
27
|
const modifiersSet = product?.modifiersSet || []
|
|
28
|
+
const orderModifiersSets = watch(`${product.id}.orderProductModifiers`)
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!isValid) return
|
|
32
|
+
clearErrors()
|
|
33
|
+
}, [isValid, clearErrors])
|
|
26
34
|
|
|
27
35
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
36
|
+
<div className='mb-8 pt-4'>
|
|
37
|
+
<div className='d-flex flex-column'>
|
|
38
|
+
{modifiersSet.map((modifierSet) => {
|
|
39
|
+
const orderProductModifiersMaxQuantity =
|
|
40
|
+
orderProductModifiersQuantity(orderModifiersSets, modifierSet)
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className='modifier-set-container' key={modifierSet.id}>
|
|
44
|
+
<div className='modifier-header'>
|
|
45
|
+
<div className='title'>{modifierSet.name}</div>
|
|
46
|
+
</div>
|
|
47
|
+
<Controller
|
|
48
|
+
control={control}
|
|
49
|
+
name={`${product.id}.${modifierSet.id}`}
|
|
50
|
+
rules={{
|
|
51
|
+
validate: () => {
|
|
52
|
+
const { maxItems, minItems } = modifierSet
|
|
53
|
+
|
|
54
|
+
if (
|
|
55
|
+
!!minItems &&
|
|
56
|
+
orderProductModifiersMaxQuantity < minItems
|
|
57
|
+
) {
|
|
58
|
+
return t('Validation:quantityMinNumberModifier', {
|
|
59
|
+
min: minItems,
|
|
60
|
+
}) as string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (orderProductModifiersMaxQuantity > maxItems) {
|
|
64
|
+
return t('Validation:quantityMaxNumberModifier', {
|
|
65
|
+
max: maxItems,
|
|
66
|
+
}) as string
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return true
|
|
70
|
+
},
|
|
71
|
+
}}
|
|
72
|
+
render={({ fieldState: { error } }) => (
|
|
73
|
+
<>
|
|
74
|
+
<ModifiersSetControl
|
|
75
|
+
modifierSet={modifierSet}
|
|
76
|
+
productId={product.id}
|
|
77
|
+
modifiers={modifierSet.modifiers}
|
|
78
|
+
isEditMode={!!editOrderModifier?.modifiers}
|
|
79
|
+
orderProductModifierSets={editOrderModifier?.modifiers}
|
|
80
|
+
isLoading={isLoading}
|
|
81
|
+
/>
|
|
82
|
+
{error?.message && (
|
|
83
|
+
<div className='invalid-feedback d-flex pl-4'>
|
|
84
|
+
{error?.message}!
|
|
85
|
+
</div>
|
|
86
|
+
)}
|
|
87
|
+
</>
|
|
88
|
+
)}
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
)
|
|
92
|
+
})}
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
54
95
|
)
|
|
55
96
|
}
|