@deenruv/admin-dashboard 1.0.5 → 1.0.9

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.
Files changed (76) hide show
  1. package/dist/DeenruvAdminPanel.js +5 -4
  2. package/dist/DeenruvDeveloperIndicator.js +1 -1
  3. package/dist/components/ContentAreaSkeleton.js +5 -0
  4. package/dist/components/Menu/LanguagesDropdown.js +4 -3
  5. package/dist/components/Menu/Navigation.js +10 -9
  6. package/dist/components/Menu/Notifications.js +2 -1
  7. package/dist/components/Menu/flag-icons.js +16 -0
  8. package/dist/components/Menu/index.js +3 -2
  9. package/dist/pages/Custom404.js +16 -2
  10. package/dist/pages/Root.js +2 -2
  11. package/dist/pages/admins/Detail.js +7 -7
  12. package/dist/pages/admins/_components/AdminDetailView.js +17 -9
  13. package/dist/pages/channels/Detail.js +12 -12
  14. package/dist/pages/channels/_components/ChannelDetailView.js +25 -17
  15. package/dist/pages/collections/Detail.js +8 -7
  16. package/dist/pages/collections/List.js +1 -2
  17. package/dist/pages/collections/_components/CollectionDetailView.js +65 -22
  18. package/dist/pages/collections/_components/CollectionProductVariantsDrawer.js +1 -1
  19. package/dist/pages/countries/Detail.js +5 -5
  20. package/dist/pages/countries/_components/CountryDetailView.js +15 -8
  21. package/dist/pages/customer-groups/Detail.js +3 -3
  22. package/dist/pages/customer-groups/_components/CustomerGroupsDetailView.js +4 -4
  23. package/dist/pages/customers/Detail.js +6 -8
  24. package/dist/pages/customers/_components/AddressForm.js +48 -60
  25. package/dist/pages/customers/_components/AddressesCard.js +1 -1
  26. package/dist/pages/customers/_components/CustomerDetailView.js +9 -9
  27. package/dist/pages/dashboard/Dashboard.js +3 -2
  28. package/dist/pages/extensions/Extensions.js +12 -13
  29. package/dist/pages/facets/Detail.js +6 -6
  30. package/dist/pages/facets/_components/AddFacetValueDialog.js +39 -39
  31. package/dist/pages/facets/_components/FacetDetailView.js +19 -12
  32. package/dist/pages/global-settings/GlobalSettingsComponent.js +9 -8
  33. package/dist/pages/global-settings/index.js +4 -4
  34. package/dist/pages/orders/List.js +2 -1
  35. package/dist/pages/orders/_components/AddressCard.js +123 -78
  36. package/dist/pages/orders/_components/CustomerSelectCard.js +38 -43
  37. package/dist/pages/orders/_components/FulfillmentModal.js +47 -28
  38. package/dist/pages/orders/_components/ModifyingCard.js +30 -13
  39. package/dist/pages/orders/_components/OrderLineCustomFields.js +2 -1
  40. package/dist/pages/orders/_components/PossibleOrderStates.js +2 -1
  41. package/dist/pages/orders/_components/ProductsCard.js +2 -1
  42. package/dist/pages/orders/_components/SurchargeCard.js +58 -60
  43. package/dist/pages/orders/_components/TopActions.js +2 -1
  44. package/dist/pages/payment-methods/Detail.js +8 -7
  45. package/dist/pages/payment-methods/_components/PaymentMethodDetailView.js +22 -14
  46. package/dist/pages/products/Detail.js +9 -7
  47. package/dist/pages/products/_components/AddOptionGroupDialog.js +36 -14
  48. package/dist/pages/products/_components/BasicFieldsCard.js +5 -2
  49. package/dist/pages/products/_components/OptionValueCard.js +25 -23
  50. package/dist/pages/products/_components/ProductDetailSidebar.js +15 -7
  51. package/dist/pages/products/_components/ProductDetailView.js +51 -17
  52. package/dist/pages/products/_components/Variant.js +105 -57
  53. package/dist/pages/promotions/Detail.js +13 -11
  54. package/dist/pages/promotions/_components/OptionsCard.js +1 -1
  55. package/dist/pages/promotions/_components/PromotionDetailSidebar.js +9 -6
  56. package/dist/pages/promotions/_components/PromotionDetailView.js +26 -20
  57. package/dist/pages/roles/Detail.js +5 -5
  58. package/dist/pages/roles/_components/RoleDetailView.js +13 -8
  59. package/dist/pages/sellers/Detail.js +4 -4
  60. package/dist/pages/sellers/_components/SellerDetailView.js +4 -4
  61. package/dist/pages/shipping-methods/Detail.js +14 -12
  62. package/dist/pages/shipping-methods/_components/Lines.js +1 -1
  63. package/dist/pages/shipping-methods/_components/ShippingMethodDetailView.js +26 -13
  64. package/dist/pages/shipping-methods/_components/TestCard.js +67 -21
  65. package/dist/pages/status/_components/Health.js +2 -1
  66. package/dist/pages/status/_components/Jobs.js +2 -6
  67. package/dist/pages/stock-locations/Detail.js +4 -4
  68. package/dist/pages/stock-locations/_components/StockLocationDetailView.js +5 -5
  69. package/dist/pages/tax-categories/Detail.js +4 -4
  70. package/dist/pages/tax-categories/_components/TaxCategoryDetailView.js +7 -7
  71. package/dist/pages/tax-rates/Detail.js +8 -8
  72. package/dist/pages/tax-rates/_components/TaxRateDetailView.js +13 -9
  73. package/dist/pages/zones/Detail.js +4 -4
  74. package/dist/pages/zones/_components/ZoneDetailView.js +8 -7
  75. package/dist/version.js +1 -1
  76. package/package.json +79 -78
@@ -24,5 +24,5 @@ export const CollectionProductVariantsDrawer = ({ collectionId, collectionName,
24
24
  };
25
25
  return (_jsx("div", { children: _jsxs(Drawer, { direction: "right", children: [children, _jsxs(DrawerContent, { className: "top-0 right-0 left-auto mt-0 w-[85vw]", children: [_jsxs(DrawerHeader, { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "shrink-0", children: [_jsx(DrawerTitle, { children: t('drawer.title', { collectionName, interpolation: { escapeValue: false } }) }), _jsx(DrawerDescription, { children: t('drawer.count', { count }) }), ' '] }), _jsxs(Select, { value: firstFilterKey, onValueChange: (e) => {
26
26
  setFilter({ [e]: {} });
27
- }, children: [_jsx(SelectTrigger, { className: "w-[280px]", children: _jsx(SelectValue, { placeholder: t('drawer.filter.title') }) }), _jsx(SelectContent, { children: filterOptions.map((i) => (_jsx(SelectItem, { className: "cursor-pointer", value: i, children: t(`drawer.filter.labels.${i}`) }, i))) })] }), filter && handleFilterValue(firstFilterKey)] }), _jsx(DrawerClose, { children: _jsx(Button, { children: t('drawer.close') }) })] }), _jsx(ContentsTable, { collectionId: collectionId, filter: filter })] })] }) }));
27
+ }, children: [_jsx(SelectTrigger, { className: "w-[280px]", children: _jsx(SelectValue, { placeholder: t('drawer.filter.title') }) }), _jsx(SelectContent, { children: filterOptions.map((i) => (_jsx(SelectItem, { className: "cursor-pointer", value: i, children: t(`drawer.filter.labels.${i}`) }, i))) })] }), filter && handleFilterValue(firstFilterKey)] }), _jsx(DrawerClose, { asChild: true, children: _jsx(Button, { children: t('drawer.close') }) })] }), _jsx(ContentsTable, { collectionId: collectionId, filter: filter })] })] }) }));
28
28
  };
