@deenruv/admin-dashboard 1.0.0
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/LICENSE +23 -0
- package/README.md +30 -0
- package/dist/@types/resources.js +51 -0
- package/dist/DeenruvAdminPanel.js +118 -0
- package/dist/DeenruvDeveloperIndicator.js +57 -0
- package/dist/components/Aexol.js +4 -0
- package/dist/components/BrandLogo.js +22 -0
- package/dist/components/CanLeaveRouteDialog.js +8 -0
- package/dist/components/DataTable.js +13 -0
- package/dist/components/DeleteDialog.js +6 -0
- package/dist/components/DuplicateEntry.js +46 -0
- package/dist/components/GlobalSearch.js +134 -0
- package/dist/components/History/AddEntryForm.js +29 -0
- package/dist/components/History/DeleteEntryDialog.js +25 -0
- package/dist/components/History/EditEntryDialog.js +32 -0
- package/dist/components/History/History.js +13 -0
- package/dist/components/History/ModifyHistoryInfo.js +6 -0
- package/dist/components/History/Timeline.js +53 -0
- package/dist/components/History/index.js +5 -0
- package/dist/components/Menu/ActiveAdmins.js +24 -0
- package/dist/components/Menu/ChannelSwitcher.js +20 -0
- package/dist/components/Menu/LanguagesDropdown.js +26 -0
- package/dist/components/Menu/Navigation.js +270 -0
- package/dist/components/Menu/NavigationFooter.js +12 -0
- package/dist/components/Menu/Notifications.js +90 -0
- package/dist/components/Menu/index.js +67 -0
- package/dist/components/index.js +6 -0
- package/dist/graphql/base.js +95 -0
- package/dist/graphql/collections.js +94 -0
- package/dist/graphql/draft_order.js +307 -0
- package/dist/graphql/orders.js +157 -0
- package/dist/graphql/products.js +230 -0
- package/dist/graphql/scalars.js +22 -0
- package/dist/i18.js +13 -0
- package/dist/index.css +161 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +1 -0
- package/dist/locales/en/admins.json +57 -0
- package/dist/locales/en/assets.json +69 -0
- package/dist/locales/en/channels.json +66 -0
- package/dist/locales/en/collections.json +145 -0
- package/dist/locales/en/common.json +1127 -0
- package/dist/locales/en/countries.json +50 -0
- package/dist/locales/en/customerGroups.json +6 -0
- package/dist/locales/en/customers.json +109 -0
- package/dist/locales/en/dashboard.json +34 -0
- package/dist/locales/en/facets.json +78 -0
- package/dist/locales/en/globalSettings.json +15 -0
- package/dist/locales/en/index.js +52 -0
- package/dist/locales/en/orders.json +932 -0
- package/dist/locales/en/paymentMethods.json +59 -0
- package/dist/locales/en/permissions.json +94 -0
- package/dist/locales/en/products.json +194 -0
- package/dist/locales/en/promotions.json +65 -0
- package/dist/locales/en/roles.json +59 -0
- package/dist/locales/en/sellers.json +41 -0
- package/dist/locales/en/shippingMethods.json +84 -0
- package/dist/locales/en/stockLocations.json +40 -0
- package/dist/locales/en/system.json +41 -0
- package/dist/locales/en/table.json +201 -0
- package/dist/locales/en/taxCategories.json +47 -0
- package/dist/locales/en/taxRates.json +56 -0
- package/dist/locales/en/zones.json +47 -0
- package/dist/locales/index.js +2 -0
- package/dist/locales/pl/admins.json +57 -0
- package/dist/locales/pl/assets.json +69 -0
- package/dist/locales/pl/channels.json +66 -0
- package/dist/locales/pl/collections.json +145 -0
- package/dist/locales/pl/common.json +1128 -0
- package/dist/locales/pl/countries.json +50 -0
- package/dist/locales/pl/customerGroups.json +6 -0
- package/dist/locales/pl/customers.json +109 -0
- package/dist/locales/pl/dashboard.json +34 -0
- package/dist/locales/pl/facets.json +78 -0
- package/dist/locales/pl/globalSettings.json +15 -0
- package/dist/locales/pl/index.js +52 -0
- package/dist/locales/pl/orders.json +932 -0
- package/dist/locales/pl/paymentMethods.json +59 -0
- package/dist/locales/pl/permissions.json +94 -0
- package/dist/locales/pl/products.json +194 -0
- package/dist/locales/pl/promotions.json +65 -0
- package/dist/locales/pl/roles.json +59 -0
- package/dist/locales/pl/sellers.json +41 -0
- package/dist/locales/pl/shippingMethods.json +84 -0
- package/dist/locales/pl/stockLocations.json +40 -0
- package/dist/locales/pl/system.json +41 -0
- package/dist/locales/pl/table.json +201 -0
- package/dist/locales/pl/taxCategories.json +47 -0
- package/dist/locales/pl/taxRates.json +56 -0
- package/dist/locales/pl/zones.json +47 -0
- package/dist/notifications/OrderStatusNotification.js +47 -0
- package/dist/notifications/SystemStatusNotification.js +19 -0
- package/dist/pages/Custom404.js +5 -0
- package/dist/pages/LoginScreen.js +37 -0
- package/dist/pages/Root.js +252 -0
- package/dist/pages/admins/Detail.js +72 -0
- package/dist/pages/admins/List.js +56 -0
- package/dist/pages/admins/_components/AdminDetailView.js +34 -0
- package/dist/pages/admins/_components/RolesCard.js +31 -0
- package/dist/pages/admins/index.js +2 -0
- package/dist/pages/assets/List.js +82 -0
- package/dist/pages/assets/_components/Asset.js +114 -0
- package/dist/pages/assets/_components/AssetListView.js +29 -0
- package/dist/pages/assets/_components/EditAssetDialog.js +85 -0
- package/dist/pages/assets/_components/UploadAssetDialog.js +133 -0
- package/dist/pages/assets/_components/UploadProgress.js +20 -0
- package/dist/pages/assets/index.js +1 -0
- package/dist/pages/channels/Detail.js +149 -0
- package/dist/pages/channels/List.js +46 -0
- package/dist/pages/channels/_components/ChannelDetailView.js +51 -0
- package/dist/pages/channels/_components/DefaultsCard.js +25 -0
- package/dist/pages/channels/index.js +2 -0
- package/dist/pages/collections/Detail.js +61 -0
- package/dist/pages/collections/List.js +135 -0
- package/dist/pages/collections/_components/CollectionDetailView.js +52 -0
- package/dist/pages/collections/_components/CollectionProductVariantsDrawer.js +28 -0
- package/dist/pages/collections/_components/CombinationMode.js +6 -0
- package/dist/pages/collections/_components/ContentsCard.js +43 -0
- package/dist/pages/collections/_components/ContentsTable.js +102 -0
- package/dist/pages/collections/_components/DeleteCollectionsFromChannel.js +36 -0
- package/dist/pages/collections/_components/FacetsSelector.js +30 -0
- package/dist/pages/collections/_components/FiltersCard.js +101 -0
- package/dist/pages/collections/_components/MoveCollectionsToCollections.js +107 -0
- package/dist/pages/collections/_components/MoveEntityToChannels.js +115 -0
- package/dist/pages/collections/_components/PageHeader.js +11 -0
- package/dist/pages/collections/_components/SelectedCollectionsModal.js +22 -0
- package/dist/pages/collections/_components/VariantsSelector.js +43 -0
- package/dist/pages/collections/consts.js +7 -0
- package/dist/pages/collections/index.js +2 -0
- package/dist/pages/countries/Detail.js +57 -0
- package/dist/pages/countries/List.js +47 -0
- package/dist/pages/countries/_components/CountryDetailView.js +28 -0
- package/dist/pages/countries/index.js +2 -0
- package/dist/pages/customer-groups/Detail.js +76 -0
- package/dist/pages/customer-groups/List.js +41 -0
- package/dist/pages/customer-groups/_components/CustomerGroupsDetailView.js +21 -0
- package/dist/pages/customer-groups/index.js +2 -0
- package/dist/pages/customers/Detail.js +75 -0
- package/dist/pages/customers/List.js +60 -0
- package/dist/pages/customers/_components/Address.js +59 -0
- package/dist/pages/customers/_components/AddressDialog.js +56 -0
- package/dist/pages/customers/_components/AddressForm.js +77 -0
- package/dist/pages/customers/_components/AddressesCard.js +9 -0
- package/dist/pages/customers/_components/CustomerDetailSidebar.js +9 -0
- package/dist/pages/customers/_components/CustomerDetailView.js +41 -0
- package/dist/pages/customers/_components/CustomerGroupsCard.js +46 -0
- package/dist/pages/customers/_components/HistoryTab.js +65 -0
- package/dist/pages/customers/_components/OrdersTab.js +46 -0
- package/dist/pages/customers/_components/PersonalDataCard.js +6 -0
- package/dist/pages/customers/_components/VerifiedCard.js +6 -0
- package/dist/pages/customers/index.js +2 -0
- package/dist/pages/dashboard/Dashboard.js +10 -0
- package/dist/pages/dashboard/index.js +1 -0
- package/dist/pages/extensions/Extensions.js +74 -0
- package/dist/pages/extensions/index.js +1 -0
- package/dist/pages/facets/Detail.js +56 -0
- package/dist/pages/facets/List.js +48 -0
- package/dist/pages/facets/_components/AddFacetValueDialog.js +105 -0
- package/dist/pages/facets/_components/ColorSample.js +18 -0
- package/dist/pages/facets/_components/FacetDetailView.js +98 -0
- package/dist/pages/facets/index.js +2 -0
- package/dist/pages/global-settings/GlobalSettingsComponent.js +30 -0
- package/dist/pages/global-settings/index.js +71 -0
- package/dist/pages/index.js +25 -0
- package/dist/pages/orders/Detail.js +21 -0
- package/dist/pages/orders/List.js +132 -0
- package/dist/pages/orders/_components/AddPaymentDialog.js +50 -0
- package/dist/pages/orders/_components/AddressCard.js +260 -0
- package/dist/pages/orders/_components/CancelAndRefundDialog.js +29 -0
- package/dist/pages/orders/_components/ChangesRegister.js +68 -0
- package/dist/pages/orders/_components/ChangesRegisterTable.js +18 -0
- package/dist/pages/orders/_components/CouponCodesCard.js +85 -0
- package/dist/pages/orders/_components/CustomComponent.js +21 -0
- package/dist/pages/orders/_components/CustomerSelectCard.js +117 -0
- package/dist/pages/orders/_components/EditNoteButton.js +10 -0
- package/dist/pages/orders/_components/FulfillmentModal.js +85 -0
- package/dist/pages/orders/_components/LineItem.js +7 -0
- package/dist/pages/orders/_components/ManualOrderChangeModal.js +47 -0
- package/dist/pages/orders/_components/ModifyAcceptModal.js +22 -0
- package/dist/pages/orders/_components/ModifyingCard.js +77 -0
- package/dist/pages/orders/_components/OrderHistory.js +59 -0
- package/dist/pages/orders/_components/OrderLineActionModal/ActionQuantityPrice.js +58 -0
- package/dist/pages/orders/_components/OrderLineActionModal/index.js +7 -0
- package/dist/pages/orders/_components/OrderLineActionModal/types.js +1 -0
- package/dist/pages/orders/_components/OrderLineCustomFields.js +26 -0
- package/dist/pages/orders/_components/OrderSummary.js +10 -0
- package/dist/pages/orders/_components/PaymentMetadata.js +6 -0
- package/dist/pages/orders/_components/Payments.js +113 -0
- package/dist/pages/orders/_components/PossibleOrderStates.js +54 -0
- package/dist/pages/orders/_components/PriceChangedInfo.js +16 -0
- package/dist/pages/orders/_components/ProductsCard.js +308 -0
- package/dist/pages/orders/_components/ProductsTable.js +29 -0
- package/dist/pages/orders/_components/PromotionsList.js +73 -0
- package/dist/pages/orders/_components/RealizationCard.js +98 -0
- package/dist/pages/orders/_components/RefundCard.js +11 -0
- package/dist/pages/orders/_components/RefundPaymentCard.js +13 -0
- package/dist/pages/orders/_components/ShippingMethod.js +112 -0
- package/dist/pages/orders/_components/SpecialLineItem.js +7 -0
- package/dist/pages/orders/_components/SurchargeCard.js +99 -0
- package/dist/pages/orders/_components/SurchargeTable.js +8 -0
- package/dist/pages/orders/_components/TaxSummary.js +11 -0
- package/dist/pages/orders/_components/ToRealizationForm.js +64 -0
- package/dist/pages/orders/_components/TopActions.js +219 -0
- package/dist/pages/orders/_components/index.js +25 -0
- package/dist/pages/orders/index.js +2 -0
- package/dist/pages/payment-methods/Detail.js +67 -0
- package/dist/pages/payment-methods/List.js +41 -0
- package/dist/pages/payment-methods/_components/OptionsCard.js +60 -0
- package/dist/pages/payment-methods/_components/PaymentMethodDetailView.js +53 -0
- package/dist/pages/payment-methods/index.js +2 -0
- package/dist/pages/product-variants/Detail.js +4 -0
- package/dist/pages/product-variants/List.js +76 -0
- package/dist/pages/product-variants/index.js +2 -0
- package/dist/pages/products/Detail.js +75 -0
- package/dist/pages/products/List.js +79 -0
- package/dist/pages/products/_components/AddOptionGroupDialog.js +65 -0
- package/dist/pages/products/_components/AssetsCard.js +35 -0
- package/dist/pages/products/_components/BasicFieldsCard.js +6 -0
- package/dist/pages/products/_components/ChannelsCard.js +6 -0
- package/dist/pages/products/_components/CollectionsCard.js +6 -0
- package/dist/pages/products/_components/Container.js +4 -0
- package/dist/pages/products/_components/DiscountRatingCard.js +6 -0
- package/dist/pages/products/_components/FacetValuesCard.js +6 -0
- package/dist/pages/products/_components/ImagesCard.js +6 -0
- package/dist/pages/products/_components/OptionGroup.js +93 -0
- package/dist/pages/products/_components/OptionValueCard.js +59 -0
- package/dist/pages/products/_components/OptionsCard.js +38 -0
- package/dist/pages/products/_components/OptionsTab.js +40 -0
- package/dist/pages/products/_components/PriceCard.js +27 -0
- package/dist/pages/products/_components/ProductDetailSidebar.js +30 -0
- package/dist/pages/products/_components/ProductDetailView.js +54 -0
- package/dist/pages/products/_components/SettingsCard.js +6 -0
- package/dist/pages/products/_components/StockCard.js +40 -0
- package/dist/pages/products/_components/Variant.js +149 -0
- package/dist/pages/products/_components/VariantsTab.js +46 -0
- package/dist/pages/products/index.js +2 -0
- package/dist/pages/promotions/Detail.js +80 -0
- package/dist/pages/promotions/List.js +38 -0
- package/dist/pages/promotions/_components/ActionsCard.js +67 -0
- package/dist/pages/promotions/_components/BasicFieldsCard.js +6 -0
- package/dist/pages/promotions/_components/ConditionsCard.js +70 -0
- package/dist/pages/promotions/_components/CustomerGroupsSelector.js +25 -0
- package/dist/pages/promotions/_components/EnabledCard.js +6 -0
- package/dist/pages/promotions/_components/OptionsCard.js +6 -0
- package/dist/pages/promotions/_components/PromotionDetailSidebar.js +15 -0
- package/dist/pages/promotions/_components/PromotionDetailView.js +66 -0
- package/dist/pages/promotions/_components/PromotionFieldRender.js +4 -0
- package/dist/pages/promotions/index.js +2 -0
- package/dist/pages/roles/Detail.js +72 -0
- package/dist/pages/roles/List.js +70 -0
- package/dist/pages/roles/_components/PermissionsCard.js +7 -0
- package/dist/pages/roles/_components/PermissionsTable.js +42 -0
- package/dist/pages/roles/_components/RoleDetailView.js +49 -0
- package/dist/pages/roles/index.js +2 -0
- package/dist/pages/sellers/Detail.js +48 -0
- package/dist/pages/sellers/List.js +37 -0
- package/dist/pages/sellers/_components/SellerDetailView.js +20 -0
- package/dist/pages/sellers/index.js +2 -0
- package/dist/pages/shipping-methods/Detail.js +105 -0
- package/dist/pages/shipping-methods/List.js +40 -0
- package/dist/pages/shipping-methods/_components/CalculatorCard.js +79 -0
- package/dist/pages/shipping-methods/_components/CheckerCard.js +76 -0
- package/dist/pages/shipping-methods/_components/Lines.js +20 -0
- package/dist/pages/shipping-methods/_components/ShippingMethodDetailView.js +67 -0
- package/dist/pages/shipping-methods/_components/TestCard.js +62 -0
- package/dist/pages/shipping-methods/index.js +2 -0
- package/dist/pages/status/Status.js +6 -0
- package/dist/pages/status/_components/FilterToolbar.js +29 -0
- package/dist/pages/status/_components/Health.js +21 -0
- package/dist/pages/status/_components/JobResultPopover.js +8 -0
- package/dist/pages/status/_components/Jobs.js +199 -0
- package/dist/pages/status/_components/JsonExplorer.js +44 -0
- package/dist/pages/status/_components/JsonPopup.js +8 -0
- package/dist/pages/status/index.js +1 -0
- package/dist/pages/stock-locations/Detail.js +77 -0
- package/dist/pages/stock-locations/List.js +38 -0
- package/dist/pages/stock-locations/_components/StockLocationDetailView.js +22 -0
- package/dist/pages/stock-locations/index.js +2 -0
- package/dist/pages/tax-categories/Detail.js +85 -0
- package/dist/pages/tax-categories/List.js +46 -0
- package/dist/pages/tax-categories/_components/TaxCategoryDetailView.js +24 -0
- package/dist/pages/tax-categories/index.js +2 -0
- package/dist/pages/tax-rates/Detail.js +62 -0
- package/dist/pages/tax-rates/List.js +64 -0
- package/dist/pages/tax-rates/_components/TaxRateDetailView.js +64 -0
- package/dist/pages/tax-rates/index.js +2 -0
- package/dist/pages/zones/Detail.js +86 -0
- package/dist/pages/zones/List.js +52 -0
- package/dist/pages/zones/_components/ZoneDetailView.js +49 -0
- package/dist/pages/zones/index.js +2 -0
- package/dist/version.js +1 -0
- package/package.json +122 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useTranslation, useOrder, cn, Button, DialogFooter, Input } from '@deenruv/react-ui-devkit';
|
|
4
|
+
import { useMemo, useState } from 'react';
|
|
5
|
+
import { ArrowDown, ArrowUp, Package, MinusCircle, PlusCircle } from 'lucide-react';
|
|
6
|
+
export const ActionQuantityPrice = ({ line, onOpenChange, onPriceQuantityChangeApprove, }) => {
|
|
7
|
+
const { t } = useTranslation('orders');
|
|
8
|
+
const [quantityChange, setQuantityChange] = useState(line?.quantity);
|
|
9
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
10
|
+
const { order } = useOrder();
|
|
11
|
+
const baseOrderLine = useMemo(() => order?.lines.find((l) => l.id === line?.id), [line, order?.lines]);
|
|
12
|
+
const handleQuantityChange = (e) => {
|
|
13
|
+
if (!e.currentTarget.value)
|
|
14
|
+
setQuantityChange(0);
|
|
15
|
+
const value = Number.parseInt(e.currentTarget.value, 10);
|
|
16
|
+
setQuantityChange(value);
|
|
17
|
+
};
|
|
18
|
+
const incrementQuantity = () => {
|
|
19
|
+
setQuantityChange((prev) => (prev !== undefined ? prev + 1 : 1));
|
|
20
|
+
};
|
|
21
|
+
const decrementQuantity = () => {
|
|
22
|
+
setQuantityChange((prev) => (prev ? prev - 1 : 0));
|
|
23
|
+
};
|
|
24
|
+
const quantityDelta = useMemo(() => (quantityChange ? quantityChange - (baseOrderLine?.quantity ?? 0) : 0), [quantityChange, baseOrderLine?.quantity]);
|
|
25
|
+
const handleApprove = async () => {
|
|
26
|
+
if (!line?.id)
|
|
27
|
+
return;
|
|
28
|
+
setIsLoading(true);
|
|
29
|
+
try {
|
|
30
|
+
await onPriceQuantityChangeApprove({
|
|
31
|
+
lineID: line.id,
|
|
32
|
+
quantityChange: quantityChange,
|
|
33
|
+
});
|
|
34
|
+
onOpenChange(false);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error('Error updating quantity:', error);
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
setIsLoading(false);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const productImage = line?.productVariant?.featuredAsset?.preview || line?.productVariant?.product?.featuredAsset?.preview;
|
|
44
|
+
const formatPrice = (amount) => {
|
|
45
|
+
if (amount === undefined)
|
|
46
|
+
return '—';
|
|
47
|
+
return new Intl.NumberFormat('en-US', {
|
|
48
|
+
style: 'currency',
|
|
49
|
+
currency: line?.productVariant?.currencyCode || 'USD',
|
|
50
|
+
minimumFractionDigits: 2,
|
|
51
|
+
maximumFractionDigits: 2,
|
|
52
|
+
}).format(amount / 100);
|
|
53
|
+
};
|
|
54
|
+
return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "space-y-6 p-2", children: [_jsxs("div", { className: "bg-card flex items-center gap-4 rounded-lg border p-5 shadow-sm transition-all hover:shadow-md", children: [productImage ? (_jsx("div", { className: "bg-background relative overflow-hidden rounded-md border", children: _jsx("img", { alt: line?.productVariant.name || 'Product image', className: "aspect-square size-24 object-cover transition-transform hover:scale-105", src: productImage || '/placeholder.svg' }) })) : (_jsx("div", { className: "bg-muted/50 flex size-24 items-center justify-center rounded-md border", children: _jsx(Package, { className: "text-muted-foreground size-10" }) })), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-lg font-medium", children: line?.productVariant.name }), _jsx("span", { className: "text-muted-foreground text-sm", children: line?.productVariant.sku || 'No SKU available' }), _jsxs("div", { className: "bg-primary/10 text-primary mt-2 inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium", children: [formatPrice(baseOrderLine?.unitPriceWithTax), " / unit"] })] })] }), _jsxs("div", { className: "bg-card rounded-lg border p-4 shadow-sm", children: [_jsxs("div", { className: "space-y-3", children: [_jsx("label", { className: "text-sm font-medium", htmlFor: "quantity-input", children: t('orderLineActionModal.quantityChange') }), _jsxs("div", { className: "flex items-center", children: [_jsx("button", { type: "button", onClick: decrementQuantity, className: "bg-muted/50 text-muted-foreground hover:bg-muted flex size-10 items-center justify-center rounded-l-md border border-r-0 transition-colors", "aria-label": "Decrease quantity", children: _jsx(MinusCircle, { className: "size-4" }) }), _jsx(Input, { id: "quantity-input", min: 1, value: quantityChange, onChange: handleQuantityChange, className: "rounded-none border-x-0 text-center transition-all focus-visible:ring-2", type: "number", placeholder: t('orderLineActionModal.changeQuantity') }), _jsx("button", { type: "button", onClick: incrementQuantity, className: "bg-muted/50 text-muted-foreground hover:bg-muted flex size-10 items-center justify-center rounded-r-md border border-l-0 transition-colors", "aria-label": "Increase quantity", children: _jsx(PlusCircle, { className: "size-4" }) })] })] }), _jsxs("div", { className: "bg-muted/40 mt-4 space-y-3 rounded-md p-5", children: [_jsxs("div", { className: "border-border/50 grid grid-cols-3 gap-2 border-b pb-2", children: [_jsx("span", { className: "text-sm font-medium", children: t('orderLineActionModal.item') }), _jsx("span", { className: "text-center text-sm font-medium", children: t('orderLineActionModal.quantity') }), _jsx("span", { className: "text-right text-sm font-medium", children: t('orderLineActionModal.price') })] }), _jsxs("div", { className: "grid grid-cols-3 gap-2 py-2", children: [_jsx("span", { className: "text-muted-foreground text-sm", children: t('orderLineActionModal.current') }), _jsx("span", { className: "text-center text-sm", children: baseOrderLine?.quantity }), _jsx("span", { className: "text-right text-sm", children: formatPrice(baseOrderLine?.unitPriceWithTax) })] }), _jsxs("div", { className: "bg-muted/60 grid grid-cols-3 gap-2 rounded-md py-2", children: [_jsx("span", { className: "text-muted-foreground pl-2 text-sm", children: t('orderLineActionModal.change') }), _jsxs("div", { className: "flex items-center justify-center", children: [quantityDelta !== 0 && (_jsx(_Fragment, { children: quantityDelta > 0 ? (_jsx(ArrowUp, { className: "mr-1 size-3 text-green-500" })) : (_jsx(ArrowDown, { className: "text-destructive mr-1 size-3" })) })), _jsx("span", { className: cn('text-sm', {
|
|
55
|
+
'text-destructive': quantityDelta < 0,
|
|
56
|
+
'text-green-500': quantityDelta > 0,
|
|
57
|
+
}), children: quantityDelta > 0 ? `+${quantityDelta}` : quantityDelta })] }), _jsx("span", { className: "pr-2 text-right text-sm", children: "-" })] }), _jsx("div", { className: "bg-border my-3 h-px w-full" }), _jsxs("div", { className: "grid grid-cols-3 gap-2 py-2", children: [_jsx("span", { className: "text-sm font-medium", children: t('orderLineActionModal.after') }), _jsx("span", { className: "text-center text-sm font-semibold", children: quantityChange !== undefined && quantityChange > 0 ? quantityChange : line?.quantity }), _jsx("span", { className: "text-right text-sm font-semibold", children: formatPrice(baseOrderLine?.unitPriceWithTax) })] }), _jsxs("div", { className: "border-border bg-primary/5 mt-3 grid grid-cols-3 gap-2 rounded-md border-t p-2", children: [_jsx("span", { className: "text-sm font-medium", children: t('orderLineActionModal.total') }), _jsx("span", { className: "text-center" }), _jsx("span", { className: "text-primary text-right text-sm font-semibold", children: formatPrice((quantityChange || 0) * (baseOrderLine?.unitPriceWithTax || 0)) })] })] })] })] }), _jsxs(DialogFooter, { className: "bg-muted/30 gap-2 border-t p-4", children: [_jsx(Button, { onClick: () => onOpenChange(false), variant: "outline", className: "flex-1 sm:flex-none", disabled: isLoading, children: t('orderLineActionModal.cancel') }), _jsx(Button, { onClick: handleApprove, disabled: isLoading || quantityChange === undefined || quantityChange < 0, className: "bg-primary hover:bg-primary/90 min-w-[100px] flex-1 sm:flex-none", children: isLoading ? (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: "size-4 animate-spin rounded-full border-2 border-current border-t-transparent" }), t('orderLineActionModal.saving')] })) : (t('orderLineActionModal.save')) })] })] }));
|
|
58
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation, Dialog, DialogContent, DialogHeader, DialogTitle } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { ActionQuantityPrice } from './ActionQuantityPrice.js';
|
|
4
|
+
export const OrderLineActionModal = ({ onOpenChange, onPriceQuantityChangeApprove, line, }) => {
|
|
5
|
+
const { t } = useTranslation('orders');
|
|
6
|
+
return (_jsx(Dialog, { open: !!line, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "flex max-w-[90dvw] flex-col rounded-lg border-0 p-0 shadow-lg sm:max-w-[550px] lg:max-w-[650px]", children: [_jsxs(DialogHeader, { className: "bg-muted/30 border-b p-6", children: [_jsx(DialogTitle, { className: "text-xl font-semibold", children: t(`orderLineActionModal.title.!TODO`) }), _jsx("p", { className: "text-muted-foreground text-sm", children: t(`orderLineActionModal.subTitle.!TODO`) })] }), _jsx(ActionQuantityPrice, { onPriceQuantityChangeApprove: onPriceQuantityChangeApprove, onOpenChange: onOpenChange, line: line })] }) }));
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Dialog, DialogContent, DialogTitle, ScrollArea, useOrder, useServer, EntityCustomFields, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
export const OrderLineCustomFields = ({ line, order, mode }) => {
|
|
5
|
+
const { setModifiedOrder } = useOrder(({ setModifiedOrder }) => ({ setModifiedOrder }));
|
|
6
|
+
const orderLineCustomFields = useServer((p) => p.serverConfig?.entityCustomFields?.find((el) => el.entityName === 'OrderLine')?.customFields || []);
|
|
7
|
+
const { t } = useTranslation('common');
|
|
8
|
+
const [open, setOpen] = useState(false);
|
|
9
|
+
if (!order)
|
|
10
|
+
return null;
|
|
11
|
+
return (_jsxs(_Fragment, { children: [!!orderLineCustomFields?.length && (_jsx(Button, { variant: "outline", className: "h-8 self-end p-0 px-4", onClick: () => setOpen(true), children: t('show') })), _jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsxs(DialogContent, { className: "min-w-[60vw]", children: [_jsx(DialogTitle, { children: line.productVariant.name }), _jsx(ScrollArea, { className: "max-h-[90vh]", children: _jsx(EntityCustomFields, { additionalData: { product: line.productVariant.product, variant: line.productVariant }, entityName: "orderLine", id: line.id, hideButton: mode === 'create' || mode === 'view', disabled: mode === 'view', fetch: async (runtimeSelector) => {
|
|
12
|
+
const orderLine = order.lines.find((l) => l.id === line.id);
|
|
13
|
+
return orderLine && 'customFields' in orderLine
|
|
14
|
+
? { customFields: orderLine.customFields }
|
|
15
|
+
: { customFields: {} };
|
|
16
|
+
}, mutation: async (customFields) => {
|
|
17
|
+
console.log(mode, customFields);
|
|
18
|
+
if (mode === 'update') {
|
|
19
|
+
setModifiedOrder({
|
|
20
|
+
...order,
|
|
21
|
+
lines: order.lines.map((l) => (l.id === line.id ? { ...l, customFields } : l)),
|
|
22
|
+
});
|
|
23
|
+
setOpen(false);
|
|
24
|
+
}
|
|
25
|
+
} }) })] }) })] }));
|
|
26
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation, useOrder, Label, Renderer } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { format } from 'date-fns';
|
|
4
|
+
export const OrderSummary = () => {
|
|
5
|
+
const { order } = useOrder();
|
|
6
|
+
const { t } = useTranslation('orders');
|
|
7
|
+
if (!order)
|
|
8
|
+
return null;
|
|
9
|
+
return (_jsxs("div", { className: "flex flex-row flex-wrap gap-x-4 gap-y-2", children: [_jsx(Label, { className: "text-muted-foreground", children: t('create.baseInfoCode', { value: order.code }) }), _jsx(Label, { className: "text-muted-foreground", children: "|" }), _jsx(Label, { className: "text-muted-foreground", children: t('create.baseInfoCreated', { value: format(new Date(order.createdAt), 'dd.MM.yyyy hh:mm') }) }), _jsx(Label, { className: "text-muted-foreground", children: "|" }), _jsx(Label, { className: "text-muted-foreground", children: t('create.baseInfoUpdated', { value: format(new Date(order.updatedAt), 'dd.MM.yyyy hh:mm') }) }), _jsx(Renderer, { position: "orders-summary" })] }));
|
|
10
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, DialogHeader, Dialog, DialogContent, DialogDescription, DialogTitle, DialogTrigger, } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { FileText } from 'lucide-react';
|
|
4
|
+
export const MetadataDisplay = ({ metadata }) => {
|
|
5
|
+
return metadata && Object.keys(metadata).length > 0 ? (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", className: "h-8 gap-1", children: [_jsx(FileText, { className: "size-4" }), _jsx("span", { children: "View" })] }) }), _jsxs(DialogContent, { className: "max-w-lg", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(FileText, { className: "size-5 text-teal-500" }), "Payment Metadata"] }), _jsx(DialogDescription, { children: "Additional information associated with this payment" })] }), _jsx("div", { className: "bg-muted/50 mt-4 rounded-md border p-4", children: _jsx("div", { className: "max-h-[300px] overflow-auto", children: Object.entries(metadata).map(([key, value]) => (_jsxs("div", { className: "border-border mb-3 border-b pb-2 last:border-0", children: [_jsx("div", { className: "text-muted-foreground mb-1 text-xs font-medium uppercase tracking-wide", children: key }), _jsx("div", { className: "break-all font-mono text-sm", children: typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value) })] }, key))) }) })] })] })) : null;
|
|
6
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useOrder, Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, ScrollArea, Badge, DropdownMenuItem, ContextMenu, ConfirmationDialog, CustomCard, EmptyState, useTranslation, apiClient, DialogTrigger, Input, priceFormatter, } from '@deenruv/react-ui-devkit';
|
|
5
|
+
import { format } from 'date-fns';
|
|
6
|
+
import { CreditCard, Calendar, CheckCircle2, XCircle, Clock, AlertCircle, Wallet, Receipt, CheckCircle, Ban, ArrowDownCircle, ArrowUpCircle, RefreshCcw, } from 'lucide-react';
|
|
7
|
+
import { useState } from 'react';
|
|
8
|
+
import { AddPaymentDialog } from './index.js';
|
|
9
|
+
import { PAYMENT_STATE } from "../../../graphql/base";
|
|
10
|
+
import { MetadataDisplay } from './PaymentMetadata.js';
|
|
11
|
+
export const Payments = () => {
|
|
12
|
+
const { order, addPaymentToOrder, settlePayment, cancelPayment } = useOrder();
|
|
13
|
+
const { t } = useTranslation('orders');
|
|
14
|
+
const [paymentToBeSettled, setPaymentToBeSettled] = useState('');
|
|
15
|
+
const [expandedRefunds, setExpandedRefunds] = useState([]);
|
|
16
|
+
if (!order)
|
|
17
|
+
return null;
|
|
18
|
+
const { payments } = order;
|
|
19
|
+
// Helper function to get status badge styling
|
|
20
|
+
const getStatusBadge = (state) => {
|
|
21
|
+
switch (state) {
|
|
22
|
+
case PAYMENT_STATE.SETTLED:
|
|
23
|
+
return {
|
|
24
|
+
variant: 'success',
|
|
25
|
+
icon: _jsx(CheckCircle, { className: "mr-1 size-3.5" }),
|
|
26
|
+
label: t('payments.status.settled', 'Settled'),
|
|
27
|
+
};
|
|
28
|
+
case PAYMENT_STATE.CANCELLED:
|
|
29
|
+
return {
|
|
30
|
+
variant: 'destructive',
|
|
31
|
+
icon: _jsx(Ban, { className: "mr-1 size-3.5" }),
|
|
32
|
+
label: t('payments.status.cancelled', 'Cancelled'),
|
|
33
|
+
};
|
|
34
|
+
case PAYMENT_STATE.AUTHORIZED:
|
|
35
|
+
return {
|
|
36
|
+
variant: 'outline',
|
|
37
|
+
icon: _jsx(Clock, { className: "mr-1 size-3.5" }),
|
|
38
|
+
label: t('payments.status.authorized', 'Authorized'),
|
|
39
|
+
};
|
|
40
|
+
default:
|
|
41
|
+
return {
|
|
42
|
+
variant: 'secondary',
|
|
43
|
+
icon: _jsx(AlertCircle, { className: "mr-1 size-3.5" }),
|
|
44
|
+
label: state,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
// Helper function to get refund status badge styling
|
|
49
|
+
const getRefundStatusBadge = (state) => {
|
|
50
|
+
switch (state.toLowerCase()) {
|
|
51
|
+
case 'settled':
|
|
52
|
+
return {
|
|
53
|
+
variant: 'success',
|
|
54
|
+
icon: _jsx(CheckCircle, { className: "mr-1 size-3.5" }),
|
|
55
|
+
label: t('refunds.status.settled', 'Settled'),
|
|
56
|
+
};
|
|
57
|
+
case 'pending':
|
|
58
|
+
return {
|
|
59
|
+
variant: 'outline',
|
|
60
|
+
icon: _jsx(Clock, { className: "mr-1 size-3.5" }),
|
|
61
|
+
label: t('refunds.status.pending', 'Pending'),
|
|
62
|
+
};
|
|
63
|
+
case 'failed':
|
|
64
|
+
return {
|
|
65
|
+
variant: 'destructive',
|
|
66
|
+
icon: _jsx(XCircle, { className: "mr-1 size-3.5" }),
|
|
67
|
+
label: t('refunds.status.failed', 'Failed'),
|
|
68
|
+
};
|
|
69
|
+
default:
|
|
70
|
+
return {
|
|
71
|
+
variant: 'secondary',
|
|
72
|
+
icon: _jsx(AlertCircle, { className: "mr-1 size-3.5" }),
|
|
73
|
+
label: state,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const toggleRefundExpand = (id) => {
|
|
78
|
+
setExpandedRefunds((prev) => (prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]));
|
|
79
|
+
};
|
|
80
|
+
const [settleRefundTransactionId, setSettleRefundTransactionId] = useState(null);
|
|
81
|
+
const settleRefund = async (id) => {
|
|
82
|
+
if (!settleRefundTransactionId) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const { settleRefund } = await apiClient('mutation')({
|
|
86
|
+
settleRefund: [
|
|
87
|
+
{ input: { id, transactionId: settleRefundTransactionId } },
|
|
88
|
+
{
|
|
89
|
+
__typename: true,
|
|
90
|
+
'...on Refund': { id: true },
|
|
91
|
+
'...on RefundStateTransitionError': { errorCode: true, fromState: true, message: true },
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
});
|
|
95
|
+
if (settleRefund.__typename === 'Refund') {
|
|
96
|
+
setSettleRefundTransactionId(null);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
console.error(settleRefund);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
return (_jsxs(CustomCard, { color: "teal", description: t('payments.subTitle'), title: t('payments.title'), icon: _jsx(Wallet, { className: "size-5 text-teal-500 dark:text-teal-400" }), upperRight: _jsx(AddPaymentDialog, { order: order, onSubmit: (v) => addPaymentToOrder(v) }), children: [_jsx(Dialog, { open: !!paymentToBeSettled, onOpenChange: () => setPaymentToBeSettled(''), children: _jsxs(DialogContent, { className: "max-w-md", children: [_jsxs(DialogHeader, { children: [_jsxs("div", { className: "mb-2 flex items-center gap-2", children: [_jsx(CheckCircle2, { className: "size-5 text-teal-500" }), _jsx(DialogTitle, { children: t('payments.settle.title', 'Settle Payment') })] }), _jsx(DialogDescription, { children: t('payments.settle.description', 'Are you sure you want to settle this payment? This action cannot be undone.') })] }), _jsxs(DialogFooter, { className: "mt-4 gap-2", children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { variant: "outline", children: t('payments.settle.cancel', 'Cancel') }) }), _jsxs(Button, { variant: "default", onClick: () => settlePayment({ id: paymentToBeSettled }), className: "gap-2", children: [_jsx(CheckCircle2, { className: "size-4" }), t('payments.settle.confirm', 'Confirm Settlement')] })] })] }) }), _jsx(ScrollArea, { className: "max-h-[400px] px-6", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { noHover: true, className: "border-border border-b", children: [_jsx(TableHead, { className: "w-[80px] py-3", children: t('payments.id') }), _jsx(TableHead, { className: "py-3", children: t('payments.created') }), _jsx(TableHead, { className: "py-3", children: t('payments.method') }), _jsx(TableHead, { className: "py-3", children: t('payments.status') }), _jsx(TableHead, { className: "py-3", children: t('payments.amount') }), _jsx(TableHead, { className: "py-3", children: t('payments.refunds', 'Refunds') }), _jsx(TableHead, { className: "py-3 text-center", children: t('payments.extra') }), _jsx(TableHead, { className: "ml-auto py-3" })] }) }), _jsx(TableBody, { children: payments?.length ? (payments.map(({ amount, id, method, state, createdAt, metadata, refunds, transactionId }) => {
|
|
103
|
+
const statusBadge = getStatusBadge(state);
|
|
104
|
+
const hasRefunds = refunds && refunds.length > 0;
|
|
105
|
+
const isRefundExpanded = expandedRefunds.includes(id);
|
|
106
|
+
const totalRefunded = hasRefunds ? refunds.reduce((sum, refund) => sum + refund.total, 0) : 0;
|
|
107
|
+
return (_jsxs(React.Fragment, { children: [_jsxs(TableRow, { noHover: true, className: "group", children: [_jsx(TableCell, { className: "text-muted-foreground py-3 font-mono text-xs", children: id }), _jsx(TableCell, { className: "py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "size-4 text-teal-500 dark:text-teal-400" }), _jsx("span", { children: format(new Date(createdAt), 'dd/LL/Y, kk:mm') })] }) }), _jsx(TableCell, { className: "py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CreditCard, { className: "size-4 text-teal-500 dark:text-teal-400" }), _jsx("span", { className: "font-medium", children: method })] }) }), _jsx(TableCell, { className: "py-3", children: _jsxs(Badge, { variant: statusBadge.variant, className: "flex w-fit items-center gap-1", children: [statusBadge.icon, statusBadge.label] }) }), _jsx(TableCell, { className: "py-3 font-mono text-sm font-medium", children: priceFormatter(amount, order.currencyCode) }), _jsx(TableCell, { className: "py-3", children: hasRefunds ? (_jsx("div", { className: "flex flex-col gap-1", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(RefreshCcw, { className: "size-4 text-orange-500 dark:text-orange-400" }), _jsx("span", { className: "font-mono text-sm font-medium text-orange-600 dark:text-orange-400", children: priceFormatter(totalRefunded, order.currencyCode) }), _jsx(Button, { variant: "ghost", size: "sm", className: "h-6 p-0", onClick: () => toggleRefundExpand(id), children: isRefundExpanded ? (_jsx(ArrowUpCircle, { className: "text-muted-foreground size-4" })) : (_jsx(ArrowDownCircle, { className: "text-muted-foreground size-4" })) })] }) })) : (_jsx("span", { className: "text-muted-foreground text-sm", children: "-" })) }), _jsx(TableCell, { className: "flex items-center justify-center", children: _jsx(MetadataDisplay, { metadata: metadata }) }), _jsx(TableCell, { className: "py-3 text-end", children: _jsxs(ContextMenu, { children: [state !== PAYMENT_STATE.SETTLED && state !== PAYMENT_STATE.CANCELLED && (_jsxs(DropdownMenuItem, { onClick: () => setPaymentToBeSettled(id), className: "flex cursor-pointer items-center gap-2", children: [_jsx(CheckCircle2, { size: 16 }), t('payments.settle.settle', 'Settle')] }, 'set')), !hasRefunds && state !== PAYMENT_STATE.CANCELLED && (_jsx(ConfirmationDialog, { onConfirm: () => cancelPayment(id), children: _jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2 text-red-500", onSelect: (e) => e.preventDefault(), children: [_jsx(XCircle, { size: 16 }), t('payments.cancel', 'Cancel')] }, 'cancel') }))] }) })] }), hasRefunds && isRefundExpanded && (_jsx(TableRow, { noHover: true, className: "bg-muted/30", children: _jsx(TableCell, { colSpan: 8, className: "p-0", children: _jsxs("div", { className: "px-8 py-3", children: [_jsx("div", { className: "mb-2 text-sm font-medium", children: t('refunds.details', 'Refund Details') }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { noHover: true, className: "border-border border-b", children: [_jsx(TableHead, { className: "py-2 text-xs", children: t('refunds.state', 'Status') }), _jsx(TableHead, { className: "py-2 text-xs", children: t('refunds.amount', 'Amount') }), _jsx(TableHead, { className: "py-2 text-xs", children: t('refunds.items', 'Items') }), refunds.some((refund) => refund.state.toLowerCase() === 'pending') && (_jsx(TableHead, { className: "py-2 text-xs", children: t('refunds.actions', 'Actions') }))] }) }), _jsx(TableBody, { children: refunds.map((refund, index) => {
|
|
108
|
+
const refundStatusBadge = getRefundStatusBadge(refund.state);
|
|
109
|
+
const state = refund.state.toLowerCase();
|
|
110
|
+
return (_jsxs(TableRow, { noHover: true, className: "border-border/50 border-b", children: [_jsx(TableCell, { className: "py-2", children: _jsxs(Badge, { variant: refundStatusBadge.variant, className: "flex w-fit items-center gap-1", children: [refundStatusBadge.icon, refundStatusBadge.label] }) }), _jsx(TableCell, { className: "py-2 font-mono text-sm", children: priceFormatter(refund.total, order.currencyCode) }), _jsx(TableCell, { className: "py-2", children: _jsx("div", { className: "text-sm", children: refund.lines.map((line, lineIndex) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-muted-foreground font-mono text-xs", children: [line.orderLineId, " |"] }), _jsxs("span", { className: "text-xs", children: ["\u00D7", line.quantity] })] }, `${id}-refund-${index}-line-${lineIndex}`))) }) }), state === 'pending' && (_jsx(TableCell, { className: "py-2", children: _jsxs(Dialog, { children: [_jsx(DialogTrigger, { asChild: true, children: _jsx(Button, { children: "Settle refund" }) }), _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Settle refund" }), _jsx(DialogDescription, { children: "After manually refunding via your payment provider (standard-payment), enter the transaction ID here." })] }), _jsx("div", { children: _jsx(Input, { placeholder: "Transaction ID", value: settleRefundTransactionId || '', onChange: (e) => setSettleRefundTransactionId(e.target.value) }) }), _jsxs(DialogFooter, { children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { variant: "outline", children: t('payments.settle.cancel', 'Cancel') }) }), _jsxs(Button, { variant: "default", onClick: () => settleRefund(refund.id), className: "gap-2", children: [_jsx(CheckCircle2, { className: "size-4" }), t('payments.settle.confirm', 'Confirm Settlement')] })] })] })] }) }))] }, `${id}-refund-${index}`));
|
|
111
|
+
}) })] })] }) }) }))] }, id));
|
|
112
|
+
})) : (_jsx(EmptyState, { columnsLength: 8, title: t('payments.notFound', 'No payments found'), color: "teal", description: t('payments.addPaymentHint'), small: true, icon: _jsx(Receipt, {}) })) })] }) })] }));
|
|
113
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { ScrollArea, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, Timeline, TimelineItem, TimelineLine, TimelineDot, TimelineContent, TimelineHeading, useServer, Button, Badge, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
4
|
+
import { ArrowRight, Check, CircleDot } from 'lucide-react';
|
|
5
|
+
export const PossibleOrderStates = ({ orderState }) => {
|
|
6
|
+
const { t } = useTranslation('orders');
|
|
7
|
+
const { t: tCommon } = useTranslation('common');
|
|
8
|
+
const orderProcess = useServer((p) => p.serverConfig?.orderProcess || []);
|
|
9
|
+
const statesAfterCancelled = useMemo(() => {
|
|
10
|
+
const cancelledIndex = orderProcess.findIndex((s) => s.name === 'Cancelled');
|
|
11
|
+
if (cancelledIndex === -1)
|
|
12
|
+
return null;
|
|
13
|
+
return orderProcess.slice(cancelledIndex + 1);
|
|
14
|
+
}, [orderProcess]);
|
|
15
|
+
const sortedOrderProcess = useMemo(() => {
|
|
16
|
+
if (!statesAfterCancelled)
|
|
17
|
+
return orderProcess;
|
|
18
|
+
const sorted = [];
|
|
19
|
+
let i = 0;
|
|
20
|
+
while (i < orderProcess.length) {
|
|
21
|
+
const state = orderProcess[i];
|
|
22
|
+
const firstPossibleNextState = state.to.length > 0 ? state.to[0] : null;
|
|
23
|
+
if (firstPossibleNextState) {
|
|
24
|
+
const stateAfterCancelled = statesAfterCancelled.find((s) => s.name === firstPossibleNextState);
|
|
25
|
+
if (stateAfterCancelled) {
|
|
26
|
+
sorted.push(state);
|
|
27
|
+
sorted.push(stateAfterCancelled);
|
|
28
|
+
i++;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
sorted.push(state);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
sorted.push(state);
|
|
36
|
+
}
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
const cancelledIndex = sorted.findIndex((s) => s.name === 'Cancelled');
|
|
40
|
+
if (cancelledIndex !== -1) {
|
|
41
|
+
return sorted.slice(0, cancelledIndex + 1);
|
|
42
|
+
}
|
|
43
|
+
return sorted;
|
|
44
|
+
}, [orderProcess, statesAfterCancelled]);
|
|
45
|
+
const currentStateIndex = useMemo(() => sortedOrderProcess.findIndex((s) => s.name === orderState), [sortedOrderProcess, orderState]);
|
|
46
|
+
const currentStateObj = useMemo(() => sortedOrderProcess.find((s) => s.name === orderState), [sortedOrderProcess, orderState]);
|
|
47
|
+
const possibleNextStates = useMemo(() => currentStateObj?.to || [], [currentStateObj]);
|
|
48
|
+
return (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", className: "w-full cursor-pointer justify-start px-4 py-2 focus-visible:ring-transparent dark:focus-visible:ring-transparent", children: t('orderStates.button') }) }), _jsxs(DialogContent, { className: "max-w-[40vw]", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t('orderStates.title') }), _jsx(DialogDescription, { children: t('orderStates.description') })] }), _jsxs("div", { className: "bg-muted/50 mb-4 rounded-md border p-4", children: [_jsx("h3", { className: "mb-2 text-sm font-medium", children: t('orderStates.currentState') }), _jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx(CircleDot, { className: "text-primary size-5" }), _jsx("span", { className: "font-semibold", children: orderState })] }), possibleNextStates.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("h4", { className: "mb-2 text-sm font-medium", children: t('orderStates.possibleNextStates') }), _jsx("div", { className: "flex flex-wrap gap-2", children: possibleNextStates.map((nextState) => (_jsxs(Badge, { variant: "outline", className: "flex items-center gap-1", children: [tCommon('search.inOperator.' + nextState), _jsx(ArrowRight, { className: "ml-1 size-3" })] }, nextState))) })] })) : (_jsx("p", { className: "text-muted-foreground text-sm", children: t('orderStates.finalState') }))] }), _jsx(ScrollArea, { className: "h-[60vh]", children: _jsx(Timeline, { children: sortedOrderProcess.map((state, index) => {
|
|
49
|
+
const isPast = index < currentStateIndex;
|
|
50
|
+
const isCurrent = index === currentStateIndex;
|
|
51
|
+
const isPossibleNext = possibleNextStates.includes(state.name);
|
|
52
|
+
return (_jsxs(TimelineItem, { status: isPast ? 'done' : isCurrent ? null : 'default', children: [_jsx(TimelineLine, { done: isPast }), _jsx(TimelineDot, { status: isPast ? 'done' : isCurrent ? 'current' : 'default', className: isPossibleNext ? 'ring-primary ring-1 ring-offset-1' : '', children: isPast && _jsx(Check, { className: "size-4" }) }), _jsxs(TimelineContent, { children: [_jsxs(TimelineHeading, { className: isCurrent ? 'text-primary font-bold' : '', children: [tCommon('search.inOperator.' + state.name), isCurrent && (_jsx(Badge, { className: "ml-2", variant: "default", children: t('orderStates.current') })), isPossibleNext && (_jsx(Badge, { className: "ml-2", variant: "outline", children: t('orderStates.possible') }))] }), state.to.length > 0 && (_jsxs("div", { className: "mt-1", children: [_jsxs("p", { className: "text-muted-foreground mb-1 text-sm", children: [t('orderStates.canTransitionTo'), ":"] }), _jsx("div", { className: "mt-1 flex flex-wrap gap-1", children: state.to.map((nextState) => (_jsx(Badge, { variant: "outline", className: `text-xs ${orderState === nextState ? 'bg-primary/10 border-primary' : ''}`, children: tCommon('search.inOperator.' + nextState) }, nextState))) })] })), state.to.length === 0 && (_jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: t('orderStates.finalState') }))] })] }, state.name));
|
|
53
|
+
}) }) })] })] }));
|
|
54
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation, useOrder, priceFormatter, CardFooter } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { ShieldCheck } from 'lucide-react';
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
export const PriceChangedInfo = ({ changes }) => {
|
|
6
|
+
const { order } = useOrder();
|
|
7
|
+
const { t } = useTranslation('orders');
|
|
8
|
+
const priceDifference = useMemo(() => {
|
|
9
|
+
const totalWithTaxChange = changes?.rest.find((ch) => ch.path === 'totalWithTax');
|
|
10
|
+
console.log('TOTAL', totalWithTaxChange);
|
|
11
|
+
if (!totalWithTaxChange)
|
|
12
|
+
return 0;
|
|
13
|
+
return +totalWithTaxChange.added - +totalWithTaxChange.removed;
|
|
14
|
+
}, [changes]);
|
|
15
|
+
return priceDifference ? (_jsx(CardFooter, { className: "flex flex-col border-t pt-4", children: _jsx("div", { className: "w-full rounded-md border border-amber-200 bg-amber-50 p-3 dark:border-amber-800 dark:bg-amber-900/20", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(ShieldCheck, { className: "mt-0.5 size-5 text-amber-500" }), _jsxs("div", { children: [t('modify.priceDifference'), " ", priceDifference > 0 && '+', priceFormatter(priceDifference, order?.currencyCode)] })] }) }) })) : null;
|
|
16
|
+
};
|