@opexa/portal-components 0.0.152 → 0.0.153
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/client/hooks/useGlobalStore.d.ts +8 -1
- package/dist/client/hooks/useGlobalStore.js +30 -0
- package/dist/client/hooks/useMarkMessageAsReadMutation.js +25 -10
- package/dist/components/Messages/Message.js +10 -8
- package/dist/components/Messages/MessageContext.d.ts +1 -1
- package/dist/components/Messages/MessageContext.js +1 -1
- package/dist/components/Messages/MessagePopup.d.ts +1 -1
- package/dist/components/Messages/MessagePopup.js +11 -7
- package/dist/components/Messages/Messages.js +7 -3
- package/dist/components/Messages/Messages.lazy.d.ts +1 -0
- package/dist/components/Messages/Messages.lazy.js +38 -32
- package/dist/components/Messages/MessagesPopup.js +59 -13
- package/dist/ui/AlertDialog/AlertDialog.d.ts +88 -88
- package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +8 -8
- package/dist/ui/Badge/Badge.d.ts +12 -12
- package/dist/ui/Badge/badge.anatomy.d.ts +1 -1
- package/dist/ui/Badge/badge.recipe.d.ts +3 -3
- package/dist/ui/Carousel/Carousel.d.ts +45 -45
- package/dist/ui/Carousel/carousel.recipe.d.ts +5 -5
- package/dist/ui/Checkbox/Checkbox.d.ts +23 -23
- package/dist/ui/Checkbox/checkbox.recipe.d.ts +3 -3
- package/dist/ui/Clipboard/Clipboard.d.ts +18 -18
- package/dist/ui/Clipboard/clipboard.recipe.d.ts +3 -3
- package/dist/ui/Combobox/Combobox.d.ts +42 -42
- package/dist/ui/Combobox/combobox.recipe.d.ts +3 -3
- package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
- package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
- package/dist/ui/Dialog/Dialog.d.ts +88 -88
- package/dist/ui/Dialog/dialog.recipe.d.ts +8 -8
- package/dist/ui/Drawer/Drawer.d.ts +33 -33
- package/dist/ui/Drawer/drawer.recipe.d.ts +3 -3
- package/dist/ui/Menu/Menu.d.ts +90 -90
- package/dist/ui/Menu/menu.recipe.d.ts +5 -5
- package/dist/ui/PasswordInput/PasswordInput.d.ts +18 -18
- package/dist/ui/PasswordInput/passwordInput.recipe.d.ts +3 -3
- package/dist/ui/Progress/Progress.d.ts +27 -27
- package/dist/ui/Progress/progress.recipe.d.ts +3 -3
- package/dist/ui/QrCode/QrCode.d.ts +25 -25
- package/dist/ui/QrCode/qrCode.recipe.d.ts +5 -5
- package/dist/ui/Select/Select.d.ts +45 -45
- package/dist/ui/Select/select.recipe.d.ts +3 -3
- package/dist/ui/Table/Table.d.ts +21 -21
- package/dist/ui/Table/table.anatomy.d.ts +1 -1
- package/dist/ui/Table/table.recipe.d.ts +3 -3
- package/dist/ui/Tabs/Tabs.d.ts +15 -15
- package/dist/ui/Tabs/tabs.recipe.d.ts +3 -3
- package/dist/ui/Tooltip/Tooltip.d.ts +30 -30
- package/dist/ui/Tooltip/tooltip.recipe.d.ts +5 -5
- package/dist/utils/queryKeys.js +42 -128
- package/package.json +1 -1
- package/dist/components/Quests/CountdownTimer.d.ts +0 -15
- package/dist/components/Quests/CountdownTimer.js +0 -33
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuest.d.ts +0 -4
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuest.js +0 -78
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuestModal.d.ts +0 -8
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuestModal.js +0 -9
- package/dist/components/Quests/OnboardingQuest/OnboardingQuest.d.ts +0 -4
- package/dist/components/Quests/OnboardingQuest/OnboardingQuest.js +0 -4
- package/dist/components/Quests/WageringQuest/WageringQuest.d.ts +0 -4
- package/dist/components/Quests/WageringQuest/WageringQuest.js +0 -20
- package/dist/components/Quests/WageringQuest/WageringQuestModal.d.ts +0 -9
- package/dist/components/Quests/WageringQuest/WageringQuestModal.js +0 -9
- package/dist/utils/dataUrlToBlob.d.ts +0 -1
- package/dist/utils/dataUrlToBlob.js +0 -11
- package/dist/utils/resizeImageSize.d.ts +0 -2
- package/dist/utils/resizeImageSize.js +0 -11
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FavoriteGame, Game, GameSession } from '../../types';
|
|
1
|
+
import type { FavoriteGame, Game, GameSession, Message } from '../../types';
|
|
2
2
|
interface PopupStore {
|
|
3
3
|
open: boolean;
|
|
4
4
|
setOpen: (open: boolean) => void;
|
|
@@ -39,6 +39,12 @@ interface MessagesStore extends PopupStore {
|
|
|
39
39
|
tab: MessagesTab;
|
|
40
40
|
setTab: (tab: MessagesTab) => void;
|
|
41
41
|
}
|
|
42
|
+
interface MessageStore extends PopupStore {
|
|
43
|
+
open: boolean;
|
|
44
|
+
setOpen: (open: boolean) => void;
|
|
45
|
+
data: Message | null;
|
|
46
|
+
setData: (data: Message | null) => void;
|
|
47
|
+
}
|
|
42
48
|
interface DepositWithdrawalStore extends PopupStore {
|
|
43
49
|
tab: DepositWithdrawalTab;
|
|
44
50
|
setTab: (tab: DepositWithdrawalTab) => void;
|
|
@@ -56,6 +62,7 @@ interface GlobalStore {
|
|
|
56
62
|
account: PopupStore;
|
|
57
63
|
account__mobile: PopupStore;
|
|
58
64
|
messages: MessagesStore;
|
|
65
|
+
message: MessageStore;
|
|
59
66
|
sidebar: CollapsibleStore;
|
|
60
67
|
kyc: PopupStore;
|
|
61
68
|
spotBonus: PopupStore;
|
|
@@ -136,6 +136,36 @@ export const useGlobalStore = create((set) => ({
|
|
|
136
136
|
...prev.messages,
|
|
137
137
|
tab,
|
|
138
138
|
},
|
|
139
|
+
message: {
|
|
140
|
+
...prev.message,
|
|
141
|
+
'~touched': true,
|
|
142
|
+
},
|
|
143
|
+
}));
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
message: {
|
|
147
|
+
open: false,
|
|
148
|
+
setOpen(open) {
|
|
149
|
+
set((prev) => ({
|
|
150
|
+
message: {
|
|
151
|
+
...prev.message,
|
|
152
|
+
open,
|
|
153
|
+
'~touched': true,
|
|
154
|
+
},
|
|
155
|
+
messages: {
|
|
156
|
+
...prev.messages,
|
|
157
|
+
'~touched': true,
|
|
158
|
+
},
|
|
159
|
+
}));
|
|
160
|
+
},
|
|
161
|
+
'~touched': false,
|
|
162
|
+
data: null,
|
|
163
|
+
setData(data) {
|
|
164
|
+
set((prev) => ({
|
|
165
|
+
message: {
|
|
166
|
+
...prev.message,
|
|
167
|
+
data,
|
|
168
|
+
},
|
|
139
169
|
}));
|
|
140
170
|
},
|
|
141
171
|
},
|
|
@@ -18,16 +18,31 @@ export const useMarkMessageAsReadMutation = (config) => {
|
|
|
18
18
|
Authorization: `Bearer ${session.token}`,
|
|
19
19
|
},
|
|
20
20
|
});
|
|
21
|
-
queryClient.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
queryClient.setQueriesData({
|
|
22
|
+
queryKey: getMessagesQueryKey(),
|
|
23
|
+
exact: false,
|
|
24
|
+
type: 'all',
|
|
25
|
+
}, (prev) => {
|
|
26
|
+
if (!prev)
|
|
27
|
+
return prev;
|
|
28
|
+
return {
|
|
29
|
+
...prev,
|
|
30
|
+
pages: prev.pages.map((page) => ({
|
|
31
|
+
...page,
|
|
32
|
+
edges: page.edges.map((edge) => {
|
|
33
|
+
if (edge.node.id === id) {
|
|
34
|
+
return {
|
|
35
|
+
...edge,
|
|
36
|
+
node: {
|
|
37
|
+
...edge.node,
|
|
38
|
+
markedAsRead: true,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return edge;
|
|
43
|
+
}),
|
|
44
|
+
})),
|
|
45
|
+
};
|
|
31
46
|
});
|
|
32
47
|
queryClient.setQueryData(getUnreadMessagesCountQueryKey(), (prev) => {
|
|
33
48
|
return prev && prev > 0 ? prev - 1 : 0;
|
|
@@ -7,8 +7,12 @@ import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
|
7
7
|
import { useLocaleInfo } from '../../client/hooks/useLocaleInfo.js';
|
|
8
8
|
import { useMarkMessageAsReadMutation } from '../../client/hooks/useMarkMessageAsReadMutation.js';
|
|
9
9
|
import { useMessageContext } from './MessageContext.js';
|
|
10
|
-
import {
|
|
10
|
+
import { MessageIcon } from './MessageIcon.js';
|
|
11
|
+
import { useMessagesPropsContext } from './MessagesContext.js';
|
|
12
|
+
import { normalizeActionUrl } from './utils.js';
|
|
11
13
|
export function Message() {
|
|
14
|
+
const messagesProps = useMessagesPropsContext();
|
|
15
|
+
const transactionsPageUrl = messagesProps.transactionsPageUrl ?? '/transactions';
|
|
12
16
|
const message = useMessageContext();
|
|
13
17
|
const localeInfo = useLocaleInfo();
|
|
14
18
|
const globalStore = useGlobalStore(useShallow((ctx) => ({
|
|
@@ -16,7 +20,6 @@ export function Message() {
|
|
|
16
20
|
messages: ctx.messages,
|
|
17
21
|
})));
|
|
18
22
|
const markMessageAsReadMutation = useMarkMessageAsReadMutation();
|
|
19
|
-
const Icon = getMessageIcon(message.icon);
|
|
20
23
|
const handleViewMessage = async () => {
|
|
21
24
|
globalStore.message.setData(message);
|
|
22
25
|
globalStore.message.setOpen(true);
|
|
@@ -24,12 +27,11 @@ export function Message() {
|
|
|
24
27
|
if (!message.markedAsRead)
|
|
25
28
|
markMessageAsReadMutation.mutate(message.id);
|
|
26
29
|
};
|
|
27
|
-
const handleActionClick = (e) => {
|
|
28
|
-
e.stopPropagation();
|
|
29
|
-
globalStore.messages.setOpen(false);
|
|
30
|
-
globalStore.messages.setTab('ALL');
|
|
31
|
-
};
|
|
32
30
|
return (_jsxs("div", { role: "button", tabIndex: 0, className: "border-border-secondary rounded-xs bg-bg-secondary flex h-auto flex-shrink-0 cursor-pointer flex-col border px-3.5 py-2.5", onClick: handleViewMessage, "aria-pressed": "false", children: [_jsxs("div", { className: "flex items-center space-x-2", children: [_jsx("p", { className: "text-text-tertiary-600 text-xs font-normal", children: format(new Date(message.dateTimeCreated), 'M/d/yyyy - h:mma', {
|
|
33
31
|
in: tz(localeInfo.timezone),
|
|
34
|
-
}) }), !message.markedAsRead && (_jsx("div", { className: "bg-utility-success-500 h-2.5 w-2.5 rounded-full" }))] }), _jsxs("div", { className: "
|
|
32
|
+
}) }), !message.markedAsRead && (_jsx("div", { className: "bg-utility-success-500 h-2.5 w-2.5 rounded-full" }))] }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(MessageIcon, { type: message.icon, className: "text-brand-400 size-5" }), _jsx("p", { className: "text-text-primary-brand text-sm font-semibold", children: message.title })] }), message.content && (_jsx("p", { className: "mt-2 line-clamp-3 text-wrap text-sm font-normal", dangerouslySetInnerHTML: { __html: message.content } })), message.actions.length > 0 && (_jsx("div", { className: "mt-2 flex flex-wrap items-center justify-end gap-2", children: message.actions.map((action, index) => (_jsx(Link, { className: "border-button-secondary-border text-button-secondary-fg rounded-md border px-3 py-2 text-sm", href: normalizeActionUrl(transactionsPageUrl, action.url), onClick: (e) => {
|
|
33
|
+
e.stopPropagation();
|
|
34
|
+
globalStore.messages.setOpen(false);
|
|
35
|
+
globalStore.messages.setTab('ALL');
|
|
36
|
+
}, children: action.name }, index))) }))] }));
|
|
35
37
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createContext } from '../../client/utils/createContext.js';
|
|
2
|
-
export const [
|
|
2
|
+
export const [MessageProvider, useMessageContext] = createContext();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare function MessagePopup(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import Image from 'next/image';
|
|
3
4
|
import Link from 'next/link';
|
|
4
5
|
import { useShallow } from 'zustand/shallow';
|
|
5
6
|
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
6
7
|
import { XIcon } from '../../icons/XIcon.js';
|
|
7
8
|
import { Dialog } from '../../ui/Dialog/index.js';
|
|
8
9
|
import { Portal } from '../../ui/Portal/index.js';
|
|
9
|
-
import {
|
|
10
|
-
|
|
10
|
+
import { MessageIcon } from './MessageIcon.js';
|
|
11
|
+
import { useMessagesPropsContext } from './MessagesContext.js';
|
|
12
|
+
import { normalizeActionUrl } from './utils.js';
|
|
13
|
+
export function MessagePopup() {
|
|
14
|
+
const messagesProps = useMessagesPropsContext();
|
|
15
|
+
const transactionsPageUrl = messagesProps.transactionsPageUrl ?? '/transactions';
|
|
11
16
|
const globalStore = useGlobalStore(useShallow((ctx) => ({ message: ctx.message })));
|
|
12
|
-
const Icon = getMessageIcon(globalStore.message.data?.icon ?? 'MESSAGE');
|
|
13
17
|
return (_jsx(Dialog.Root, { lazyMount: true, unmountOnExit: true, open: globalStore.message.open, onOpenChange: ({ open }) => {
|
|
14
18
|
globalStore.message.setOpen(open);
|
|
15
|
-
}, closeOnEscape: false, closeOnInteractOutside: false, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+1)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+2)] flex items-center justify-center", children: _jsxs(Dialog.Content, { className: "min-h-auto mx-auto min-w-[21.438rem] max-w-[21.438rem] rounded-xl px-xl pb-0 pt-5 shadow-xl", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs("div", { className: "pb-6", children: [_jsx("div", { className: "bg-bg-brand-secondary mx-auto w-fit rounded-full p-3", children: _jsx(
|
|
16
|
-
__html: globalStore.message.data
|
|
17
|
-
} })] }), globalStore.message.data?.actions.length ? (_jsx("div", { className: "flex flex-col space-y-2 px-4 pb-8 pt-6 text-center", children: globalStore.message.data.actions.map((action, index) => (_jsx(Link, { className: "bg-button-primary-bg rounded-xs text-button-primary-fg w-full px-4 py-2.5 text-base font-semibold", href: action.url, onClick: () => {
|
|
19
|
+
}, closeOnEscape: false, closeOnInteractOutside: false, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+1)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+2)] flex items-center justify-center", children: _jsxs(Dialog.Content, { className: "min-h-auto mx-auto min-w-[21.438rem] max-w-[21.438rem] rounded-xl px-xl pb-0 pt-5 shadow-xl", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs("div", { className: "pb-6", children: [_jsx("div", { className: "bg-bg-brand-secondary mx-auto w-fit rounded-full p-3", children: _jsx(MessageIcon, { type: globalStore.message.data?.icon ?? 'INFO', className: "text-text-brand size-6" }) }), _jsx("p", { className: "text-text-primary-brand mt-lg text-center text-lg font-semibold leading-tight", children: globalStore.message.data?.title }), globalStore.message.data?.content && (_jsx("div", { className: "text-shadow-text-secondary-700 mt-xs text-center text-sm font-normal leading-tight", dangerouslySetInnerHTML: {
|
|
20
|
+
__html: globalStore.message.data.content,
|
|
21
|
+
} })), globalStore.message.data?.image && (_jsx(Image, { src: globalStore.message.data.image, alt: "", width: 400, height: 400, loading: "lazy", unoptimized: true, className: "mt-5 h-auto w-full" }))] }), globalStore.message.data?.actions.length ? (_jsx("div", { className: "flex flex-col space-y-2 px-4 pb-8 pt-6 text-center", children: globalStore.message.data.actions.map((action, index) => (_jsx(Link, { className: "bg-button-primary-bg rounded-xs text-button-primary-fg w-full px-4 py-2.5 text-base font-semibold", href: normalizeActionUrl(transactionsPageUrl, action.url), onClick: () => {
|
|
18
22
|
globalStore.message.setOpen(false);
|
|
19
23
|
}, children: action.name }, index))) })) : null] }) })] }) }));
|
|
20
|
-
}
|
|
24
|
+
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import dynamic from 'next/dynamic';
|
|
4
4
|
import { useShallow } from 'zustand/shallow';
|
|
5
5
|
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
6
|
-
import {
|
|
6
|
+
import { MessagesPropsProvider } from './MessagesContext.js';
|
|
7
7
|
const Component = dynamic(() => import('./Messages.lazy.js').then((mod) => mod.Messages), {
|
|
8
8
|
ssr: false,
|
|
9
9
|
loading: () => null,
|
|
10
10
|
});
|
|
11
|
+
const MessagesPopup = dynamic(() => import('./MessagesPopup.js').then((mod) => mod.MessagesPopup), {
|
|
12
|
+
ssr: false,
|
|
13
|
+
loading: () => null,
|
|
14
|
+
});
|
|
11
15
|
export function Messages(props) {
|
|
12
16
|
const touched = useGlobalStore(useShallow((ctx) => ctx.messages['~touched']));
|
|
13
|
-
return (_jsxs(
|
|
17
|
+
return (_jsxs(MessagesPropsProvider, { value: props, children: [touched && _jsx(Component, { ...props }), _jsx(MessagesPopup, {})] }));
|
|
14
18
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { tz } from '@date-fns/tz';
|
|
4
4
|
import { format } from 'date-fns';
|
|
5
5
|
import Image from 'next/image';
|
|
@@ -7,7 +7,6 @@ import Link from 'next/link';
|
|
|
7
7
|
import { twMerge } from 'tailwind-merge';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { useShallow } from 'zustand/shallow';
|
|
10
|
-
import { useDisclosure } from '../../client/hooks/useDisclosure.js';
|
|
11
10
|
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
12
11
|
import { useLocaleInfo } from '../../client/hooks/useLocaleInfo.js';
|
|
13
12
|
import { useMarkMessageAsReadMutation } from '../../client/hooks/useMarkMessageAsReadMutation.js';
|
|
@@ -22,7 +21,7 @@ import { Portal } from '../../ui/Portal/index.js';
|
|
|
22
21
|
import { Tabs } from '../../ui/Tabs/index.js';
|
|
23
22
|
import { InfiniteScroll } from '../shared/InfiniteScroll.js';
|
|
24
23
|
import { MessageIcon } from './MessageIcon.js';
|
|
25
|
-
import { MessageProvider,
|
|
24
|
+
import { MessageProvider, useMessageContext, useMessagesPropsContext, } from './MessagesContext.js';
|
|
26
25
|
import { normalizeActionUrl } from './utils.js';
|
|
27
26
|
const TABS = ['ALL', 'UNREAD'];
|
|
28
27
|
export function Messages(props) {
|
|
@@ -48,12 +47,12 @@ export function Messages(props) {
|
|
|
48
47
|
const [mobileOffsetTop, desktopOffsetTop] = Array.isArray(props.offsetTop)
|
|
49
48
|
? props.offsetTop
|
|
50
49
|
: [props.offsetTop ?? '0px', props.offsetTop ?? '0px'];
|
|
51
|
-
return (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
return (_jsxs(_Fragment, { children: [_jsx(Drawer.Root, { open: globalStore.messages.open, onOpenChange: ({ open }) => globalStore.messages.setOpen(open), lazyMount: true, unmountOnExit: true, children: _jsx(Portal, { children: _jsx(Drawer.Positioner, { children: _jsx(Drawer.Content, { className: twMerge('flex', 'flex-col', 'border-border-secondary', 'top-[var(--offset-top-mobile)]', 'h-[calc(100%-var(--offset-top-mobile))]', 'lg:border-l', 'lg:top-[var(--offset-top-desktop)]', 'lg:h-[calc(100%-var(--offset-top-desktop))]'), style: {
|
|
51
|
+
['--offset-top-mobile']: mobileOffsetTop,
|
|
52
|
+
['--offset-top-desktop']: desktopOffsetTop,
|
|
53
|
+
}, children: _jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "flex items-end justify-between p-xl", children: [_jsx("p", { className: "text-text-primary-brand text-xl font-semibold", children: "Notifications" }), _jsx(Drawer.CloseTrigger, { className: "p-2", children: _jsx(XIcon, {}) })] }), _jsxs(Tabs.Root, { value: globalStore.messages.tab, onValueChange: (details) => globalStore.messages.setTab(z.enum(TABS).parse(details.value)), lazyMount: true, unmountOnExit: true, className: "flex grow flex-col overflow-y-auto", children: [_jsx("div", { className: "p-xl pt-0", children: _jsxs(Tabs.List, { className: "w-full", children: [_jsx(Tabs.Trigger, { value: "ALL", className: "w-full", children: "All" }), _jsxs(Tabs.Trigger, { value: "UNREAD", className: "w-full", children: ["Unread", !!unreadMessagesCount && (_jsx("span", { className: "border-border-primary bg-bg-secondary ml-md rounded-full border px-2 py-0.5", children: unreadMessagesCount }))] }), _jsx(Tabs.Indicator, {})] }) }), TABS.map((tab) => (_jsxs(Tabs.Content, { value: tab, className: "scrollbar:w-2 scrollbar-track:bg-bg-primary-alt scrollbar-track:rounded-full scrollbar-thumb:bg-bg-quaternary scrollbar-thumb:rounded-full border-border-secondary grow overflow-y-auto border-t p-xl", children: [messages.length > 0 && (_jsx("div", { className: "flex flex-col space-y-3", children: messages.map((message) => (_jsx(MessageProvider, { value: message, children: _jsx(Message, {}) }, message.id))) })), _jsx(InfiniteScroll, { loader: _jsx(SpinnerIcon, { className: "mx-auto size-5" }), hasMore: !!messagesQuery.hasNextPage, loadMore: async () => {
|
|
54
|
+
await messagesQuery.fetchNextPage();
|
|
55
|
+
}, className: "mt-4" })] }, tab)))] })] }) }) }) }) }), _jsx(MessageDetails, {})] }));
|
|
57
56
|
}
|
|
58
57
|
function Message() {
|
|
59
58
|
const messagesProps = useMessagesPropsContext();
|
|
@@ -62,29 +61,36 @@ function Message() {
|
|
|
62
61
|
const localeInfo = useLocaleInfo();
|
|
63
62
|
const globalStore = useGlobalStore(useShallow((ctx) => ({
|
|
64
63
|
messages: ctx.messages,
|
|
64
|
+
message: ctx.message,
|
|
65
65
|
})));
|
|
66
|
-
const disclosure = useDisclosure({
|
|
67
|
-
onOpenChange(open) {
|
|
68
|
-
if (open) {
|
|
69
|
-
globalStore.messages.setOpen(false);
|
|
70
|
-
if (!message.markedAsRead) {
|
|
71
|
-
markMessageAsReadMutation.mutate(message.id);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
66
|
const markMessageAsReadMutation = useMarkMessageAsReadMutation();
|
|
77
|
-
return (_jsxs(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
67
|
+
return (_jsxs("button", { className: "border-border-secondary rounded-xs bg-bg-secondary flex h-auto flex-shrink-0 cursor-pointer flex-col border px-3.5 py-2.5 text-left", onClick: () => {
|
|
68
|
+
globalStore.messages.setOpen(false);
|
|
69
|
+
globalStore.message.setOpen(true);
|
|
70
|
+
globalStore.message.setData(message);
|
|
71
|
+
if (!message.markedAsRead) {
|
|
72
|
+
markMessageAsReadMutation.mutate(message.id);
|
|
73
|
+
}
|
|
74
|
+
}, children: [_jsxs("div", { className: "flex items-center space-x-2", children: [_jsx("p", { className: "text-text-tertiary-600 text-xs font-normal", children: format(new Date(message.dateTimeCreated), 'M/d/yyyy - h:mma', {
|
|
75
|
+
in: tz(localeInfo.timezone),
|
|
76
|
+
}) }), !message.markedAsRead && (_jsx("span", { className: "bg-utility-success-500 block size-2.5 rounded-full" }))] }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(MessageIcon, { type: message.icon, className: "text-brand-400 size-5" }), _jsx("h2", { className: "text-text-primary-brand text-sm font-semibold", children: message.title })] }), message.content && (_jsx("div", { className: "mt-2 line-clamp-3 text-wrap text-sm font-normal", dangerouslySetInnerHTML: { __html: message.content } })), message.actions.length > 0 && (_jsx("div", { className: "mt-2 flex flex-wrap items-center justify-end gap-2", children: message.actions.map((action, index) => (_jsx(Link, { className: "border-button-secondary-border text-button-secondary-fg rounded-md border px-3 py-2 text-sm", href: normalizeActionUrl(transactionsPageUrl, action.url), onClick: (e) => {
|
|
77
|
+
e.stopPropagation();
|
|
78
|
+
globalStore.messages.setOpen(false);
|
|
79
|
+
}, children: action.name }, index))) }))] }));
|
|
80
|
+
}
|
|
81
|
+
export function MessageDetails() {
|
|
82
|
+
const messagesProps = useMessagesPropsContext();
|
|
83
|
+
const transactionsPageUrl = messagesProps.transactionsPageUrl ?? '/transactions';
|
|
84
|
+
const globalStore = useGlobalStore(useShallow((ctx) => ({
|
|
85
|
+
message: ctx.message,
|
|
86
|
+
})));
|
|
87
|
+
const message = globalStore.message.data;
|
|
88
|
+
return (_jsx(Dialog.Root, { lazyMount: true, unmountOnExit: true, open: globalStore.message.open, onOpenChange: (details) => {
|
|
89
|
+
globalStore.message.setOpen(details.open);
|
|
90
|
+
}, closeOnEscape: false, closeOnInteractOutside: false, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+1)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+2)] flex items-center justify-center", children: _jsxs(Dialog.Content, { className: "min-h-auto mx-auto min-w-[21.438rem] max-w-[21.438rem] rounded-xl p-3xl lg:min-w-[25rem] lg:max-w-[25rem]", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsx("div", { className: "bg-bg-brand-secondary text-text-brand mx-auto flex size-12 items-center justify-center rounded-full", children: _jsx(MessageIcon, { type: message?.icon ?? 'INFO', className: "size-6" }) }), _jsx(Dialog.Title, { className: "mt-lg text-center text-lg font-semibold lg:mt-xl", children: message?.title }), message?.content && (_jsx(Dialog.Description, { className: "text-text-secondary-700 mt-xs pb-5 text-center text-sm", dangerouslySetInnerHTML: {
|
|
91
|
+
__html: message?.content,
|
|
92
|
+
} })), message?.image && (_jsx("div", { className: "mt-5 pb-5", children: _jsx(Image, { src: message?.image, alt: "", width: 400, height: 250, loading: "lazy", unoptimized: true, className: "h-auto w-full rounded-sm" }) })), message?.actions.length ? (_jsx("div", { className: "mt-3xl flex flex-col gap-2 text-center lg:mt-4xl", children: message?.actions.map((action, index) => (_jsx(Button, { asChild: true, children: _jsx(Link, { href: normalizeActionUrl(transactionsPageUrl, action.url), onClick: (e) => {
|
|
93
|
+
e.stopPropagation();
|
|
94
|
+
globalStore.message.setOpen(false);
|
|
95
|
+
}, children: action.name }) }, index))) })) : null] }) })] }) }));
|
|
90
96
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Image from 'next/image';
|
|
3
3
|
import Link from 'next/link';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useInterval } from 'usehooks-ts';
|
|
6
|
+
import { useShallow } from 'zustand/shallow';
|
|
7
|
+
import { useDisclosure } from '../../client/hooks/useDisclosure.js';
|
|
8
|
+
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
9
|
+
import { useMarkMessageAsReadMutation } from '../../client/hooks/useMarkMessageAsReadMutation.js';
|
|
4
10
|
import { useMessagesQuery } from '../../client/hooks/useMessagesQuery.js';
|
|
5
11
|
import { ChevronLeftIcon } from '../../icons/ChevronLeftIcon.js';
|
|
6
12
|
import { ChevronRightIcon } from '../../icons/ChevronRightIcon.js';
|
|
@@ -10,24 +16,64 @@ import { Carousel } from '../../ui/Carousel/index.js';
|
|
|
10
16
|
import { Dialog } from '../../ui/Dialog/index.js';
|
|
11
17
|
import { Portal } from '../../ui/Portal/index.js';
|
|
12
18
|
import { MessageIcon } from './MessageIcon.js';
|
|
19
|
+
import { useMessagesPropsContext } from './MessagesContext.js';
|
|
13
20
|
import { normalizeActionUrl } from './utils.js';
|
|
14
21
|
export function MessagesPopup() {
|
|
22
|
+
const messagesProps = useMessagesPropsContext();
|
|
23
|
+
const transactionsPageUrl = messagesProps.transactionsPageUrl ?? '/transactions';
|
|
24
|
+
const globalStore = useGlobalStore(useShallow((ctx) => ({
|
|
25
|
+
message: ctx.message,
|
|
26
|
+
messages: ctx.messages,
|
|
27
|
+
})));
|
|
28
|
+
const markMessageAsReadMutation = useMarkMessageAsReadMutation();
|
|
29
|
+
const [paused, setPaused] = useState(false);
|
|
30
|
+
useInterval(() => setPaused(false), paused ? 1000 * 30 : null);
|
|
31
|
+
const disclosure = useDisclosure({
|
|
32
|
+
onOpenChange(open) {
|
|
33
|
+
if (open) {
|
|
34
|
+
const message = messages.at(0);
|
|
35
|
+
if (!message || message.markedAsRead)
|
|
36
|
+
return;
|
|
37
|
+
markMessageAsReadMutation.mutate(message.id);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
setPaused(true);
|
|
41
|
+
setPage(1);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
});
|
|
15
45
|
const messagesQuery = useMessagesQuery({
|
|
16
|
-
first:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
46
|
+
first: 10,
|
|
47
|
+
filter: {
|
|
48
|
+
popup: {
|
|
49
|
+
equal: true,
|
|
50
|
+
},
|
|
51
|
+
markedAsRead: {
|
|
52
|
+
equal: false,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
25
55
|
}, {
|
|
26
|
-
|
|
56
|
+
enabled: !globalStore.messages.open && !globalStore.message.open && !paused,
|
|
57
|
+
refetchInterval: disclosure.open ? undefined : 10_000,
|
|
27
58
|
});
|
|
28
59
|
const messages = messagesQuery.data?.pages.flatMap((page) => page.edges.map((edge) => edge.node)) ?? [];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
60
|
+
const [page, setPage] = useState(1);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (messages.length > 0) {
|
|
63
|
+
disclosure.setOpen(true);
|
|
64
|
+
}
|
|
65
|
+
}, [disclosure, messages.length, paused]);
|
|
66
|
+
return (_jsx(Dialog.Root, { open: disclosure.open, onOpenChange: (details) => {
|
|
67
|
+
disclosure.setOpen(details.open);
|
|
68
|
+
}, lazyMount: true, unmountOnExit: true, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+1)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+2)] flex items-center justify-center", children: _jsxs(Dialog.Content, { className: "min-h-auto mx-auto min-w-[21.438rem] max-w-[21.438rem] rounded-xl p-3xl lg:min-w-[25rem] lg:max-w-[25rem]", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs(Carousel.Root, { page: page, onPageChange: (details) => {
|
|
69
|
+
setPage(details.page);
|
|
70
|
+
const message = messages.at(details.page - 1);
|
|
71
|
+
if (!message)
|
|
72
|
+
return;
|
|
73
|
+
if (message.markedAsRead)
|
|
74
|
+
return;
|
|
75
|
+
markMessageAsReadMutation.mutate(message.id);
|
|
76
|
+
}, slideCount: messages.length, allowMouseDrag: true, children: [_jsx(Carousel.ItemGroup, { children: messages.map((message, index) => (_jsxs(Carousel.Item, { index: index, className: "select-none", children: [_jsx("div", { className: "bg-bg-brand-secondary text-text-brand mx-auto flex size-12 items-center justify-center rounded-full", children: _jsx(MessageIcon, { type: message.icon, className: "size-6" }) }), _jsx("h2", { className: "mt-lg text-center text-lg font-semibold xl:mt-xl", children: message.title }), message.content && (_jsx("div", { dangerouslySetInnerHTML: { __html: message.content }, className: "text-text-secondary-700 mt-xs pb-5 text-center text-sm" })), message.image && (_jsx("div", { className: "mt-5 pb-5", children: _jsx(Image, { src: message.image, alt: "", width: 400, height: 250, loading: "lazy", unoptimized: true, className: "h-auto w-full rounded-sm" }) })), message.actions.length ? (_jsx("div", { className: "mt-3xl flex flex-col gap-2 text-center lg:mt-4xl", children: message.actions.map((action, index) => (_jsx(Button, { asChild: true, children: _jsx(Link, { href: normalizeActionUrl(transactionsPageUrl, action.url), onClick: () => {
|
|
77
|
+
disclosure.setOpen(false);
|
|
32
78
|
}, children: action.name }) }, index))) })) : null] }, message.id))) }), _jsxs(Carousel.Control, { className: "mt-5 flex items-center lg:mt-3xl", children: [_jsxs(Carousel.PrevTrigger, { className: "text-text-quarterary-500 hidden items-center gap-md font-semibold disabled:invisible lg:flex", children: [_jsx(ChevronLeftIcon, { className: "size-5" }), "Back"] }), _jsx(Carousel.IndicatorGroup, { className: "flex grow justify-center gap-xs", children: messages.map((message, index) => (_jsx(Carousel.Indicator, { index: index, className: "bg-bg-quaternary ui-current:bg-brand-400 size-2.5 rounded-full transition-all duration-150 ui-current:w-5" }, message.id))) }), _jsxs(Carousel.NextTrigger, { className: "text-text-quarterary-500 hidden items-center gap-md font-semibold disabled:invisible lg:flex", children: ["Next", _jsx(ChevronRightIcon, { className: "size-5" })] })] })] })] }) })] }) }));
|
|
33
79
|
}
|