@@ -14,14 +14,14 @@ export const CountriesDetailPage = () => {
14
14
  const [remove] = useMutation(DeleteCountryMutation);
15
15
  const { translationsValidator, stringValidator } = useValidators();
16
16
  const onSubmitHandler = useCallback((data) => {
17
- if (!data.code?.validatedValue) {
17
+ if (!data.code) {
18
18
  throw new Error('Code is required.');
19
19
  }
20
20
  const inputData = {
21
- code: data.code.validatedValue,
22
- enabled: data.enabled?.validatedValue || data.enabled?.initialValue,
23
- translations: data.translations?.validatedValue,
24
- ...(data.customFields?.validatedValue ? { customFields: data.customFields?.validatedValue } : {}),
21
+ code: data.code,
22
+ enabled: data.enabled,
23
+ translations: data.translations,
24
+ ...(data.customFields ? { customFields: data.customFields } : {}),
25
25
  };
26
26
  if (id) {
27
27
  return update({ input: { id, ...inputData } });
@@ -3,26 +3,33 @@ import { useCallback, useEffect } from 'react';
3
3
  import { Input, Label, Switch, useSettings, useDetailView, DetailViewMarker, CustomCard, CardIcons, setInArrayBy, useTranslation, } from '@deenruv/react-ui-devkit';
4
4
  export const CountryDetailView = () => {
5
5
  const { form, entity, fetchEntity, id } = useDetailView('countries-detail-view', 'CreateCountryInput', 'code', 'enabled', 'translations', 'customFields');
6
- const { base: { setField, state }, } = form;
6
+ const { base } = form;
7
7
  const { t } = useTranslation('countries');
8
8
  const { translationsLanguage: currentTranslationLng } = useSettings();
9
- const translations = state?.translations?.value || [];
9
+ const translations = base.watch('translations') || [];
10
10
  const currentTranslationValue = translations.find((v) => v.languageCode === currentTranslationLng);
11
11
  useEffect(() => {
12
12
  (async () => {
13
13
  const resp = await fetchEntity();
14
14
  if (!resp)
15
15
  return;
16
- setField('code', resp.code);
17
- setField('translations', resp.translations);
18
- setField('enabled', resp.enabled);
16
+ base.setField('code', resp.code);
17
+ base.setField('translations', resp.translations);
18
+ base.setField('enabled', resp.enabled);
19
19
  })();
20
20
  }, []);
21
21
  const setTranslationField = useCallback((field, e) => {
22
- setField('translations', setInArrayBy(translations, (t) => t.languageCode !== currentTranslationLng, {
22
+ const baseTranslation = currentTranslationValue ?? {
23
+ languageCode: currentTranslationLng,
24
+ name: '',
25
+ };
26
+ base.setField('translations', setInArrayBy(translations, (t) => t.languageCode === currentTranslationLng, {
27
+ ...baseTranslation,
23
28
  [field]: e,
24
29
  languageCode: currentTranslationLng,
25
30
  }));
26
- }, [currentTranslationLng, translations]);
27
- return (_jsx("main", { className: "min-h-96", children: _jsxs("div", { className: "mx-auto mt-2 flex w-full max-w-[1440px] flex-col gap-4 2xl:px-8", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.name'), value: currentTranslationValue?.name ?? undefined, onChange: (e) => setTranslationField('name', e.target.value), errors: state.translations?.errors, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.code'), value: state.code?.value, onChange: (e) => setField('code', e.target.value), errors: state.code?.errors, required: true }) }), _jsxs("div", { className: "mt-7 flex basis-full items-center gap-3 md:basis-1/3", children: [_jsx(Switch, { checked: state.enabled?.value, onCheckedChange: (e) => setField('enabled', e) }), _jsx(Label, { children: t('details.basic.enabled') })] })] }) }), _jsx(DetailViewMarker, { position: 'countries-detail-view' })] }) }));
31
+ }, [currentTranslationLng, translations, currentTranslationValue]);
32
+ return (_jsx("main", { className: "min-h-96", children: _jsxs("div", { className: "mx-auto mt-2 flex w-full max-w-[1440px] flex-col gap-4 2xl:px-8", children: [_jsx(CustomCard, { title: t('details.basic.title'), icon: _jsx(CardIcons.basic, {}), color: "green", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.name'), value: currentTranslationValue?.name ?? undefined, onChange: (e) => setTranslationField('name', e.target.value), errors: base.formState.errors?.translations?.message
33
+ ? [base.formState.errors.translations.message]
34
+ : undefined, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.code'), value: base.watch('code'), onChange: (e) => base.setField('code', e.target.value), errors: base.formState.errors?.code?.message ? [base.formState.errors.code.message] : undefined, required: true }) }), _jsxs("div", { className: "mt-7 flex basis-full items-center gap-3 md:basis-1/3", children: [_jsx(Switch, { checked: base.watch('enabled'), onCheckedChange: (e) => base.setField('enabled', e) }), _jsx(Label, { children: t('details.basic.enabled') })] })] }) }), _jsx(DetailViewMarker, { position: 'countries-detail-view' })] }) }));
28
35
  };
@@ -35,12 +35,12 @@ export const CustomerGroupsDetailPage = () => {
35
35
  const [remove] = useMutation(DeleteCustomerGroupMutation);
36
36
  const { nameValidator } = useValidators();
37
37
  const onSubmitHandler = useCallback((data) => {
38
- if (!data.name?.validatedValue) {
38
+ if (!data.name) {
39
39
  throw new Error('Name is required.');
40
40
  }
41
41
  const inputData = {
42
- name: data.name.validatedValue,
43
- ...(data.customFields?.validatedValue ? { customFields: data.customFields?.validatedValue } : {}),
42
+ name: data.name,
43
+ ...(data.customFields ? { customFields: data.customFields } : {}),
44
44
  };
45
45
  if (id) {
46
46
  return update({ input: { id, ...inputData } });
@@ -6,16 +6,16 @@ export const CustomerGroupsDetailView = () => {
6
6
  const contentLng = useSettings((p) => p.translationsLanguage);
7
7
  const { t } = useTranslation('customerGroups');
8
8
  const { id, form, entity, fetchEntity } = useDetailView('customerGroups-detail-view', ...CUSTOMER_GROUPS_FORM_KEYS);
9
- const { base: { setField, state }, } = form;
9
+ const { base } = form;
10
10
  useEffect(() => {
11
11
  (async () => {
12
12
  const res = await fetchEntity();
13
13
  if (!res)
14
14
  return;
15
- setField('name', res.name);
15
+ base.setField('name', res.name);
16
16
  })();
17
17
  }, [contentLng]);
18
- return (_jsx("main", { className: "min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('basic.header'), icon: _jsx(CardIcons.basic, {}), children: _jsx(Input, { className: "w-1/2", label: t('basic.name'), value: state.name?.value, onChange: (e) => setField('name', e.target.value), errors: state.name?.errors, required: true }) }), _jsx(DetailViewMarker, { position: 'customerGroups-detail-view' }), _jsx(EntityCustomFields, { entityName: "customerGroup", id: id, hideButton: true, onChange: (customFields) => {
19
- setField('customFields', customFields);
18
+ return (_jsx("main", { className: "min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(CustomCard, { title: t('basic.header'), icon: _jsx(CardIcons.basic, {}), children: _jsx(Input, { className: "w-1/2", label: t('basic.name'), value: base.watch('name'), onChange: (e) => base.setField('name', e.target.value), errors: base.formState.errors?.name?.message ? [base.formState.errors.name.message] : undefined, required: true }) }), _jsx(DetailViewMarker, { position: 'customerGroups-detail-view' }), _jsx(EntityCustomFields, { entityName: "customerGroup", id: id, hideButton: true, onChange: (customFields) => {
19
+ base.setField('customFields', customFields);
20
20
  }, initialValues: entity && 'customFields' in entity ? { customFields: entity.customFields } : { customFields: {} } })] }) }));
21
21
  };
@@ -46,14 +46,12 @@ export const CustomersDetailPage = () => {
46
46
  },
47
47
  onSubmitted: (data) => {
48
48
  const sharedInput = {
49
- emailAddress: data.emailAddress?.validatedValue,
50
- firstName: data.firstName?.validatedValue,
51
- lastName: data.lastName?.validatedValue,
52
- phoneNumber: data.phoneNumber?.validatedValue,
53
- title: data.title?.validatedValue,
54
- ...('customFields' in data && data.customFields?.validatedValue
55
- ? { customFields: data.customFields.validatedValue }
56
- : {}),
49
+ emailAddress: data.emailAddress,
50
+ firstName: data.firstName,
51
+ lastName: data.lastName,
52
+ phoneNumber: data.phoneNumber,
53
+ title: data.title,
54
+ ...('customFields' in data && data.customFields ? { customFields: data.customFields } : {}),
57
55
  };
58
56
  if (!sharedInput.emailAddress || !sharedInput.firstName || !sharedInput.lastName)
59
57
  return;
@@ -1,77 +1,65 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef, useEffect, useImperativeHandle } from 'react';
3
- import { Input, SimpleSelect, useGFFLP, useServer, EntityCustomFields, useTranslation, } from '@deenruv/react-ui-devkit';
3
+ import { Input, SimpleSelect, useDeenruvForm, z, useServer, EntityCustomFields, useTranslation, } from '@deenruv/react-ui-devkit';
4
4
  export const AddressForm = forwardRef(({ initialValues: address, addressId, onInputChange }, ref) => {
5
5
  const { t } = useTranslation('customers');
6
6
  const countries = useServer((p) => p.countries);
7
- const { state, setField, checkIfAllFieldsAreValid } = useGFFLP('CreateAddressInput', 'city', 'company', 'countryCode', 'fullName', 'phoneNumber', 'postalCode', 'streetLine1', 'streetLine2', 'province', 'customFields')({
8
- fullName: {
9
- initialValue: address?.fullName,
10
- validate: (v) => {
11
- if (!v || v === '')
12
- return [t('selectAddress.nameRequired')];
13
- },
14
- },
15
- company: { initialValue: address?.company },
16
- streetLine1: {
17
- initialValue: address?.streetLine1,
18
- validate: (v) => {
19
- if (!v || v === '')
20
- return [t('selectAddress.streetRequired')];
21
- },
22
- },
23
- streetLine2: { initialValue: address?.streetLine2 },
24
- postalCode: {
25
- initialValue: address?.postalCode,
26
- validate: (v) => {
27
- if (!v || v === '')
28
- return [t('selectAddress.postalCodeRequired')];
29
- },
30
- },
31
- countryCode: {
32
- initialValue: address?.country.code,
33
- validate: (v) => {
34
- if (!v || v === '')
35
- return [t('selectAddress.countryRequired')];
36
- },
37
- },
38
- phoneNumber: {
39
- initialValue: address?.phoneNumber,
40
- validate: (v) => {
41
- if (!v || v === '')
42
- return [t('selectAddress.phoneNumberRequired')];
43
- },
44
- },
45
- city: {
46
- initialValue: address?.city,
47
- validate: (v) => {
48
- if (!v || v === '')
49
- return [t('selectAddress.cityRequired')];
50
- },
7
+ const addressSchema = z.object({
8
+ fullName: z.string().min(1, t('selectAddress.nameRequired')),
9
+ company: z.string().default(''),
10
+ streetLine1: z.string().min(1, t('selectAddress.streetRequired')),
11
+ streetLine2: z.string().default(''),
12
+ postalCode: z.string().min(1, t('selectAddress.postalCodeRequired')),
13
+ countryCode: z.string().min(1, t('selectAddress.countryRequired')),
14
+ phoneNumber: z.string().min(1, t('selectAddress.phoneNumberRequired')),
15
+ city: z.string().min(1, t('selectAddress.cityRequired')),
16
+ province: z.string().default(''),
17
+ customFields: z.record(z.string(), z.any()).default({}),
18
+ });
19
+ const form = useDeenruvForm({
20
+ schema: addressSchema,
21
+ defaultValues: {
22
+ fullName: address?.fullName ?? '',
23
+ company: address?.company ?? '',
24
+ streetLine1: address?.streetLine1 ?? '',
25
+ streetLine2: address?.streetLine2 ?? '',
26
+ postalCode: address?.postalCode ?? '',
27
+ countryCode: address?.country?.code ?? '',
28
+ phoneNumber: address?.phoneNumber ?? '',
29
+ city: address?.city ?? '',
30
+ province: address?.province ?? '',
31
+ customFields: {},
51
32
  },
52
- province: { initialValue: address?.province },
53
33
  });
34
+ const formValues = form.watch();
54
35
  useImperativeHandle(ref, () => ({
55
- validate: checkIfAllFieldsAreValid,
36
+ validate: () => {
37
+ // trigger is async but ref API expects sync boolean — use formState.isValid
38
+ // which is reliable because mode is 'onTouched' and all fields have been interacted with
39
+ void form.trigger();
40
+ return form.formState.isValid;
41
+ },
56
42
  }));
57
43
  useEffect(() => {
58
44
  const input = {
59
- countryCode: state.countryCode.validatedValue,
60
- streetLine1: state.streetLine1.validatedValue,
61
- streetLine2: state.streetLine2.validatedValue,
62
- city: state.city.validatedValue,
63
- company: state.company.validatedValue,
64
- fullName: state.fullName.validatedValue,
65
- phoneNumber: state.phoneNumber.validatedValue,
66
- postalCode: state.postalCode.validatedValue,
67
- province: state.province?.validatedValue,
68
- ...(state.customFields?.validatedValue ? { customFields: state.customFields?.validatedValue } : {}),
45
+ countryCode: formValues.countryCode,
46
+ streetLine1: formValues.streetLine1,
47
+ streetLine2: formValues.streetLine2,
48
+ city: formValues.city,
49
+ company: formValues.company,
50
+ fullName: formValues.fullName,
51
+ phoneNumber: formValues.phoneNumber,
52
+ postalCode: formValues.postalCode,
53
+ province: formValues.province,
54
+ ...(formValues.customFields && Object.keys(formValues.customFields).length > 0
55
+ ? { customFields: formValues.customFields }
56
+ : {}),
69
57
  };
70
58
  onInputChange(input);
71
- }, [state]);
72
- return (_jsxs("form", { className: "flex flex-col gap-3 overflow-auto", children: [_jsx(Input, { label: t('selectAddress.inputNameLabel'), placeholder: t('selectAddress.inputNamePlaceholder'), value: state.fullName?.value ?? undefined, defaultValue: state?.fullName?.value ?? undefined, onChange: (e) => setField('fullName', e.target.value), errors: state.fullName?.errors, required: true }), _jsx(Input, { label: t('selectAddress.inputCompanyLabel'), placeholder: t('selectAddress.inputCompanyPlaceholder'), value: state.company?.value ?? undefined, defaultValue: state?.company?.value ?? undefined, onChange: (e) => setField('company', e.target.value), errors: state.company?.errors }), _jsx(Input, { label: t('selectAddress.inputStreetLabel'), placeholder: t('selectAddress.inputStreetPlaceholder'), value: state.streetLine1?.value, defaultValue: state?.streetLine1?.value, onChange: (e) => setField('streetLine1', e.target.value), errors: state.streetLine1?.errors, required: true }), _jsx(Input, { label: t('selectAddress.inputStreet2Label'), placeholder: t('selectAddress.inputStreet2Placeholder'), value: state.streetLine2?.value ?? undefined, defaultValue: state?.streetLine2?.value ?? undefined, onChange: (e) => setField('streetLine2', e.target.value), errors: state.streetLine2?.errors }), _jsx(Input, { label: t('selectAddress.inputCityLabel'), placeholder: t('selectAddress.inputCityPlaceholder'), defaultValue: state?.city?.value ?? undefined, onChange: (e) => setField('city', e.target.value), errors: state.city?.errors, required: true }), _jsx(Input, { label: t('selectAddress.inputProvinceLabel'), placeholder: t('selectAddress.inputProvincePlaceholder'), defaultValue: state?.province?.value ?? undefined, onChange: (e) => setField('province', e.target.value), errors: state.province?.errors }), _jsx(Input, { label: t('selectAddress.inputPostalLabel'), placeholder: t('selectAddress.inputPostalPlaceholder'), value: state.postalCode?.value ?? undefined, defaultValue: state?.postalCode?.value ?? undefined, onChange: (e) => setField('postalCode', e.target.value), errors: state.postalCode?.errors, required: true }), _jsx(Input, { label: t('selectAddress.inputPhoneLabel'), placeholder: t('selectAddress.inputPhonePlaceholder'), value: state.phoneNumber?.value ?? undefined, defaultValue: state?.phoneNumber?.value ?? undefined, onChange: (e) => setField('phoneNumber', e.target.value), errors: state.phoneNumber?.errors, required: true }), _jsx(SimpleSelect, { label: t('selectAddress.countrySelectLabel'), options: countries.map((c) => ({ label: c.name, value: c.code })), value: state.countryCode?.value, onValueChange: (value) => setField('countryCode', value), errors: state.countryCode?.errors, required: true }), addressId && (_jsx(EntityCustomFields, { id: addressId, entityName: "address", hideButton: true, initialValues: address && 'customFields' in address
59
+ }, [formValues]);
60
+ return (_jsxs("form", { className: "flex flex-col gap-3 overflow-auto", children: [_jsx(Input, { label: t('selectAddress.inputNameLabel'), placeholder: t('selectAddress.inputNamePlaceholder'), value: formValues.fullName ?? undefined, defaultValue: formValues.fullName ?? undefined, onChange: (e) => form.setField('fullName', e.target.value), errors: form.formState.errors.fullName?.message ? [form.formState.errors.fullName.message] : undefined, required: true }), _jsx(Input, { label: t('selectAddress.inputCompanyLabel'), placeholder: t('selectAddress.inputCompanyPlaceholder'), value: formValues.company ?? undefined, defaultValue: formValues.company ?? undefined, onChange: (e) => form.setField('company', e.target.value), errors: form.formState.errors.company?.message ? [form.formState.errors.company.message] : undefined }), _jsx(Input, { label: t('selectAddress.inputStreetLabel'), placeholder: t('selectAddress.inputStreetPlaceholder'), value: formValues.streetLine1, defaultValue: formValues.streetLine1, onChange: (e) => form.setField('streetLine1', e.target.value), errors: form.formState.errors.streetLine1?.message ? [form.formState.errors.streetLine1.message] : undefined, required: true }), _jsx(Input, { label: t('selectAddress.inputStreet2Label'), placeholder: t('selectAddress.inputStreet2Placeholder'), value: formValues.streetLine2 ?? undefined, defaultValue: formValues.streetLine2 ?? undefined, onChange: (e) => form.setField('streetLine2', e.target.value), errors: form.formState.errors.streetLine2?.message ? [form.formState.errors.streetLine2.message] : undefined }), _jsx(Input, { label: t('selectAddress.inputCityLabel'), placeholder: t('selectAddress.inputCityPlaceholder'), defaultValue: formValues.city ?? undefined, onChange: (e) => form.setField('city', e.target.value), errors: form.formState.errors.city?.message ? [form.formState.errors.city.message] : undefined, required: true }), _jsx(Input, { label: t('selectAddress.inputProvinceLabel'), placeholder: t('selectAddress.inputProvincePlaceholder'), defaultValue: formValues.province ?? undefined, onChange: (e) => form.setField('province', e.target.value), errors: form.formState.errors.province?.message ? [form.formState.errors.province.message] : undefined }), _jsx(Input, { label: t('selectAddress.inputPostalLabel'), placeholder: t('selectAddress.inputPostalPlaceholder'), value: formValues.postalCode ?? undefined, defaultValue: formValues.postalCode ?? undefined, onChange: (e) => form.setField('postalCode', e.target.value), errors: form.formState.errors.postalCode?.message ? [form.formState.errors.postalCode.message] : undefined, required: true }), _jsx(Input, { label: t('selectAddress.inputPhoneLabel'), placeholder: t('selectAddress.inputPhonePlaceholder'), value: formValues.phoneNumber ?? undefined, defaultValue: formValues.phoneNumber ?? undefined, onChange: (e) => form.setField('phoneNumber', e.target.value), errors: form.formState.errors.phoneNumber?.message ? [form.formState.errors.phoneNumber.message] : undefined, required: true }), _jsx(SimpleSelect, { label: t('selectAddress.countrySelectLabel'), options: countries.map((c) => ({ label: c.name, value: c.code })), value: formValues.countryCode, onValueChange: (value) => form.setField('countryCode', value), errors: form.formState.errors.countryCode?.message ? [form.formState.errors.countryCode.message] : undefined, required: true }), addressId && (_jsx(EntityCustomFields, { id: addressId, entityName: "address", hideButton: true, initialValues: address && 'customFields' in address
73
61
  ? { customFields: address.customFields }
74
62
  : { customFields: {} }, onChange: (cf) => {
75
- setField('customFields', cf);
63
+ form.setField('customFields', cf);
76
64
  }, additionalData: {}, withoutBorder: true }))] }));
77
65
  });
@@ -5,5 +5,5 @@ import { PlusCircle } from 'lucide-react';
5
5
  import { AddressDialog } from "./AddressDialog";
6
6
  export const AddressesCard = ({ addresses, customerId, onActionCompleted }) => {
7
7
  const { t } = useTranslation('customers');
8
- return (_jsx(CustomCard, { title: t('addresses.header'), icon: _jsx(CardIcons.address, {}), color: "green", bottomRight: customerId && (_jsx(AddressDialog, { customerId: customerId, onActionCompleted: onActionCompleted, children: _jsxs(Button, { variant: "secondary", className: "flex items-center gap-2", children: [_jsx(PlusCircle, {}), t('addresses.addBtn')] }) })), children: _jsx("div", { className: "flex gap-4", children: addresses?.length ? (addresses?.map((a) => _jsx(Address, { onActionCompleted: onActionCompleted, address: a, customerId: customerId }))) : (_jsx("p", { className: "w-full text-center", children: t(customerId ? 'addresses.empty' : 'addresses.createCustomerFirst') })) }) }));
8
+ return (_jsx(CustomCard, { title: t('addresses.header'), icon: _jsx(CardIcons.address, {}), color: "green", bottomRight: customerId && (_jsx(AddressDialog, { customerId: customerId, onActionCompleted: onActionCompleted, children: _jsxs(Button, { variant: "secondary", className: "flex items-center gap-2", children: [_jsx(PlusCircle, {}), t('addresses.addBtn')] }) })), children: _jsx("div", { className: "flex gap-4", children: addresses?.length ? (addresses?.map((a) => (_jsx(Address, { onActionCompleted: onActionCompleted, address: a, customerId: customerId }, a.id)))) : (_jsx("p", { className: "w-full text-center", children: t(customerId ? 'addresses.empty' : 'addresses.createCustomerFirst') })) }) }));
9
9
  };
@@ -16,18 +16,18 @@ export const CustomerDetailView = () => {
16
16
  const [addresses, setAddresses] = useState([]);
17
17
  const contentLng = useSettings((p) => p.translationsLanguage);
18
18
  const { form, entity, id, fetchEntity } = useDetailView('customers-detail-view', ...CUSTOMER_FORM_KEYS);
19
- const { base: { setField, state }, } = form;
19
+ const { base } = form;
20
20
  const handleFetchEntity = useCallback(async () => {
21
21
  const res = await fetchEntity();
22
22
  if (!res)
23
23
  return;
24
- setField('title', res.title);
25
- setField('phoneNumber', res.phoneNumber);
26
- setField('firstName', res.firstName);
27
- setField('lastName', res.lastName);
28
- setField('emailAddress', res.emailAddress);
24
+ base.setField('title', res.title);
25
+ base.setField('phoneNumber', res.phoneNumber);
26
+ base.setField('firstName', res.firstName);
27
+ base.setField('lastName', res.lastName);
28
+ base.setField('emailAddress', res.emailAddress);
29
29
  if ('customFields' in res)
30
- setField('customFields', res.customFields);
30
+ base.setField('customFields', res.customFields);
31
31
  setAddresses(res.addresses);
32
32
  }, []);
33
33
  useEffect(() => {
@@ -35,7 +35,7 @@ export const CustomerDetailView = () => {
35
35
  await handleFetchEntity();
36
36
  })();
37
37
  }, [contentLng]);
38
- return (_jsx("main", { className: "min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(PersonalDataCard, { setField: setField, state: state }), _jsx(DetailViewMarker, { position: 'customers-detail-view' }), _jsx(EntityCustomFields, { entityName: "customer", id: id, hideButton: true, additionalData: {}, initialValues: entity && 'customFields' in entity ? { customFields: entity.customFields } : { customFields: {} }, onChange: (cf) => {
39
- setField('customFields', cf);
38
+ return (_jsx("main", { className: "min-h-96", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(PersonalDataCard, { setField: base.setField, state: base }), _jsx(DetailViewMarker, { position: 'customers-detail-view' }), _jsx(EntityCustomFields, { entityName: "customer", id: id, hideButton: true, additionalData: {}, initialValues: entity && 'customFields' in entity ? { customFields: entity.customFields } : { customFields: {} }, onChange: (cf) => {
39
+ base.setField('customFields', cf);
40
40
  } }), id && _jsx(AddressesCard, { addresses: addresses, customerId: id, onActionCompleted: handleFetchEntity })] }) }));
41
41
  };
@@ -1,10 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { DashboardWidgets, useWidgetsStore, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup, Button, DropdownMenuCheckboxItem, useTranslation, } from '@deenruv/react-ui-devkit';
3
+ import { useShallow } from 'zustand/react/shallow';
3
4
  export const Dashboard = () => {
4
5
  const { t } = useTranslation('common');
5
- const { widgets, setShowWidget } = useWidgetsStore((state) => ({
6
+ const { widgets, setShowWidget } = useWidgetsStore(useShallow((state) => ({
6
7
  widgets: state.widgets,
7
8
  setShowWidget: state.setShowWidget,
8
- }));
9
+ })));
9
10
  return (_jsxs("div", { className: "px-4 pt-2 pb-4 md:px-8 md:py-4", children: [_jsx("div", { className: "mb-4 flex justify-end", children: !!widgets.length && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", children: t('widgets.add') }) }), _jsxs(DropdownMenuContent, { className: "w-42", children: [_jsx(DropdownMenuLabel, { children: t('widgets.title') }), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuGroup, { children: widgets.map((widget) => (_jsx(DropdownMenuCheckboxItem, { checked: widget.visible, onCheckedChange: (checked) => setShowWidget(widget.id, checked), children: widget.name }, widget.id))) })] })] })) }), _jsx(DashboardWidgets, {})] }));
10
11
  };
@@ -1,9 +1,7 @@
1
- 'use client';
2
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
2
  import { useMemo, useState } from 'react';
4
- import { Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Input, PageBlock, Switch, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, usePluginStore, } from '@deenruv/react-ui-devkit';
5
- import { BarChart3, Box, Check, ChevronDown, Code2, Cog, Download, FileCode, Filter, Grid3X3, Info, LayoutDashboard, List, MessageSquare, Puzzle, RefreshCw, Search, Settings, Table, X, } from 'lucide-react';
6
- import { Separator } from '@radix-ui/react-dropdown-menu';
3
+ import { Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Input, PageBlock, Separator, Switch, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, usePluginStore, } from '@deenruv/react-ui-devkit';
4
+ import { BarChart3, Box, Check, ChevronDown, Code2, Cog, FileCode, Filter, Grid3X3, Info, LayoutDashboard, List, MessageSquare, Puzzle, RefreshCw, Search, Settings, Table, X, } from 'lucide-react';
7
5
  const getCategoryIcon = (category) => {
8
6
  switch (category) {
9
7
  case 'visualization':
@@ -35,16 +33,16 @@ const getStatusBadge = (status) => {
35
33
  }
36
34
  };
37
35
  export const Extensions = () => {
38
- const { plugins: _plugins, changePluginStatus } = usePluginStore();
36
+ const { allPlugins: _plugins, changePluginStatus } = usePluginStore();
39
37
  const [searchTerm, setSearchTerm] = useState('');
40
38
  const [categoryFilter, setCategoryFilter] = useState('all');
41
39
  const [statusFilter, setStatusFilter] = useState('all');
42
40
  const [view, setView] = useState('grid');
43
41
  const plugins = useMemo(() => _plugins.map((plugin) => ({
44
42
  ...plugin,
45
- description: 'No description provided',
46
- category: 'unknown',
47
- author: 'Unknown',
43
+ description: plugin.description || 'No description provided',
44
+ category: plugin.category || 'unknown',
45
+ author: plugin.author || 'Deenruv',
48
46
  })), [_plugins]);
49
47
  const filteredPlugins = plugins.filter((plugin) => {
50
48
  const matchesSearch = plugin.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
@@ -54,11 +52,12 @@ export const Extensions = () => {
54
52
  return matchesSearch && matchesCategory && matchesStatus;
55
53
  });
56
54
  const totalPlugins = plugins.length;
57
- const activePlugins = plugins.filter((p) => p).length;
55
+ const activePlugins = plugins.filter((p) => p.status === 'active').length;
56
+ const inactivePlugins = plugins.length - activePlugins;
58
57
  const totalWidgets = plugins.reduce((sum, plugin) => sum + (plugin.widgets?.length || 0), 0);
59
58
  const totalComponents = plugins.reduce((sum, plugin) => sum + (plugin.components?.length || 0), 0);
60
59
  const categories = ['all', ...new Set(plugins.map((p) => p.category))];
61
- return (_jsx(PageBlock, { children: _jsxs("div", { className: "flex flex-col gap-6", children: [_jsx("div", { className: "flex flex-col gap-2", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Extensions Dashboard" }), _jsx("p", { className: "mt-1 text-muted-foreground", children: "Manage and monitor your installed plugins" })] }), _jsxs(Button, { children: [_jsx(Download, { className: "mr-2 size-4" }), "Install New Extension"] })] }) }), _jsxs("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Total Extensions" }), _jsx(Puzzle, { className: "size-4 text-muted-foreground" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: totalPlugins }), _jsxs("p", { className: "text-xs text-muted-foreground", children: [activePlugins, " active, ", totalPlugins - activePlugins, " inactive"] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Total Widgets" }), _jsx(Grid3X3, { className: "size-4 text-muted-foreground" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: totalWidgets }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Across ", plugins.filter((p) => (p.widgets?.length || 0) > 0).length, " extensions"] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Total Components" }), _jsx(Code2, { className: "size-4 text-muted-foreground" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: totalComponents }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Across ", plugins.filter((p) => (p.components?.length || 0) > 0).length, " extensions"] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Categories" }), _jsx(LayoutDashboard, { className: "size-4 text-muted-foreground" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: categories.length - 1 }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Different extension types" })] })] })] }), _jsxs("div", { className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { className: "flex flex-1 items-center space-x-2", children: [_jsx(Input, { placeholder: "Search extensions...", className: "max-w-sm", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), startAdornment: _jsx(Search, { className: "size-4 text-muted-foreground" }) }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", className: "ml-auto", children: [_jsx(Filter, { className: "mr-2 size-4" }), "Filter", _jsx(ChevronDown, { className: "ml-2 size-4" })] }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-[200px]", children: [_jsx(DropdownMenuLabel, { children: "Filter by Category" }), _jsx(DropdownMenuSeparator, {}), categories.map((category) => (_jsxs(DropdownMenuItem, { onClick: () => setCategoryFilter(category), className: "flex items-center justify-between", children: [_jsx("span", { className: "capitalize", children: category === 'all' ? 'All Categories' : category }), categoryFilter === category && _jsx(Check, { className: "size-4" })] }, category))), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuLabel, { children: "Filter by Status" }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onClick: () => setStatusFilter('all'), className: "flex items-center justify-between", children: ["All Statuses", statusFilter === 'all' && _jsx(Check, { className: "size-4" })] }), _jsxs(DropdownMenuItem, { onClick: () => setStatusFilter('active'), className: "flex items-center justify-between", children: ["Active", statusFilter === 'active' && _jsx(Check, { className: "size-4" })] }), _jsxs(DropdownMenuItem, { onClick: () => setStatusFilter('inactive'), className: "flex items-center justify-between", children: ["Inactive", statusFilter === 'inactive' && _jsx(Check, { className: "size-4" })] }), _jsxs(DropdownMenuItem, { onClick: () => setStatusFilter('beta'), className: "flex items-center justify-between", children: ["Beta", statusFilter === 'beta' && _jsx(Check, { className: "size-4" })] })] })] })] }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(Button, { variant: view === 'grid' ? 'default' : 'outline', size: "icon", onClick: () => setView('grid'), className: "size-8", children: _jsx(Grid3X3, { className: "size-4" }) }), _jsx(Button, { variant: view === 'list' ? 'default' : 'outline', size: "icon", onClick: () => setView('list'), className: "size-8", children: _jsx(List, { className: "size-4" }) })] })] }), (categoryFilter !== 'all' || statusFilter !== 'all' || searchTerm) && (_jsxs("div", { className: "flex flex-wrap gap-2", children: [categoryFilter !== 'all' && (_jsxs(Badge, { variant: "secondary", className: "flex items-center gap-1", children: ["Category: ", _jsx("span", { className: "capitalize", children: categoryFilter }), _jsx(Button, { variant: "ghost", size: "icon", className: "ml-1 size-4 p-0", onClick: () => setCategoryFilter('all'), children: _jsx(X, { className: "size-3" }) })] })), statusFilter !== 'all' && (_jsxs(Badge, { variant: "secondary", className: "flex items-center gap-1", children: ["Status: ", _jsx("span", { className: "capitalize", children: statusFilter }), _jsx(Button, { variant: "ghost", size: "icon", className: "ml-1 size-4 p-0", onClick: () => setStatusFilter('all'), children: _jsx(X, { className: "size-3" }) })] })), searchTerm && (_jsxs(Badge, { variant: "secondary", className: "flex items-center gap-1", children: ["Search: ", searchTerm, _jsx(Button, { variant: "ghost", size: "icon", className: "ml-1 size-4 p-0", onClick: () => setSearchTerm(''), children: _jsx(X, { className: "size-3" }) })] })), _jsx(Button, { variant: "ghost", size: "sm", className: "h-6 text-xs", onClick: () => {
60
+ return (_jsx(PageBlock, { children: _jsxs("div", { className: "flex flex-col gap-6", children: [_jsx("div", { className: "flex flex-col gap-2", children: _jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { children: [_jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Extensions Dashboard" }), _jsx("p", { className: "mt-1 text-muted-foreground", children: "Manage and monitor your installed plugins" })] }) }) }), _jsxs("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Total Extensions" }), _jsx(Puzzle, { className: "size-4 text-muted-foreground" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: totalPlugins }), _jsxs("p", { className: "text-xs text-muted-foreground", children: [activePlugins, " active, ", inactivePlugins, " inactive"] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Total Widgets" }), _jsx(Grid3X3, { className: "size-4 text-muted-foreground" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: totalWidgets }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Across ", plugins.filter((p) => (p.widgets?.length || 0) > 0).length, " extensions"] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Total Components" }), _jsx(Code2, { className: "size-4 text-muted-foreground" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: totalComponents }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Across ", plugins.filter((p) => (p.components?.length || 0) > 0).length, " extensions"] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [_jsx(CardTitle, { className: "text-sm font-medium", children: "Categories" }), _jsx(LayoutDashboard, { className: "size-4 text-muted-foreground" })] }), _jsxs(CardContent, { children: [_jsx("div", { className: "text-2xl font-bold", children: categories.length - 1 }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Different extension types" })] })] })] }), _jsxs("div", { className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { className: "flex flex-1 items-center space-x-2", children: [_jsx(Input, { placeholder: "Search extensions...", className: "max-w-sm", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), startAdornment: _jsx(Search, { className: "size-4 text-muted-foreground" }) }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", className: "ml-auto", children: [_jsx(Filter, { className: "mr-2 size-4" }), "Filter", _jsx(ChevronDown, { className: "ml-2 size-4" })] }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-[200px]", children: [_jsx(DropdownMenuLabel, { children: "Filter by Category" }), _jsx(DropdownMenuSeparator, {}), categories.map((category) => (_jsxs(DropdownMenuItem, { onClick: () => setCategoryFilter(category), className: "flex items-center justify-between", children: [_jsx("span", { className: "capitalize", children: category === 'all' ? 'All Categories' : category }), categoryFilter === category && _jsx(Check, { className: "size-4" })] }, category))), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuLabel, { children: "Filter by Status" }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onClick: () => setStatusFilter('all'), className: "flex items-center justify-between", children: ["All Statuses", statusFilter === 'all' && _jsx(Check, { className: "size-4" })] }), _jsxs(DropdownMenuItem, { onClick: () => setStatusFilter('active'), className: "flex items-center justify-between", children: ["Active", statusFilter === 'active' && _jsx(Check, { className: "size-4" })] }), _jsxs(DropdownMenuItem, { onClick: () => setStatusFilter('inactive'), className: "flex items-center justify-between", children: ["Inactive", statusFilter === 'inactive' && _jsx(Check, { className: "size-4" })] })] })] })] }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(Button, { variant: view === 'grid' ? 'default' : 'outline', size: "icon", onClick: () => setView('grid'), className: "size-8", children: _jsx(Grid3X3, { className: "size-4" }) }), _jsx(Button, { variant: view === 'list' ? 'default' : 'outline', size: "icon", onClick: () => setView('list'), className: "size-8", children: _jsx(List, { className: "size-4" }) })] })] }), (categoryFilter !== 'all' || statusFilter !== 'all' || searchTerm) && (_jsxs("div", { className: "flex flex-wrap gap-2", children: [categoryFilter !== 'all' && (_jsxs(Badge, { variant: "secondary", className: "flex items-center gap-1", children: ["Category: ", _jsx("span", { className: "capitalize", children: categoryFilter }), _jsx(Button, { variant: "ghost", size: "icon", className: "ml-1 size-4 p-0", onClick: () => setCategoryFilter('all'), children: _jsx(X, { className: "size-3" }) })] })), statusFilter !== 'all' && (_jsxs(Badge, { variant: "secondary", className: "flex items-center gap-1", children: ["Status: ", _jsx("span", { className: "capitalize", children: statusFilter }), _jsx(Button, { variant: "ghost", size: "icon", className: "ml-1 size-4 p-0", onClick: () => setStatusFilter('all'), children: _jsx(X, { className: "size-3" }) })] })), searchTerm && (_jsxs(Badge, { variant: "secondary", className: "flex items-center gap-1", children: ["Search: ", searchTerm, _jsx(Button, { variant: "ghost", size: "icon", className: "ml-1 size-4 p-0", onClick: () => setSearchTerm(''), children: _jsx(X, { className: "size-3" }) })] })), _jsx(Button, { variant: "ghost", size: "sm", className: "h-6 text-xs", onClick: () => {
62
61
  setCategoryFilter('all');
63
62
  setStatusFilter('all');
64
63
  setSearchTerm('');
@@ -66,9 +65,9 @@ export const Extensions = () => {
66
65
  setCategoryFilter('all');
67
66
  setStatusFilter('all');
68
67
  setSearchTerm('');
69
- }, children: "Reset filters" })] })) : view === 'grid' ? (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filteredPlugins.map((plugin) => (_jsxs(Card, { className: "overflow-hidden", children: [_jsxs(CardHeader, { className: "pb-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "rounded-md bg-primary/10 p-2", children: getCategoryIcon(plugin.category) }), _jsx(CardTitle, { className: "text-lg", children: plugin.name })] }), getStatusBadge(plugin.status)] }), _jsx(CardDescription, { className: "mt-2", children: plugin.description })] }), _jsxs(CardContent, { className: "pb-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-2 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground", children: "Version:" }), _jsx("span", { children: plugin.version })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground", children: "Author:" }), _jsx("span", { children: plugin.author })] })] }), _jsx(Separator, { className: "my-3" }), _jsxs("div", { className: "grid grid-cols-4 gap-2 text-center text-sm", children: [_jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.tables?.length }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Tables" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.tabs?.length }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Tabs" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.components?.length }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Components" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.widgets?.length }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Widgets" })] })] })] }), _jsxs(CardFooter, { className: "flex justify-between pt-2", children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "size-8", children: _jsx(Info, { className: "size-4" }) }) }), _jsx(TooltipContent, { children: "View details" })] }) }), _jsx("div", { className: "flex gap-2", children: _jsxs(Switch, { checked: plugin.status === 'active', onCheckedChange: (checked) => {
68
+ }, children: "Reset filters" })] })) : view === 'grid' ? (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filteredPlugins.map((plugin) => (_jsxs(Card, { className: "overflow-hidden", children: [_jsxs(CardHeader, { className: "pb-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "rounded-md bg-primary/10 p-2", children: getCategoryIcon(plugin.category) }), _jsx(CardTitle, { className: "text-lg", children: plugin.name })] }), getStatusBadge(plugin.status)] }), _jsx(CardDescription, { className: "mt-2", children: plugin.description })] }), _jsxs(CardContent, { className: "pb-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-2 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground", children: "Version:" }), _jsx("span", { children: plugin.version })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground", children: "Author:" }), _jsx("span", { children: plugin.author })] })] }), _jsx(Separator, { className: "my-3" }), _jsxs("div", { className: "grid grid-cols-4 gap-2 text-center text-sm", children: [_jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.tables?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Tables" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.tabs?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Tabs" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.components?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Components" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.widgets?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Widgets" })] })] })] }), _jsxs(CardFooter, { className: "flex justify-between pt-2", children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "size-8", children: _jsx(Info, { className: "size-4" }) }) }), _jsx(TooltipContent, { children: "View details" })] }) }), _jsx("div", { className: "flex gap-2", children: _jsx(Switch, { checked: plugin.status === 'active', onCheckedChange: (checked) => {
70
69
  changePluginStatus(plugin.name, checked ? 'active' : 'inactive');
71
- }, className: "h-6 w-11", children: [_jsx("span", { className: "sr-only", children: "Toggle plugin status" }), _jsx("span", { className: "absolute top-0 left-0 size-6 rounded-full bg-primary transition-transform duration-200 ease-in-out" })] }) })] })] }, plugin.name))) })) : (_jsxs("div", { className: "rounded-md border", children: [_jsxs("div", { className: "grid grid-cols-12 gap-4 p-4 font-medium", children: [_jsx("div", { className: "col-span-4", children: "Name" }), _jsx("div", { className: "col-span-3", children: "Author" }), _jsx("div", { className: "col-span-1 text-center", children: "Version" }), _jsx("div", { className: "col-span-1 text-center", children: "Status" }), _jsx("div", { className: "col-span-3 text-right", children: "Actions" })] }), _jsx(Separator, {}), filteredPlugins.map((plugin, index) => (_jsxs("div", { children: [_jsxs("div", { className: "grid grid-cols-12 items-center gap-4 p-4", children: [_jsx("div", { className: "col-span-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "rounded-md bg-primary/10 p-2", children: getCategoryIcon(plugin.category) }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.name }), _jsx("div", { className: "text-xs text-muted-foreground", children: plugin.description })] })] }) }), _jsx("div", { className: "col-span-3", children: plugin.author }), _jsx("div", { className: "col-span-1 text-center", children: plugin.version }), _jsx("div", { className: "col-span-1 text-center", children: getStatusBadge(plugin.status) }), _jsxs("div", { className: "col-span-3 flex justify-end gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(Settings, { className: "mr-2 size-3" }), "Configure"] }), _jsxs(Switch, { checked: plugin.status === 'active', onCheckedChange: (checked) => {
70
+ } }) })] })] }, plugin.name))) })) : (_jsxs("div", { className: "rounded-md border", children: [_jsxs("div", { className: "grid grid-cols-12 gap-4 p-4 font-medium", children: [_jsx("div", { className: "col-span-4", children: "Name" }), _jsx("div", { className: "col-span-3", children: "Author" }), _jsx("div", { className: "col-span-1 text-center", children: "Version" }), _jsx("div", { className: "col-span-1 text-center", children: "Status" }), _jsx("div", { className: "col-span-3 text-right", children: "Actions" })] }), _jsx(Separator, {}), filteredPlugins.map((plugin, index) => (_jsxs("div", { children: [_jsxs("div", { className: "grid grid-cols-12 items-center gap-4 p-4", children: [_jsx("div", { className: "col-span-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "rounded-md bg-primary/10 p-2", children: getCategoryIcon(plugin.category) }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.name }), _jsx("div", { className: "text-xs text-muted-foreground", children: plugin.description })] })] }) }), _jsx("div", { className: "col-span-3", children: plugin.author }), _jsx("div", { className: "col-span-1 text-center", children: plugin.version }), _jsx("div", { className: "col-span-1 text-center", children: getStatusBadge(plugin.status) }), _jsxs("div", { className: "col-span-3 flex justify-end gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(Settings, { className: "mr-2 size-3" }), "Configure"] }), _jsx(Switch, { checked: plugin.status === 'active', onCheckedChange: (checked) => {
72
71
  changePluginStatus(plugin.name, checked ? 'active' : 'inactive');
73
- }, className: "h-6 w-11", children: [_jsx("span", { className: "sr-only", children: "Toggle plugin status" }), _jsx("span", { className: "absolute top-0 left-0 size-6 rounded-full bg-primary transition-transform duration-200 ease-in-out" })] })] })] }), index < filteredPlugins.length - 1 && _jsx(Separator, {})] }, plugin.name)))] }))] }) }));
72
+ } })] })] }), index < filteredPlugins.length - 1 && _jsx(Separator, {})] }, plugin.name)))] }))] }) }));
74
73
  };
@@ -14,15 +14,15 @@ export const FacetsDetailPage = () => {
14
14
  const [remove] = useMutation(DeleteFacetMutation);
15
15
  const { stringValidator, translationsValidator } = useValidators();
16
16
  const onSubmitHandler = useCallback((data) => {
17
- if (!data.code?.validatedValue) {
17
+ if (!data.code) {
18
18
  throw new Error('Code is required.');
19
19
  }
20
20
  const inputData = {
21
- code: data.code.validatedValue,
22
- isPrivate: data.isPrivate?.value || data.isPrivate?.initialValue,
23
- translations: data.translations?.validatedValue,
24
- values: data.values?.validatedValue,
25
- ...(data.customFields?.validatedValue ? { customFields: data.customFields?.validatedValue } : {}),
21
+ code: data.code,
22
+ isPrivate: data.isPrivate,
23
+ translations: data.translations,
24
+ values: data.values,
25
+ ...(data.customFields ? { customFields: data.customFields } : {}),
26
26
  };
27
27
  if (id) {
28
28
  return update({ input: { id, ...inputData } });