@deenruv/admin-dashboard 1.0.0 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DeenruvAdminPanel.js +1 -1
- package/dist/DeenruvDeveloperIndicator.js +1 -1
- package/dist/components/CanLeaveRouteDialog.js +1 -1
- package/dist/components/DeleteDialog.js +1 -1
- package/dist/components/GlobalSearch.js +6 -6
- package/dist/components/History/AddEntryForm.js +3 -3
- package/dist/components/History/DeleteEntryDialog.js +1 -1
- package/dist/components/History/EditEntryDialog.js +1 -1
- package/dist/components/History/History.js +1 -1
- package/dist/components/History/ModifyHistoryInfo.js +1 -1
- package/dist/components/History/Timeline.js +4 -4
- package/dist/components/Menu/ActiveAdmins.js +2 -2
- package/dist/components/Menu/ChannelSwitcher.js +1 -1
- package/dist/components/Menu/Navigation.js +4 -4
- package/dist/components/Menu/NavigationFooter.js +3 -3
- package/dist/components/Menu/Notifications.js +1 -1
- package/dist/components/Menu/index.js +5 -5
- package/dist/index.css +182 -92
- package/dist/pages/Custom404.js +1 -1
- package/dist/pages/LoginScreen.js +1 -1
- package/dist/pages/Root.js +2 -2
- package/dist/pages/admins/Detail.js +1 -1
- package/dist/pages/assets/_components/Asset.js +3 -3
- package/dist/pages/assets/_components/AssetListView.js +2 -2
- package/dist/pages/assets/_components/EditAssetDialog.js +5 -5
- package/dist/pages/assets/_components/UploadAssetDialog.js +2 -2
- package/dist/pages/assets/_components/UploadProgress.js +1 -1
- package/dist/pages/channels/Detail.js +1 -1
- package/dist/pages/collections/Detail.js +1 -1
- package/dist/pages/collections/_components/CollectionDetailView.js +1 -1
- package/dist/pages/collections/_components/CollectionProductVariantsDrawer.js +1 -1
- package/dist/pages/collections/_components/CombinationMode.js +1 -1
- package/dist/pages/collections/_components/ContentsTable.js +2 -2
- package/dist/pages/collections/_components/MoveCollectionsToCollections.js +2 -2
- package/dist/pages/collections/_components/MoveEntityToChannels.js +2 -2
- package/dist/pages/collections/_components/PageHeader.js +2 -2
- package/dist/pages/countries/Detail.js +1 -1
- package/dist/pages/customer-groups/Detail.js +1 -1
- package/dist/pages/customers/Detail.js +1 -1
- package/dist/pages/customers/_components/Address.js +1 -1
- package/dist/pages/dashboard/Dashboard.js +1 -1
- package/dist/pages/extensions/Extensions.js +5 -5
- package/dist/pages/facets/Detail.js +1 -1
- package/dist/pages/orders/Detail.js +1 -1
- package/dist/pages/orders/List.js +1 -1
- package/dist/pages/orders/_components/AddPaymentDialog.js +1 -1
- package/dist/pages/orders/_components/AddressCard.js +2 -2
- package/dist/pages/orders/_components/ChangesRegister.js +3 -3
- package/dist/pages/orders/_components/CouponCodesCard.js +1 -1
- package/dist/pages/orders/_components/CustomComponent.js +1 -1
- package/dist/pages/orders/_components/CustomerSelectCard.js +2 -2
- package/dist/pages/orders/_components/FulfillmentModal.js +3 -3
- package/dist/pages/orders/_components/LineItem.js +1 -1
- package/dist/pages/orders/_components/ManualOrderChangeModal.js +2 -2
- package/dist/pages/orders/_components/ModifyingCard.js +1 -1
- package/dist/pages/orders/_components/OrderHistory.js +1 -1
- package/dist/pages/orders/_components/OrderLineActionModal/ActionQuantityPrice.js +2 -2
- package/dist/pages/orders/_components/OrderLineActionModal/index.js +1 -1
- package/dist/pages/orders/_components/PaymentMetadata.js +1 -1
- package/dist/pages/orders/_components/Payments.js +3 -3
- package/dist/pages/orders/_components/PossibleOrderStates.js +2 -2
- package/dist/pages/orders/_components/ProductsCard.js +4 -4
- package/dist/pages/orders/_components/ProductsTable.js +2 -2
- package/dist/pages/orders/_components/PromotionsList.js +1 -1
- package/dist/pages/orders/_components/RealizationCard.js +1 -1
- package/dist/pages/orders/_components/RefundCard.js +1 -1
- package/dist/pages/orders/_components/RefundPaymentCard.js +1 -1
- package/dist/pages/orders/_components/ShippingMethod.js +4 -4
- package/dist/pages/orders/_components/SpecialLineItem.js +1 -1
- package/dist/pages/orders/_components/SurchargeCard.js +1 -1
- package/dist/pages/orders/_components/TaxSummary.js +1 -1
- package/dist/pages/orders/_components/ToRealizationForm.js +1 -1
- package/dist/pages/orders/_components/TopActions.js +4 -4
- package/dist/pages/payment-methods/Detail.js +1 -1
- package/dist/pages/product-variants/List.js +1 -1
- package/dist/pages/products/Detail.js +1 -1
- package/dist/pages/products/_components/ProductDetailSidebar.js +1 -1
- package/dist/pages/products/_components/VariantsTab.js +1 -1
- package/dist/pages/promotions/Detail.js +1 -1
- package/dist/pages/roles/Detail.js +1 -1
- package/dist/pages/roles/_components/PermissionsTable.js +1 -1
- package/dist/pages/sellers/Detail.js +1 -1
- package/dist/pages/shipping-methods/Detail.js +1 -1
- package/dist/pages/status/_components/FilterToolbar.js +1 -1
- package/dist/pages/status/_components/Health.js +4 -4
- package/dist/pages/status/_components/JobResultPopover.js +1 -1
- package/dist/pages/stock-locations/Detail.js +1 -1
- package/dist/pages/tax-categories/Detail.js +1 -1
- package/dist/pages/tax-rates/Detail.js +1 -1
- package/dist/pages/zones/Detail.js +1 -1
- package/dist/version.js +1 -1
- package/package.json +82 -84
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
// eslint-disable-next-line no-restricted-imports
|
|
3
3
|
import { I18nextProvider } from 'react-i18next';
|
|
4
4
|
import { useEffect } from 'react';
|
|
5
|
-
import {
|
|
5
|
+
import { createBrowserRouter, RouterProvider } from 'react-router';
|
|
6
6
|
import { AnimatePresence } from 'framer-motion';
|
|
7
7
|
import { Toaster } from 'sonner';
|
|
8
8
|
import i18n from './i18.js';
|
|
@@ -53,5 +53,5 @@ export const DeenruvDeveloperIndicator = () => {
|
|
|
53
53
|
const { graphQLSchema } = useServer(({ graphQLSchema }) => ({ graphQLSchema }));
|
|
54
54
|
const { plugins, viewMarkers, setViewMarkers } = usePluginStore();
|
|
55
55
|
const [showSchema, setShowSchema] = useState(false);
|
|
56
|
-
return (_jsx("div", { className: "fixed
|
|
56
|
+
return (_jsx("div", { className: "fixed right-4 bottom-4", children: _jsxs(Drawer, { children: [_jsx(DrawerTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", className: "flex size-10 items-center justify-center rounded-full border-dashed border-primary text-xs", children: "DDP" }) }), _jsx(DrawerContent, { className: "w-full max-w-5xl place-self-end", children: _jsxs("div", { className: "w-full", children: [_jsx(DrawerHeader, { children: _jsx(DrawerTitle, { children: "DDP - Deenruv Developer Panel" }) }), _jsx("div", { className: "p-4 pb-0", children: _jsxs("div", { className: "flex flex-col space-y-4 md:flex-row md:space-y-0 md:space-x-4", children: [_jsxs("div", { className: "space-y-4 md:w-1/4", children: [_jsxs("div", { className: "rounded-md border p-3", children: [_jsx("h3", { className: "mb-2 text-sm font-medium", children: "Controls" }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(Switch, { id: "markers", checked: viewMarkers, onCheckedChange: setViewMarkers }), _jsx("label", { htmlFor: "markers", className: "text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: "Show markers (ctrl + x)" })] }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(Switch, { id: "schema", checked: showSchema, onCheckedChange: setShowSchema }), _jsx("label", { htmlFor: "schema", className: "text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: "Show GraphQL Schema" })] })] })] }), _jsxs("div", { className: "rounded-md border p-3", children: [_jsxs("div", { className: "mb-1 flex items-center gap-2", children: [_jsx("div", { className: "size-3 rounded-full bg-green-500" }), _jsx("h3", { className: "text-sm font-medium", children: "Plugins" })] }), _jsx(ScrollArea, { className: "mt-2 h-[250px]", children: _jsxs("div", { className: "grid gap-2 pr-2", children: [plugins.map((plugin) => (_jsxs("div", { className: "dark:hover:bg-gray-750 flex items-center rounded-md border border-gray-200 bg-gray-50 p-2 transition-colors hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-800", children: [_jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "text-sm font-medium", children: plugin.name }), _jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: ["v", plugin.version] })] }), _jsx("div", { className: "mr-1 size-2 rounded-full bg-green-500", title: "Active" })] }, plugin.name))), plugins.length === 0 && (_jsx("div", { className: "py-4 text-center text-sm text-gray-500 italic dark:text-gray-400", children: "No plugins installed" }))] }) })] })] }), _jsx("div", { className: "md:w-3/4" })] }) }), _jsx(DrawerFooter, { children: _jsx(DrawerClose, { asChild: true, children: _jsx(Button, { variant: "outline", children: "Close" }) }) })] }) })] }) }));
|
|
57
57
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, useRouteGuardStore, } from '@deenruv/react-ui-devkit';
|
|
3
|
-
import { useNavigate } from 'react-router
|
|
3
|
+
import { useNavigate } from 'react-router';
|
|
4
4
|
export const CanLeaveRouteDialog = () => {
|
|
5
5
|
const { isModalOpen, confirmNavigation, cancelNavigation } = useRouteGuardStore();
|
|
6
6
|
const navigate = useNavigate();
|
|
@@ -2,5 +2,5 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { Button, DialogTitle, Dialog, DialogContent, DialogFooter, DialogClose, DialogDescription, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
3
3
|
export const DeleteDialog = ({ onConfirm, title, description, onOpenChange, open, deletedNames, }) => {
|
|
4
4
|
const { t } = useTranslation('common');
|
|
5
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsxs(DialogTitle, { children: [" ", title] }), _jsxs("div", { className: "flex max-h-[50vh] flex-col gap-2", children: [_jsx(DialogDescription, { className: "text-
|
|
5
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsxs(DialogTitle, { children: [" ", title] }), _jsxs("div", { className: "flex max-h-[50vh] flex-col gap-2", children: [_jsx(DialogDescription, { className: "text-lg text-primary", children: description }), _jsx(DialogDescription, { children: deletedNames.map((n) => (_jsx("div", { children: n }, n))) })] }), _jsxs(DialogFooter, { children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { variant: "ghost", children: t('confirmationDialog.cancelBtn') }) }), _jsx(Button, { variant: "destructive", onClick: onConfirm, children: t('confirmationDialog.confirmBtn') })] })] }) }));
|
|
6
6
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, usePluginStore, Routes, useGlobalSearch, capitalizeFirstLetter, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
3
3
|
import { useEffect, useMemo } from 'react';
|
|
4
|
-
import { useNavigate } from 'react-router
|
|
4
|
+
import { useNavigate } from 'react-router';
|
|
5
5
|
import { LayoutDashboard, ListPlus, FileText, Puzzle, ArrowRight } from 'lucide-react';
|
|
6
6
|
export const GlobalSearch = () => {
|
|
7
7
|
const { t, tEntity } = useTranslation('common');
|
|
@@ -110,25 +110,25 @@ export const GlobalSearch = () => {
|
|
|
110
110
|
return _jsx(LayoutDashboard, { className: "mr-2 h-4 w-4 text-gray-500" });
|
|
111
111
|
}
|
|
112
112
|
};
|
|
113
|
-
return (_jsxs(CommandDialog, { open: isOpen, onOpenChange: toggle, modal: true, children: [_jsx(CommandInput, { placeholder: t('globalSearch.placeholder'), className: "
|
|
113
|
+
return (_jsxs(CommandDialog, { open: isOpen, onOpenChange: toggle, modal: true, children: [_jsx(CommandInput, { placeholder: t('globalSearch.placeholder'), className: "flex-1 bg-transparent text-base outline-none placeholder:text-muted-foreground" }), _jsxs(CommandList, { className: "max-h-[300px] overflow-y-auto py-2", children: [_jsx(CommandEmpty, { className: "py-6 text-center text-sm", children: t('globalSearch.emptyState') }), groupedRoutes.core.length > 0 && (_jsx(CommandGroup, { heading: t('globalSearch.navigation'), className: "px-2", children: groupedRoutes.core.map((route) => (_jsxs(CommandItem, { onSelect: () => {
|
|
114
114
|
if (route.path) {
|
|
115
115
|
navigate(route.path);
|
|
116
116
|
}
|
|
117
117
|
close();
|
|
118
|
-
}, className: "
|
|
118
|
+
}, className: "group flex cursor-pointer items-center rounded-md px-2 py-2 transition-colors hover:bg-accent", children: [getRouteIcon(route.type), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "font-medium", children: route.name }), route.description && _jsx("span", { className: "text-xs text-muted-foreground", children: route.description })] }), _jsx(ArrowRight, { className: "ml-auto h-4 w-4 opacity-0 transition-opacity group-hover:opacity-70" })] }, route.id || `core-${route.name}-${route.path}`))) })), groupedRoutes.newItems.length > 0 && (_jsx(CommandGroup, { heading: t('globalSearch.createNew'), className: "px-2", children: groupedRoutes.newItems.map((route) => (_jsxs(CommandItem, { onSelect: () => {
|
|
119
119
|
if (route.path) {
|
|
120
120
|
navigate(route.path);
|
|
121
121
|
}
|
|
122
122
|
close();
|
|
123
|
-
}, className: "
|
|
123
|
+
}, className: "group flex cursor-pointer items-center rounded-md px-2 py-2 transition-colors hover:bg-accent", children: [getRouteIcon(route.type), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "font-medium", children: route.name }), route.description && _jsx("span", { className: "text-xs text-muted-foreground", children: route.description })] }), _jsx(ArrowRight, { className: "ml-auto h-4 w-4 opacity-0 transition-opacity group-hover:opacity-70" })] }, route.id || `new-${route.name}-${route.path}`))) })), groupedRoutes.lists.length > 0 && (_jsx(CommandGroup, { heading: t('globalSearch.viewLists'), className: "px-2", children: groupedRoutes.lists.map((route) => (_jsxs(CommandItem, { onSelect: () => {
|
|
124
124
|
if (route.path) {
|
|
125
125
|
navigate(route.path);
|
|
126
126
|
}
|
|
127
127
|
close();
|
|
128
|
-
}, className: "
|
|
128
|
+
}, className: "group flex cursor-pointer items-center rounded-md px-2 py-2 transition-colors hover:bg-accent", children: [getRouteIcon(route.type), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "font-medium", children: route.name }), route.description && _jsx("span", { className: "text-xs text-muted-foreground", children: route.description })] }), _jsx(ArrowRight, { className: "ml-auto h-4 w-4 opacity-0 transition-opacity group-hover:opacity-70" })] }, route.id || `list-${route.name}-${route.path}`))) })), groupedRoutes.pluginRoutes.length > 0 && (_jsx(CommandGroup, { heading: t('globalSearch.plugins'), className: "px-2", children: groupedRoutes.pluginRoutes.map((route) => (_jsxs(CommandItem, { onSelect: () => {
|
|
129
129
|
if (route.path) {
|
|
130
130
|
navigate(route.path);
|
|
131
131
|
}
|
|
132
132
|
close();
|
|
133
|
-
}, className: "
|
|
133
|
+
}, className: "group flex cursor-pointer items-center rounded-md px-2 py-2 transition-colors hover:bg-accent", children: [getRouteIcon(route.type), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "font-medium", children: route.name }), route.description && _jsx("span", { className: "text-xs text-muted-foreground", children: route.description })] }), _jsx(ArrowRight, { className: "ml-auto h-4 w-4 opacity-0 transition-opacity group-hover:opacity-70" })] }, route.id || `plugin-${route.name}-${route.path}`))) }))] }), _jsx("div", { className: "border-t bg-muted/50 p-2", children: _jsxs("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [_jsxs("div", { className: "flex gap-2", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border bg-muted px-1.5 py-0.5 text-[10px]", children: "\u2191" }), _jsx("kbd", { className: "rounded border bg-muted px-1.5 py-0.5 text-[10px]", children: "\u2193" }), _jsx("span", { children: t('globalSearch.navigate') })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border bg-muted px-1.5 py-0.5 text-[10px]", children: "Enter" }), _jsx("span", { children: t('globalSearch.select') })] })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border bg-muted px-1.5 py-0.5 text-[10px]", children: "Esc" }), _jsx("span", { children: t('globalSearch.close') })] })] }) })] }));
|
|
134
134
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useTranslation, Badge, Button, Checkbox, Label, Textarea, cn } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { useState } from 'react';
|
|
5
|
-
import { useParams } from 'react-router
|
|
5
|
+
import { useParams } from 'react-router';
|
|
6
6
|
import { MessageCircle, ShieldCheck, Send } from 'lucide-react';
|
|
7
7
|
export const AddEntryForm = ({ newNote, isPrivate, setIsPrivate, setNewNote, onConfirm, }) => {
|
|
8
8
|
const { t } = useTranslation('common');
|
|
@@ -20,10 +20,10 @@ export const AddEntryForm = ({ newNote, isPrivate, setIsPrivate, setNewNote, onC
|
|
|
20
20
|
setIsSubmitting(false);
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
return (_jsxs("div", { className: "
|
|
23
|
+
return (_jsxs("div", { className: "rounded-md border bg-card p-4", children: [_jsx(Label, { htmlFor: "comment", className: "mb-2 block font-medium", children: t('history.addCommentButton', 'Add a note') }), _jsx("div", { className: "mb-3", children: _jsx(Textarea, { id: "comment", placeholder: t('history.commentPlaceholder', 'Type your note here...'), onKeyUp: (e) => {
|
|
24
24
|
e.currentTarget.style.height = '1px';
|
|
25
25
|
e.currentTarget.style.height = 12 + e.currentTarget.scrollHeight + 'px';
|
|
26
|
-
}, value: newNote, onChange: (e) => setNewNote(e.currentTarget.value), className: "h-min max-h-[300px] min-h-[80px] w-full resize-none overflow-auto rounded-md p-3" }) }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "isPublic", name: "isPublic", checked: isPrivate, onClick: () => setIsPrivate((p) => !p) }), _jsxs(Label, { htmlFor: "isPublic", className: "flex cursor-pointer items-center gap-1 text-sm", children: [_jsx(ShieldCheck, { className: cn('h-4 w-4', isPrivate ? 'text-emerald-500' : 'text-muted-foreground') }), t('history.isPrivate', 'Private note'), _jsx("span", { className: "
|
|
26
|
+
}, value: newNote, onChange: (e) => setNewNote(e.currentTarget.value), className: "h-min max-h-[300px] min-h-[80px] w-full resize-none overflow-auto rounded-md p-3" }) }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "isPublic", name: "isPublic", checked: isPrivate, onClick: () => setIsPrivate((p) => !p) }), _jsxs(Label, { htmlFor: "isPublic", className: "flex cursor-pointer items-center gap-1 text-sm", children: [_jsx(ShieldCheck, { className: cn('h-4 w-4', isPrivate ? 'text-emerald-500' : 'text-muted-foreground') }), t('history.isPrivate', 'Private note'), _jsx("span", { className: "ml-1 text-xs text-muted-foreground", children: t('history.isPrivateDescription', '(visible only to admins)') })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Badge, { variant: isPrivate ? 'outline' : 'secondary', className: cn('gap-1', !isPrivate
|
|
27
27
|
? 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300'
|
|
28
28
|
: 'border-emerald-200 text-emerald-800 dark:border-emerald-800 dark:text-emerald-300'), children: !isPrivate ? (_jsxs(_Fragment, { children: [_jsx(MessageCircle, { className: "size-3" }), t('history.toAdminsAndCustomer', 'Visible to customer')] })) : (_jsxs(_Fragment, { children: [_jsx(ShieldCheck, { className: "size-3" }), t('history.toAdmins', 'Admin only')] })) }), _jsx(Button, { disabled: newNote === '' || isSubmitting, onClick: handleSubmit, className: "gap-2", children: isSubmitting ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "size-4 animate-spin rounded-full border-2 border-current border-r-transparent" }), t('history.adding', 'Adding...')] })) : (_jsxs(_Fragment, { children: [_jsx(Send, { className: "size-4" }), t('history.addComment', 'Add Note')] })) })] })] })] }));
|
|
29
29
|
};
|
|
@@ -18,7 +18,7 @@ export const DeleteEntryDialog = ({ isOpen, setIsOpen, selectedNote, onConfirm }
|
|
|
18
18
|
setIsDeleting(false);
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
|
-
return (_jsx(AlertDialog, { open: isOpen, onOpenChange: setIsOpen, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsxs(AlertDialogTitle, { className: "flex items-center gap-2 text-red-600", children: [_jsx(Trash, { className: "size-5" }), t('history.deleteNoteHeader', 'Delete Note')] }), _jsx(AlertDialogDescription, { children: t('history.deleteConfirmation', 'Are you sure you want to delete this note? This action cannot be undone.') })] }), selectedNote?.data?.note && (_jsx("div", { className: "
|
|
21
|
+
return (_jsx(AlertDialog, { open: isOpen, onOpenChange: setIsOpen, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsxs(AlertDialogTitle, { className: "flex items-center gap-2 text-red-600", children: [_jsx(Trash, { className: "size-5" }), t('history.deleteNoteHeader', 'Delete Note')] }), _jsx(AlertDialogDescription, { children: t('history.deleteConfirmation', 'Are you sure you want to delete this note? This action cannot be undone.') })] }), selectedNote?.data?.note && (_jsx("div", { className: "my-4 max-h-[200px] overflow-y-auto rounded-md border bg-muted/30 p-3 text-sm", children: _jsx("div", { className: "whitespace-pre-wrap", children: selectedNote.data.note }) })), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, children: t('history.cancel', 'Cancel') }), _jsx(AlertDialogAction, { onClick: (e) => {
|
|
22
22
|
e.preventDefault();
|
|
23
23
|
handleDelete();
|
|
24
24
|
}, disabled: isDeleting, className: "bg-red-600 text-white hover:bg-red-700 dark:bg-red-700 dark:hover:bg-red-800", children: isDeleting ? (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: "size-4 animate-spin rounded-full border-2 border-current border-r-transparent" }), t('history.deleting', 'Deleting...')] })) : (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx(Trash, { className: "size-4" }), t('history.delete', 'Delete')] })) })] })] }) }));
|
|
@@ -23,7 +23,7 @@ export const EditEntryDialog = ({ isOpen, setIsOpen, selectedNote, onConfirm, se
|
|
|
23
23
|
setIsUpdating(false);
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
|
-
return (_jsx(AlertDialog, { open: isOpen, onOpenChange: setIsOpen, children: _jsxs(AlertDialogContent, { className: "min-w-min", children: [_jsx(AlertDialogHeader, { children: _jsxs(AlertDialogTitle, { className: "flex items-center gap-2", children: [_jsx(Pencil, { className: "size-5 text-blue-500" }), t('history.editNoteHeader', 'Edit Note')] }) }), _jsx("div", { className: "my-4", children: _jsx(Textarea, { onChange: (e) => setSelectedNote((p) => (p ? { ...p, data: { ...p?.data, note: e.currentTarget.value } } : undefined)), value: selectedNote?.data.note || '', className: "h-[200px] w-full min-w-[400px] resize-none overflow-auto rounded-md p-3", placeholder: t('history.notePlaceholder', 'Enter your note here...') }) }), _jsxs("div", { className: "mb-4 flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "isPublicEdit", name: "isPublicEdit", checked: !selectedNote?.isPublic, onClick: () => setSelectedNote((p) => (p ? { ...p, isPublic: !p.isPublic } : undefined)) }), _jsxs(Label, { htmlFor: "isPublicEdit", className: "flex cursor-pointer items-center gap-1 text-sm", children: [_jsx(ShieldCheck, { className: cn('h-4 w-4', !selectedNote?.isPublic ? 'text-emerald-500' : 'text-muted-foreground') }), t('history.isPrivate', 'Private note'), _jsx("span", { className: "
|
|
26
|
+
return (_jsx(AlertDialog, { open: isOpen, onOpenChange: setIsOpen, children: _jsxs(AlertDialogContent, { className: "min-w-min", children: [_jsx(AlertDialogHeader, { children: _jsxs(AlertDialogTitle, { className: "flex items-center gap-2", children: [_jsx(Pencil, { className: "size-5 text-blue-500" }), t('history.editNoteHeader', 'Edit Note')] }) }), _jsx("div", { className: "my-4", children: _jsx(Textarea, { onChange: (e) => setSelectedNote((p) => (p ? { ...p, data: { ...p?.data, note: e.currentTarget.value } } : undefined)), value: selectedNote?.data.note || '', className: "h-[200px] w-full min-w-[400px] resize-none overflow-auto rounded-md p-3", placeholder: t('history.notePlaceholder', 'Enter your note here...') }) }), _jsxs("div", { className: "mb-4 flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "isPublicEdit", name: "isPublicEdit", checked: !selectedNote?.isPublic, onClick: () => setSelectedNote((p) => (p ? { ...p, isPublic: !p.isPublic } : undefined)) }), _jsxs(Label, { htmlFor: "isPublicEdit", className: "flex cursor-pointer items-center gap-1 text-sm", children: [_jsx(ShieldCheck, { className: cn('h-4 w-4', !selectedNote?.isPublic ? 'text-emerald-500' : 'text-muted-foreground') }), t('history.isPrivate', 'Private note'), _jsx("span", { className: "ml-1 text-xs text-muted-foreground", children: t('history.isPrivateDescription', '(visible only to admins)') })] })] }), _jsx(Badge, { variant: !selectedNote?.isPublic ? 'outline' : 'secondary', className: cn('gap-1', selectedNote?.isPublic
|
|
27
27
|
? 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300'
|
|
28
28
|
: 'border-emerald-200 text-emerald-800 dark:border-emerald-800 dark:text-emerald-300'), children: selectedNote?.isPublic ? (_jsxs(_Fragment, { children: [_jsx(MessageCircle, { className: "size-3" }), t('history.toAdminsAndCustomer', 'Visible to customer')] })) : (_jsxs(_Fragment, { children: [_jsx(ShieldCheck, { className: "size-3" }), t('history.toAdmins', 'Admin only')] })) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isUpdating, children: t('history.cancel', 'Cancel') }), _jsx(AlertDialogAction, { onClick: (e) => {
|
|
29
29
|
e.preventDefault();
|
|
@@ -9,5 +9,5 @@ export const History = ({ data, onNoteAdd, onNoteEdit, onNoteDelete }) => {
|
|
|
9
9
|
const [isEditOpen, setIsEditOpen] = useState(false);
|
|
10
10
|
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
|
|
11
11
|
const [selectedNote, setSelectedNote] = useState();
|
|
12
|
-
return (_jsxs("div", { className: "space-y-6", children: [_jsx(AddEntryForm, { isPrivate: isPrivate, newNote: newNote, onConfirm: onNoteAdd, setIsPrivate: setIsPrivate, setNewNote: setNewNote }), data && data.length > 0 ? (_jsx(Timeline, { setIsDeleteOpen: setIsDeleteOpen, setIsEditOpen: setIsEditOpen, setSelectedNote: setSelectedNote, data: data })) : (_jsxs("div", { className: "flex flex-col items-center justify-center gap-3 py-8 text-center", children: [_jsx("div", { className: "rounded-full bg-amber-100 p-3 dark:bg-amber-900/30", children: _jsx(ClipboardList, { className: "size-6 text-amber-500 dark:text-amber-400" }) }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "No history entries yet" }), _jsx("p", { className: "
|
|
12
|
+
return (_jsxs("div", { className: "space-y-6", children: [_jsx(AddEntryForm, { isPrivate: isPrivate, newNote: newNote, onConfirm: onNoteAdd, setIsPrivate: setIsPrivate, setNewNote: setNewNote }), data && data.length > 0 ? (_jsx(Timeline, { setIsDeleteOpen: setIsDeleteOpen, setIsEditOpen: setIsEditOpen, setSelectedNote: setSelectedNote, data: data })) : (_jsxs("div", { className: "flex flex-col items-center justify-center gap-3 py-8 text-center", children: [_jsx("div", { className: "rounded-full bg-amber-100 p-3 dark:bg-amber-900/30", children: _jsx(ClipboardList, { className: "size-6 text-amber-500 dark:text-amber-400" }) }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "No history entries yet" }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Add a note above to start building the order history" })] })] })), _jsx(DeleteEntryDialog, { isOpen: isDeleteOpen, setIsOpen: setIsDeleteOpen, selectedNote: selectedNote, onConfirm: onNoteDelete }), _jsx(EditEntryDialog, { isOpen: isEditOpen, setIsOpen: setIsEditOpen, selectedNote: selectedNote, setSelectedNote: setSelectedNote, onConfirm: onNoteEdit })] }));
|
|
13
13
|
};
|
|
@@ -2,5 +2,5 @@ import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useTranslation } from '@deenruv/react-ui-devkit';
|
|
3
3
|
export const ModifyHistoryInfo = ({ modificationId }) => {
|
|
4
4
|
const { t } = useTranslation('orders');
|
|
5
|
-
return (_jsxs("div", { className: "
|
|
5
|
+
return (_jsxs("div", { className: "flex gap-2 text-sm text-muted-foreground", children: [t('modifyInfo'), ": ", modificationId] }));
|
|
6
6
|
};
|
|
@@ -25,14 +25,14 @@ const getEntryTypeIcon = (type, isPublic) => {
|
|
|
25
25
|
export const Timeline = ({ data, setIsEditOpen, setIsDeleteOpen, setSelectedNote, }) => {
|
|
26
26
|
const { t } = useTranslation('common');
|
|
27
27
|
const { order } = useOrder();
|
|
28
|
-
return (_jsxs("div", { className: "
|
|
28
|
+
return (_jsxs("div", { className: "rounded-md border bg-card p-4", children: [_jsx("h3", { className: "mb-4 font-medium", children: t('history.timeline') }), _jsx(TimelineWrapper, { positions: "left", className: "w-full", children: data?.map((history) => {
|
|
29
29
|
const entryIcon = getEntryTypeIcon(history.type, history.isPublic);
|
|
30
30
|
const isNote = history.type === HistoryEntryType.ORDER_NOTE || history.type === HistoryEntryType.CUSTOMER_NOTE;
|
|
31
31
|
const modificationNote = history.type === HistoryEntryType.ORDER_MODIFIED
|
|
32
32
|
? order?.modifications.find((m) => m.id === history.data.modificationId)?.note
|
|
33
33
|
: '';
|
|
34
|
-
return (_jsxs(TimelineItem, { status: "done", className: "w-full pb-6", children: [_jsx(TimelineHeading, { side: "right", className: "w-full", children: _jsxs("div", { className: "flex w-full items-center justify-between", children: [_jsx("div", { className: "flex items-center gap-2", children: history.administrator ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "
|
|
35
|
-
Math.floor(new Date(history.updatedAt).getTime() / 1000) && (_jsx("span", { className: "ml-1 italic", children: t('history.edited') }))] })] })] })) : (_jsx("div", { className: "text-muted-foreground
|
|
34
|
+
return (_jsxs(TimelineItem, { status: "done", className: "w-full pb-6", children: [_jsx(TimelineHeading, { side: "right", className: "w-full", children: _jsxs("div", { className: "flex w-full items-center justify-between", children: [_jsx("div", { className: "flex items-center gap-2", children: history.administrator ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex size-8 items-center justify-center rounded-full bg-muted", children: _jsxs("span", { className: "text-xs font-medium", children: [history.administrator.firstName?.[0], history.administrator.lastName?.[0]] }) }), _jsxs("div", { children: [_jsxs("div", { className: "font-medium", children: [history.administrator?.firstName, " ", history.administrator?.lastName] }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [format(new Date(history.createdAt), 'MMM d, yyyy • h:mm a'), Math.floor(new Date(history.createdAt).getTime() / 1000) !==
|
|
35
|
+
Math.floor(new Date(history.updatedAt).getTime() / 1000) && (_jsx("span", { className: "ml-1 italic", children: t('history.edited') }))] })] })] })) : (_jsx("div", { className: "text-sm text-muted-foreground", children: format(new Date(history.createdAt), 'MMM d, yyyy • h:mm a') })) }), _jsxs("div", { className: "flex items-center gap-2", children: [isNote && (_jsx(Badge, { variant: history.isPublic ? 'secondary' : 'outline', className: cn('gap-1', history.isPublic
|
|
36
36
|
? 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300'
|
|
37
37
|
: 'border-emerald-200 text-emerald-800 dark:border-emerald-800 dark:text-emerald-300'), children: history.isPublic ? (_jsxs(_Fragment, { children: [_jsx(MessageCircle, { className: "size-3" }), t('history.public', 'Public')] })) : (_jsxs(_Fragment, { children: [_jsx(ShieldCheck, { className: "size-3" }), t('history.private', 'Private')] })) })), isNote ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "size-8", children: _jsx(EllipsisVerticalIcon, { className: "size-4" }) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsxs(DropdownMenuItem, { onClick: () => {
|
|
38
38
|
setIsEditOpen(true);
|
|
@@ -41,7 +41,7 @@ export const Timeline = ({ data, setIsEditOpen, setIsDeleteOpen, setSelectedNote
|
|
|
41
41
|
setIsDeleteOpen(true);
|
|
42
42
|
setSelectedNote(history);
|
|
43
43
|
}, className: "flex cursor-pointer items-center gap-2 text-red-600", children: [_jsx(Trash, { className: "size-4" }), " ", t('history.delete', 'Delete')] })] })] })) : 'modificationId' in history.data ? (_jsx(ModifyHistoryInfo, { modificationId: history.data.modificationId })) : ('from' in history.data &&
|
|
44
|
-
'to' in history.data && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(OrderStateBadge, { state: history.data.from }), _jsx(ArrowRightLeft, { className: "text-muted-foreground
|
|
44
|
+
'to' in history.data && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(OrderStateBadge, { state: history.data.from }), _jsx(ArrowRightLeft, { className: "size-4 text-muted-foreground" }), _jsx(OrderStateBadge, { state: history.data.to })] })))] })] }) }), _jsx(TimelineDot, { status: "done", className: "bg-primary" }), _jsx(TimelineLine, { done: true, className: "bg-muted" }), _jsx(TimelineContent, { className: "relative mt-2", children: _jsxs("div", { className: "rounded-md border bg-muted/30 p-3", children: [_jsxs("div", { className: "mb-1 flex items-center gap-2", children: [entryIcon, _jsx("span", { className: "font-medium", children: t(`history.entryType.${history.type}`, history.type.replace(/_/g, ' ')) })] }), isNote && history.data?.note && (_jsx("div", { className: "mt-2 rounded-md bg-background p-3 text-sm whitespace-pre-wrap", children: history.data.note })), 'paymentId' in history.data && (_jsxs("div", { className: "mt-2 flex items-center gap-2 text-sm", children: [_jsx(CreditCard, { className: "size-4 text-purple-500" }), _jsx("span", { className: "font-medium", children: "Payment ID:" }), _jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-xs", children: history.data.paymentId })] })), 'fulfillmentId' in history.data && (_jsxs("div", { className: "mt-2 flex items-center gap-2 text-sm", children: [_jsx(Package, { className: "size-4 text-green-500" }), _jsx("span", { className: "font-medium", children: "Fulfillment ID:" }), _jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-xs", children: history.data.fulfillmentId })] })), 'modificationId' in history.data && (_jsx("div", { className: "mt-2 rounded-md bg-background p-3 text-sm whitespace-pre-wrap", children: modificationNote })), 'reason' in history.data && (_jsxs("div", { children: [_jsx("div", { className: "mt-2 rounded-md bg-background p-3 text-sm whitespace-pre-wrap", children: history.data.reason }), 'lines' in history.data && (_jsx("ul", { className: "mt-2 list-disc pl-5", children: history.data.lines
|
|
45
45
|
.map((l) => {
|
|
46
46
|
const line = order?.lines.find((line) => line.id === l.orderLineId);
|
|
47
47
|
if (!line)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useTranslation, Button, Label, Popover, PopoverContent, PopoverTrigger, useServer, } from '@deenruv/react-ui-devkit';
|
|
3
3
|
import { motion } from 'framer-motion';
|
|
4
|
-
import { NavLink } from 'react-router
|
|
4
|
+
import { NavLink } from 'react-router';
|
|
5
5
|
export const ActiveAdmins = () => {
|
|
6
6
|
const { t } = useTranslation('common');
|
|
7
7
|
const activeClients = useServer((p) => p.activeClients);
|
|
@@ -20,5 +20,5 @@ export const ActiveAdmins = () => {
|
|
|
20
20
|
else
|
|
21
21
|
return t('awesomeMenu.above5MinAgo');
|
|
22
22
|
};
|
|
23
|
-
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "sm", className: "h-10", children: t('awesomeMenu.activeAdministratorsValue', { value: activeClients.length }) }) }), _jsx(PopoverContent, { className: "mr-4", children: _jsxs("div", { className: "flex flex-col gap-4 rounded-md", children: [_jsx(Label, { className: "select-none", children: t('awesomeMenu.activeAdministrators') }), activeClients.length ? (activeClients.map((client) => (_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "flex w-full flex-col", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-sm font-bold", children: [client.firstName, " ", client.lastName, " ", client.me && '(me)'] }), _jsx(motion.div, { animate: { scale: [1, 1.2, 1] }, transition: { duration: 1.5, repeat: Infinity }, className: "size-2 rounded-full bg-green-500" })] }), _jsx("span", { className: "text-muted-foreground
|
|
23
|
+
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "sm", className: "h-10", children: t('awesomeMenu.activeAdministratorsValue', { value: activeClients.length }) }) }), _jsx(PopoverContent, { className: "mr-4", children: _jsxs("div", { className: "flex flex-col gap-4 rounded-md", children: [_jsx(Label, { className: "select-none", children: t('awesomeMenu.activeAdministrators') }), activeClients.length ? (activeClients.map((client) => (_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "flex w-full flex-col", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-sm font-bold", children: [client.firstName, " ", client.lastName, " ", client.me && '(me)'] }), _jsx(motion.div, { animate: { scale: [1, 1.2, 1] }, transition: { duration: 1.5, repeat: Infinity }, className: "size-2 rounded-full bg-green-500" })] }), _jsx("span", { className: "text-sm text-muted-foreground", children: formatTimeAgo(client.lastActive) }), !client.me && (_jsx(NavLink, { to: client.location, className: "text-sm text-muted-foreground", viewTransition: true, children: client.location.replace(window.location.origin, '') }))] }) }, client.id)))) : (_jsx("div", { children: _jsx("span", { className: "text-sm text-muted-foreground", children: t('awesomeMenu.noActiveAdministrators') }) }))] }) })] }));
|
|
24
24
|
};
|
|
@@ -16,5 +16,5 @@ export function ChannelSwitcher({ className }) {
|
|
|
16
16
|
if (!channels || channels.length === 0) {
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
|
-
return (_jsx("div", { className: className, children: _jsxs(Select, { defaultValue: selectedChannel?.id, onValueChange: onChannelChange, value: selectedChannel?.id, children: [_jsx(SelectTrigger, { className: cn('flex items-center gap-2 [&>span]:line-clamp-1 [&>span]:flex [&>span]:w-full [&>span]:items-center [&>span]:gap-1 [&>span]:truncate
|
|
19
|
+
return (_jsx("div", { className: className, children: _jsxs(Select, { defaultValue: selectedChannel?.id, onValueChange: onChannelChange, value: selectedChannel?.id, children: [_jsx(SelectTrigger, { className: cn('flex items-center gap-2 [&_svg]:h-4 [&_svg]:w-4 [&_svg]:shrink-0 [&>span]:line-clamp-1 [&>span]:flex [&>span]:w-full [&>span]:items-center [&>span]:gap-1 [&>span]:truncate'), "aria-label": "Select an channel", children: _jsx(SelectValue, { children: _jsx("span", { className: "ml-2", children: getChannelLabel(channels.find((account) => account.id === selectedChannel?.id)?.code) }) }) }), _jsx(SelectContent, { children: channels.map((channel) => (_jsx(SelectItem, { value: channel.id, children: _jsx("div", { className: "flex items-center gap-3 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-foreground", children: getChannelLabel(channel.code) }) }, channel.code))) })] }) }));
|
|
20
20
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { NavLink, useLocation } from 'react-router
|
|
2
|
+
import { NavLink, useLocation } from 'react-router';
|
|
3
3
|
import React, { useMemo } from 'react';
|
|
4
4
|
import { cn, buttonVariants, Routes, usePluginStore, Tooltip, TooltipContent, TooltipTrigger, useServer, Accordion, AccordionItem, AccordionTrigger, AccordionContent, useNotifications, useTranslation, capitalizeFirstLetter, } from '@deenruv/react-ui-devkit';
|
|
5
5
|
import { BarChart, Barcode, Store, ShoppingCart, Images, Folder, Globe2, Tag, UserCog, Users, UserRoundSearch, MapPin, Flag, Coins, Globe, Percent, CreditCard, Truck, Cog, UsersRound, Server, ScanBarcode, } from 'lucide-react';
|
|
@@ -261,10 +261,10 @@ export function Navigation({ isCollapsed }) {
|
|
|
261
261
|
const defaultAccordionOpenValue = ['shop-group', 'assortment-group'];
|
|
262
262
|
if (!loaded)
|
|
263
263
|
return null;
|
|
264
|
-
return (_jsx("div", { className: "relative overflow-y-auto", children: _jsx("div", { "data-collapsed": isCollapsed, className: "group flex h-[calc(100%-70px)] flex-col gap-4 pb-2 data-[collapsed=true]:py-2 lg:h-[calc(100%-80px)]", children: _jsx(Accordion, { type: "multiple", className: "w-full", defaultValue: defaultAccordionOpenValue, value: isCollapsed ? permittedNavigationGroups.map((g) => g.id) : undefined, children: permittedNavigationGroups.map((group) => (_jsx(AccordionItem, { value: group.id, children: _jsxs(React.Fragment, { children: [!isCollapsed && (_jsx(AccordionTrigger, { className: cn('flex items-center justify-between pr-3 hover:no-underline'), children: _jsxs("div", { className: "flex items-center gap-2 px-6", children: [_jsx("h4", { className: "text-xs font-bold uppercase hover:underline", children: group.label }), getNavigationNotification(group.id), viewMarkers ? (_jsx("p", { className: "text-muted-foreground dark:text-muted-foreground
|
|
264
|
+
return (_jsx("div", { className: "relative overflow-y-auto", children: _jsx("div", { "data-collapsed": isCollapsed, className: "group flex h-[calc(100%-70px)] flex-col gap-4 pb-2 data-[collapsed=true]:py-2 lg:h-[calc(100%-80px)]", children: _jsx(Accordion, { type: "multiple", className: "w-full", defaultValue: defaultAccordionOpenValue, value: isCollapsed ? permittedNavigationGroups.map((g) => g.id) : undefined, children: permittedNavigationGroups.map((group) => (_jsx(AccordionItem, { value: group.id, children: _jsxs(React.Fragment, { children: [!isCollapsed && (_jsx(AccordionTrigger, { className: cn('flex items-center justify-between pr-3 hover:no-underline'), children: _jsxs("div", { className: "flex items-center gap-2 px-6", children: [_jsx("h4", { className: "text-xs font-bold uppercase hover:underline", children: group.label }), getNavigationNotification(group.id), viewMarkers ? (_jsx("p", { className: "text-xs font-semibold text-muted-foreground lowercase dark:text-muted-foreground", children: group.id })) : null] }) })), _jsx(AccordionContent, { className: cn(isCollapsed ? 'py-2' : 'pb-4'), children: _jsx("nav", { id: group.id, className: "grid gap-1 px-2 text-muted-foreground group-[[data-collapsed=true]]:justify-center group-[[data-collapsed=true]]:px-2", children: group.links.map((link, index) => {
|
|
265
265
|
const notifications = getNavigationNotification(link.id);
|
|
266
266
|
return (_jsx(React.Fragment, { children: isCollapsed ? (_jsxs(Tooltip, { delayDuration: 0, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("div", { children: _jsx(NavLink, { to: link.href, viewTransition: true, children: _jsxs("div", { className: cn(buttonVariants({ variant: 'navigation-link', size: 'icon' }), 'h-9 w-9', location.pathname === link.href &&
|
|
267
|
-
'bg-muted hover:bg-muted hover:text-muted-foreground dark:bg-muted dark:hover:bg-muted
|
|
268
|
-
'bg-muted hover:bg-muted hover:text-muted-foreground dark:bg-muted dark:hover:bg-muted
|
|
267
|
+
'bg-muted opacity-100 hover:bg-muted hover:text-muted-foreground dark:bg-muted dark:hover:bg-muted'), children: [_jsx(link.icon, { className: "size-6" }), _jsx("span", { className: "sr-only", children: link.title })] }) }) }) }), _jsxs(TooltipContent, { side: "right", className: "relative flex items-center gap-4", children: [viewMarkers ? (_jsx("div", { className: "text-xs font-semibold text-muted-foreground lowercase dark:text-muted-foreground", children: link.id })) : null, capitalizeFirstLetter(link.title), notifications] })] }, index)) : (_jsx(NavLink, { to: link.href, viewTransition: true, children: _jsxs("div", { id: link.id, className: cn('relative flex items-center justify-start rounded-md px-4 py-2 capitalize', location.pathname === link.href &&
|
|
268
|
+
'bg-muted font-semibold opacity-100 hover:bg-muted hover:text-muted-foreground dark:bg-muted dark:hover:bg-muted'), children: [viewMarkers ? (_jsx("div", { className: "absolute top-1/2 right-2 -translate-y-1/2 text-xs font-semibold text-muted-foreground lowercase dark:text-muted-foreground", children: link.id })) : null, _jsx(link.icon, { className: "mr-2 size-4" }), capitalizeFirstLetter(link.title), notifications] }) })) }, link.id));
|
|
269
269
|
}) }) })] }, group.id) }))) }) }) }));
|
|
270
270
|
}
|
|
@@ -2,11 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { Permission } from '@deenruv/admin-types';
|
|
3
3
|
import { capitalizeFirstLetter, cn, Routes, Separator, useServer, useTranslation } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { Puzzle } from 'lucide-react';
|
|
5
|
-
import { NavLink } from 'react-router
|
|
5
|
+
import { NavLink } from 'react-router';
|
|
6
6
|
export const NavigationFooter = ({ isCollapsed }) => {
|
|
7
7
|
const { t } = useTranslation('common');
|
|
8
8
|
const userPermissions = useServer((p) => p.userPermissions);
|
|
9
9
|
const isPermittedToExtensions = userPermissions.includes(Permission.ReadSettings);
|
|
10
|
-
return (_jsxs("div", { className: "
|
|
11
|
-
'bg-muted hover:bg-muted hover:text-muted-foreground dark:bg-muted dark:hover:bg-muted
|
|
10
|
+
return (_jsxs("div", { className: "flex w-full flex-col gap-2 bg-secondary py-2 text-xs shadow-2xl select-none", children: [isPermittedToExtensions && !isCollapsed && (_jsxs(_Fragment, { children: [_jsx("div", { children: _jsx(NavLink, { to: Routes.extensions, viewTransition: true, children: _jsxs("div", { className: cn('relative flex items-center justify-center rounded-md px-4 capitalize', location.pathname === Routes.extensions &&
|
|
11
|
+
'bg-muted font-semibold opacity-100 hover:bg-muted hover:text-muted-foreground dark:bg-muted dark:hover:bg-muted'), children: [_jsx(Puzzle, { className: "mr-2 size-4" }), capitalizeFirstLetter(t('menu.extensions'))] }) }) }), _jsx(Separator, {})] })), _jsxs("div", { className: "flex items-center justify-center gap-1", children: [!isCollapsed && _jsx("p", { className: "uppercase", children: "Deenruv" }), _jsxs("span", { children: [!isCollapsed ? 'ver. ' : 'v. ', window.__DEENRUV_SETTINGS__.appVersion] })] })] }));
|
|
12
12
|
};
|
|
@@ -86,5 +86,5 @@ export const Notifications = () => {
|
|
|
86
86
|
prevJobQueuesRef.current = [...jobQueues];
|
|
87
87
|
}
|
|
88
88
|
}, [jobQueues, status]);
|
|
89
|
-
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "icon", className: "relative size-10", children: [_jsx(Bell, { className: "size-4" }), hasUnread && (_jsx("span", { className: "absolute
|
|
89
|
+
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "icon", className: "relative size-10", children: [_jsx(Bell, { className: "size-4" }), hasUnread && (_jsx("span", { className: "absolute top-1.5 right-1.5 size-2 rounded-full bg-red-500", children: _jsx("span", { className: "absolute inset-0 animate-ping rounded-full bg-red-400 opacity-75" }) })), _jsx("span", { className: "sr-only", children: t('notificationsBox.toggleNotifications') })] }) }), _jsx(PopoverContent, { className: "z-[2138] w-md p-0", align: "end", children: _jsx(Tabs, { defaultValue: "ALL", className: "w-full", children: _jsxs(Card, { className: "w-full border-0 shadow-none", children: [_jsxs(CardHeader, { className: cn('flex w-full flex-col items-start justify-start gap-2 bg-muted/30 p-0', components.length === 0 && 'pb-3'), children: [_jsxs("div", { className: "flex h-full w-full flex-1 items-center justify-between px-4 pt-3", children: [_jsxs("div", { className: "flex flex-col", children: [_jsx(CardTitle, { className: "text-base", children: t('notificationsBox.notifications') }), _jsx(CardDescription, { className: "mt-1 text-xs", children: t('notificationsBox.recentNotifications') })] }), notifications.length > 0 && (_jsxs(Button, { variant: "ghost", size: "sm", className: "h-8 text-xs", onClick: clearAllNotifications, children: [_jsx(Trash2, { className: "mr-1 size-3" }), t('notificationsBox.clearAll')] }))] }), components.length !== 0 && (_jsxs(TabsList, { className: "m-0 w-full rounded-none", children: [_jsx(TabsTrigger, { value: "ALL", className: "w-full rounded-none text-left", children: t('notificationsBox.all') }), cyclingNotifications.map((notification) => (_jsx(TabsTrigger, { value: notification.id, className: "w-full rounded-none text-left", children: notification.id }, notification.id)))] }))] }), _jsxs(CardContent, { className: "max-h-[400px] overflow-auto p-0", children: [_jsx(TabsContent, { value: "ALL", className: "mt-0", children: notifications.length > 0 ? (_jsx("div", { className: "divide-y", children: notifications.map((notification) => (_jsxs("div", { className: `flex items-start gap-3 p-4 transition-colors ${notification.read ? 'bg-background' : 'bg-muted/20'}`, children: [_jsx("div", { className: "mt-0.5", children: notification.icon }), _jsxs("div", { className: "flex-1 space-y-1", children: [_jsx("p", { className: "text-sm leading-none font-medium", children: notification.title }), _jsx("p", { className: "text-xs text-muted-foreground", children: notification.description }), _jsxs("div", { className: "flex items-center pt-1", children: [_jsx(Clock, { className: "mr-1 size-3 text-muted-foreground" }), _jsx("span", { className: "text-xs text-muted-foreground", children: notification.time })] })] })] }, notification.id))) })) : (_jsxs("div", { className: "flex flex-col items-center justify-center px-4 py-8 text-center", children: [_jsx("div", { className: "mb-3 rounded-full bg-muted p-3", children: _jsx(Bell, { className: "size-6 text-muted-foreground" }) }), _jsx("h3", { className: "text-sm font-medium", children: t('notificationsBox.emptyStateMessage') }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t('notificationsBox.emptyStateDescription') })] })) }), components.map((notification) => (_jsx(TabsContent, { value: notification.id, children: notification.component }, notification.id)))] }), hasUnread && (_jsx(CardFooter, { className: "flex items-center justify-end p-4", children: _jsxs(Button, { variant: "ghost", size: "sm", className: "h-8 text-xs", onClick: markAllAsRead, children: [_jsx(Check, { className: "mr-1 size-3" }), t('notificationsBox.markAllAsRead')] }) }))] }) }) })] }));
|
|
90
90
|
};
|
|
@@ -4,7 +4,7 @@ import { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbSeparator, Button
|
|
|
4
4
|
import { GripVertical, LogOutIcon, MenuIcon, Moon, Slash, Sun, SunMoon, RotateCwSquare, SearchIcon, } from 'lucide-react';
|
|
5
5
|
import * as ResizablePrimitive from 'react-resizable-panels';
|
|
6
6
|
import { Navigation } from './Navigation.js';
|
|
7
|
-
import { NavLink, useMatches, useNavigate } from 'react-router
|
|
7
|
+
import { NavLink, useMatches, useNavigate } from 'react-router';
|
|
8
8
|
import { ChannelSwitcher } from './ChannelSwitcher.js';
|
|
9
9
|
import { BrandLogo } from "../BrandLogo.js";
|
|
10
10
|
import { LanguagesDropdown } from './LanguagesDropdown.js';
|
|
@@ -12,7 +12,7 @@ import { Notifications } from './Notifications.js';
|
|
|
12
12
|
import { NavigationFooter } from "./NavigationFooter.js";
|
|
13
13
|
const ResizablePanelGroup = ({ className, ...props }) => (_jsx(ResizablePrimitive.PanelGroup, { className: cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', className), ...props }));
|
|
14
14
|
const ResizablePanel = ResizablePrimitive.Panel;
|
|
15
|
-
const ResizableHandle = ({ withHandle, className, ...props }) => (_jsx(ResizablePrimitive.PanelResizeHandle, { className: cn('
|
|
15
|
+
const ResizableHandle = ({ withHandle, className, ...props }) => (_jsx(ResizablePrimitive.PanelResizeHandle, { className: cn('relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90', className), ...props, children: withHandle && (_jsx("div", { className: "z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border", children: _jsx(GripVertical, { className: "size-2.5" }) })) }));
|
|
16
16
|
const removableCrumbs = ['draft', 'admin-ui'];
|
|
17
17
|
export const Menu = ({ children }) => {
|
|
18
18
|
const openGlobalSearch = useGlobalSearch((state) => state.open);
|
|
@@ -41,7 +41,7 @@ export const Menu = ({ children }) => {
|
|
|
41
41
|
.flatMap((p) => p.split('/'))
|
|
42
42
|
.filter(Boolean)
|
|
43
43
|
.filter((crumb) => !removableCrumbs.includes(crumb)), [matches]);
|
|
44
|
-
return (_jsx("div", { className: "
|
|
44
|
+
return (_jsx("div", { className: "w-full border-r bg-muted/40", children: _jsx("div", { className: "flex h-full max-h-screen flex-col gap-2", children: _jsx("div", { className: "flex-1", children: _jsx(TooltipProvider, { delayDuration: 100, children: _jsxs(ResizablePanelGroup, { onLayout: (sizes) => {
|
|
45
45
|
document.cookie = `react-resizable-panels:layout=${JSON.stringify(sizes)}`;
|
|
46
46
|
}, direction: "horizontal", className: "size-full", children: [_jsxs(ResizablePanel, { defaultSize: 18, collapsedSize: 4, collapsible: true, minSize: 10, maxSize: 20, onExpand: () => {
|
|
47
47
|
setIsCollapsed(false);
|
|
@@ -51,8 +51,8 @@ export const Menu = ({ children }) => {
|
|
|
51
51
|
document.cookie = `react-resizable-panels:collapsed=${JSON.stringify(true)}`;
|
|
52
52
|
}, className: cn(isCollapsed && 'min-w-[50px] transition-all duration-300 ease-in-out'), children: [_jsx("div", { className: cn('flex h-[80px] flex-col items-center justify-center gap-4 border-b'), children: _jsx("div", { className: `flex h-full items-center justify-center ${!isCollapsed && 'w-full'} cursor-pointer p-4`, onClick: () => navigate(Routes.dashboard, { viewTransition: true }), children: _jsx(BrandLogo, { isCollapsed: isCollapsed }) }) }), _jsxs("div", { className: "flex h-[calc(100vh-80px)] flex-col justify-between", children: [_jsx(Navigation, { isCollapsed: isCollapsed }), _jsx(NavigationFooter, { isCollapsed: isCollapsed })] })] }), _jsx(ResizableHandle, { withHandle: true }), _jsxs(ResizablePanel, { children: [_jsxs("div", { className: "flex h-[70px] items-center border-b p-4 lg:h-[80px] lg:px-6", children: [_jsxs("div", { className: "flex flex-col items-start justify-center", children: [_jsx(Breadcrumb, { children: _jsx(BreadcrumbList, { children: crumbs.length ? (crumbs.map((c, i) => {
|
|
53
53
|
linkPath.push(c);
|
|
54
|
-
return (_jsxs(React.Fragment, { children: [_jsx(BreadcrumbItem, { children: _jsx(NavLink, { to: buildURL(linkPath), viewTransition: true, children: _jsx("p", { className: cn('text-md text-foreground
|
|
55
|
-
})) : (_jsx(BreadcrumbItem, { children: _jsx(NavLink, { to: Routes.dashboard, viewTransition: true, children: _jsx("p", { className: "text-
|
|
54
|
+
return (_jsxs(React.Fragment, { children: [_jsx(BreadcrumbItem, { children: _jsx(NavLink, { to: buildURL(linkPath), viewTransition: true, children: _jsx("p", { className: cn('text-md font-bold text-foreground capitalize'), children: i === 0 ? t('menu.' + dashToCamelCase(c)) : c }) }) }), i !== crumbs.length - 1 && (_jsx(BreadcrumbSeparator, { children: _jsx(Slash, { className: "text-muted-foreground" }) }))] }, c));
|
|
55
|
+
})) : (_jsx(BreadcrumbItem, { children: _jsx(NavLink, { to: Routes.dashboard, viewTransition: true, children: _jsx("p", { className: "text-2xl font-bold text-foreground", children: t('dashboard') }) }) })) }) }), _jsx("div", { className: "flex items-center gap-2" })] }), _jsxs("div", { className: "flex flex-1 items-center justify-end gap-2", children: [topNavigationComponents && topNavigationComponents.length > 0 ? (_jsx("div", { className: "flex items-center gap-2", children: topNavigationComponents.map(({ component: Component }, index) => (_jsx(Component, {}, index))) })) : null, _jsx(LanguagesDropdown, {}), _jsx(ChannelSwitcher, { className: "min-w-44" }), _jsx(Button, { onClick: openGlobalSearch, variant: "outline", size: "icon", className: "relative size-10", children: _jsx(SearchIcon, { className: "size-4" }) }), _jsx(Notifications, {}), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "icon", children: [theme === 'light' ? (_jsx(Sun, { className: "size-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" })) : theme === 'dark' ? (_jsx(Moon, { className: "absolute size-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" })) : (_jsx(SunMoon, { className: "absolute size-[1.2rem] rotate-90 transition-all" })), _jsx("span", { className: "sr-only", children: t('toggleTheme') })] }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsx(DropdownMenuItem, { onClick: () => setTheme('light'), children: t('themeLight') }), _jsx(DropdownMenuItem, { onClick: () => setTheme('dark'), children: t('themeDark') }), _jsx(DropdownMenuItem, { onClick: () => setTheme('system'), children: t('themeSystem') })] })] }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "icon", children: _jsx(MenuIcon, { className: "size-4" }) }) }), _jsxs(DropdownMenuContent, { className: "z-[150] mr-6 min-w-40", children: [activeAdministrator?.emailAddress && (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuLabel, { className: "flex items-center gap-2 px-3 py-2 font-medium", children: [_jsx("div", { className: "flex size-5 items-center justify-center rounded-full bg-gray-100 text-xs text-gray-600", children: activeAdministrator.firstName.charAt(0).toUpperCase() }), _jsxs("div", { className: "truncate text-sm", children: [activeAdministrator.firstName, " ", activeAdministrator.lastName] })] }), _jsx(DropdownMenuSeparator, { className: "my-1" })] })), _jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2 text-nowrap", onSelect: rebuildSearchIndex, children: [_jsx(RotateCwSquare, { className: "size-4" }), t('rebuildSerachIndex')] }), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuGroup, { children: _jsxs(DropdownMenuSub, { children: [_jsx(DropdownMenuSubTrigger, { children: t('fastLinks') }), _jsx(DropdownMenuPortal, { children: _jsxs(DropdownMenuSubContent, { children: [_jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2 text-nowrap", onSelect: () => navigate(Routes.status, { viewTransition: true }), children: [_jsx(RotateCwSquare, { className: "size-4" }), t('systemStatus')] }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2 text-nowrap", onSelect: () => navigate(Routes.globalSettings, { viewTransition: true }), children: [_jsx(RotateCwSquare, { className: "size-4" }), t('globalSettings')] })] }) })] }) }), topNavigationActionsMenu?.length && topNavigationActionsMenu.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), topNavigationActionsMenu.map((action) => (_jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2", onSelect: action.onClick, children: [action.icon && _jsx(action.icon, { className: "size-4" }), action.label] }, action.label)))] })) : null, _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2 text-red-500", onSelect: async () => {
|
|
56
56
|
const result = await createDialog({
|
|
57
57
|
title: t('logOutConfirmation'),
|
|
58
58
|
description: t('logOutConfirmationDescription'),
|