@opexa/portal-components 0.1.23 → 0.1.25
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 +22 -0
- package/dist/client/hooks/useGlobalStore.js +108 -0
- package/dist/components/BetDepositLimit/BetDepositLimitModal.js +11 -11
- package/dist/components/BetDepositLimit/DepositLimitReached.d.ts +1 -1
- package/dist/components/BetDepositLimit/index.d.ts +1 -1
- package/dist/components/BetDepositLimit/index.js +1 -1
- package/dist/components/DepositWithdrawal/Deposit/AurixPayQRPHDeposit/AurixPayQRPHDepositContext.d.ts +2 -2
- package/dist/components/DepositWithdrawal/Deposit/AurixPayQRPHDeposit/useAurixPayQRPHDeposit.d.ts +1 -1
- package/dist/components/DepositWithdrawal/DepositWithdrawalContext.d.ts +1 -1
- package/dist/components/ResponsibleGamingLimits/ResponsibleGamingLimits.d.ts +1 -0
- package/dist/components/ResponsibleGamingLimits/ResponsibleGamingLimits.js +10 -0
- package/dist/components/ResponsibleGamingLimits/ResponsibleGamingLimits.lazy.d.ts +1 -0
- package/dist/components/ResponsibleGamingLimits/ResponsibleGamingLimits.lazy.js +117 -0
- package/dist/components/ResponsibleGamingLimits/ResponsibleGamingLimitsForm.lazy.d.ts +1 -0
- package/dist/components/ResponsibleGamingLimits/ResponsibleGamingLimitsForm.lazy.js +117 -0
- package/dist/components/ResponsibleGamingLimits/index.d.ts +1 -0
- package/dist/components/ResponsibleGamingLimits/index.js +1 -0
- package/package.json +1 -1
|
@@ -64,6 +64,19 @@ export interface HasPendingBonusStore {
|
|
|
64
64
|
shouldShowWarning: boolean;
|
|
65
65
|
setShouldShowWarning: (shouldShow: boolean) => void;
|
|
66
66
|
}
|
|
67
|
+
export type LimitType = 'bet' | 'deposit';
|
|
68
|
+
export type LimitPeriod = 'daily' | 'monthly';
|
|
69
|
+
export interface BetDepositLimitStore extends PopupStore {
|
|
70
|
+
type: LimitType;
|
|
71
|
+
setType: (type: LimitType) => void;
|
|
72
|
+
period: LimitPeriod;
|
|
73
|
+
setPeriod: (period: LimitPeriod) => void;
|
|
74
|
+
currentLimit: number;
|
|
75
|
+
setCurrentLimit: (limit: number) => void;
|
|
76
|
+
requestedLimit: number;
|
|
77
|
+
setRequestedLimit: (limit: number) => void;
|
|
78
|
+
openModal: (type: LimitType, period: LimitPeriod, currentLimit: number, requestedLimit: number) => void;
|
|
79
|
+
}
|
|
67
80
|
export interface GlobalStore {
|
|
68
81
|
signUp: PopupStore;
|
|
69
82
|
signIn: PopupStore;
|
|
@@ -89,6 +102,7 @@ export interface GlobalStore {
|
|
|
89
102
|
onboarding: OnboardingStore;
|
|
90
103
|
responsibleGamingReminder: ResponsibleGamingReminderStore;
|
|
91
104
|
pendingBonus: HasPendingBonusStore;
|
|
105
|
+
betDepositLimit: BetDepositLimitStore;
|
|
92
106
|
kycVerificationStatus: PopupStore;
|
|
93
107
|
kycAccountVerificationRequired: PopupStore;
|
|
94
108
|
bankInformationDetails: PopupStore;
|
|
@@ -123,4 +137,12 @@ export declare const useGlobalStore: import("zustand").UseBoundStore<Omit<Omit<i
|
|
|
123
137
|
} | undefined): () => void;
|
|
124
138
|
};
|
|
125
139
|
}>;
|
|
140
|
+
export declare const betDepositLimitStore: {
|
|
141
|
+
isOpen: boolean;
|
|
142
|
+
type: LimitType;
|
|
143
|
+
period: LimitPeriod;
|
|
144
|
+
currentLimit: number;
|
|
145
|
+
requestedLimit: number;
|
|
146
|
+
openModal(newType: LimitType, newPeriod: LimitPeriod, currentLimit: number, requestedLimit: number): void;
|
|
147
|
+
};
|
|
126
148
|
export {};
|
|
@@ -504,6 +504,68 @@ export const useGlobalStore = create()(devtools(subscribeWithSelector((set) => (
|
|
|
504
504
|
})),
|
|
505
505
|
'~touched': false,
|
|
506
506
|
},
|
|
507
|
+
betDepositLimit: {
|
|
508
|
+
open: false,
|
|
509
|
+
setOpen(open) {
|
|
510
|
+
set((prev) => ({
|
|
511
|
+
betDepositLimit: {
|
|
512
|
+
...prev.betDepositLimit,
|
|
513
|
+
open,
|
|
514
|
+
'~touched': true,
|
|
515
|
+
},
|
|
516
|
+
}));
|
|
517
|
+
},
|
|
518
|
+
'~touched': false,
|
|
519
|
+
type: 'bet',
|
|
520
|
+
setType(type) {
|
|
521
|
+
set((prev) => ({
|
|
522
|
+
betDepositLimit: {
|
|
523
|
+
...prev.betDepositLimit,
|
|
524
|
+
type,
|
|
525
|
+
},
|
|
526
|
+
}));
|
|
527
|
+
},
|
|
528
|
+
period: 'daily',
|
|
529
|
+
setPeriod(period) {
|
|
530
|
+
set((prev) => ({
|
|
531
|
+
betDepositLimit: {
|
|
532
|
+
...prev.betDepositLimit,
|
|
533
|
+
period,
|
|
534
|
+
},
|
|
535
|
+
}));
|
|
536
|
+
},
|
|
537
|
+
currentLimit: 0,
|
|
538
|
+
setCurrentLimit(currentLimit) {
|
|
539
|
+
set((prev) => ({
|
|
540
|
+
betDepositLimit: {
|
|
541
|
+
...prev.betDepositLimit,
|
|
542
|
+
currentLimit,
|
|
543
|
+
},
|
|
544
|
+
}));
|
|
545
|
+
},
|
|
546
|
+
requestedLimit: 0,
|
|
547
|
+
setRequestedLimit(requestedLimit) {
|
|
548
|
+
set((prev) => ({
|
|
549
|
+
betDepositLimit: {
|
|
550
|
+
...prev.betDepositLimit,
|
|
551
|
+
requestedLimit,
|
|
552
|
+
},
|
|
553
|
+
}));
|
|
554
|
+
},
|
|
555
|
+
openModal(type, period, currentLimit, requestedLimit) {
|
|
556
|
+
set((prev) => ({
|
|
557
|
+
betDepositLimit: {
|
|
558
|
+
...prev.betDepositLimit,
|
|
559
|
+
type,
|
|
560
|
+
period,
|
|
561
|
+
currentLimit,
|
|
562
|
+
requestedLimit,
|
|
563
|
+
open: true,
|
|
564
|
+
'~touched': true,
|
|
565
|
+
},
|
|
566
|
+
}));
|
|
567
|
+
},
|
|
568
|
+
},
|
|
507
569
|
isNonRegulated: false,
|
|
508
570
|
setIsNonRegulated: (isNonRegulated) => set((state) => ({
|
|
509
571
|
...state,
|
|
@@ -598,6 +660,15 @@ export const useGlobalStore = create()(devtools(subscribeWithSelector((set) => (
|
|
|
598
660
|
'~touched': false,
|
|
599
661
|
shouldShowWarning: false,
|
|
600
662
|
},
|
|
663
|
+
betDepositLimit: {
|
|
664
|
+
...state.betDepositLimit,
|
|
665
|
+
open: false,
|
|
666
|
+
'~touched': false,
|
|
667
|
+
type: 'bet',
|
|
668
|
+
period: 'daily',
|
|
669
|
+
currentLimit: 0,
|
|
670
|
+
requestedLimit: 0,
|
|
671
|
+
},
|
|
601
672
|
kycVerificationStatus: {
|
|
602
673
|
...state.kycVerificationStatus,
|
|
603
674
|
open: false,
|
|
@@ -617,3 +688,40 @@ export const useGlobalStore = create()(devtools(subscribeWithSelector((set) => (
|
|
|
617
688
|
}));
|
|
618
689
|
},
|
|
619
690
|
}))));
|
|
691
|
+
export const betDepositLimitStore = {
|
|
692
|
+
get isOpen() {
|
|
693
|
+
return useGlobalStore.getState().betDepositLimit.open;
|
|
694
|
+
},
|
|
695
|
+
set isOpen(value) {
|
|
696
|
+
useGlobalStore.getState().betDepositLimit.setOpen(value);
|
|
697
|
+
},
|
|
698
|
+
get type() {
|
|
699
|
+
return useGlobalStore.getState().betDepositLimit.type;
|
|
700
|
+
},
|
|
701
|
+
set type(value) {
|
|
702
|
+
useGlobalStore.getState().betDepositLimit.setType(value);
|
|
703
|
+
},
|
|
704
|
+
get period() {
|
|
705
|
+
return useGlobalStore.getState().betDepositLimit.period;
|
|
706
|
+
},
|
|
707
|
+
set period(value) {
|
|
708
|
+
useGlobalStore.getState().betDepositLimit.setPeriod(value);
|
|
709
|
+
},
|
|
710
|
+
get currentLimit() {
|
|
711
|
+
return useGlobalStore.getState().betDepositLimit.currentLimit;
|
|
712
|
+
},
|
|
713
|
+
set currentLimit(value) {
|
|
714
|
+
useGlobalStore.getState().betDepositLimit.setCurrentLimit(value);
|
|
715
|
+
},
|
|
716
|
+
get requestedLimit() {
|
|
717
|
+
return useGlobalStore.getState().betDepositLimit.requestedLimit;
|
|
718
|
+
},
|
|
719
|
+
set requestedLimit(value) {
|
|
720
|
+
useGlobalStore.getState().betDepositLimit.setRequestedLimit(value);
|
|
721
|
+
},
|
|
722
|
+
openModal(newType, newPeriod, currentLimit, requestedLimit) {
|
|
723
|
+
useGlobalStore
|
|
724
|
+
.getState()
|
|
725
|
+
.betDepositLimit.openModal(newType, newPeriod, currentLimit, requestedLimit);
|
|
726
|
+
},
|
|
727
|
+
};
|
|
@@ -7,16 +7,16 @@ import { XIcon } from '../../icons/XIcon.js';
|
|
|
7
7
|
import { Button } from '../../ui/Button/index.js';
|
|
8
8
|
import { Dialog } from '../../ui/Dialog/index.js';
|
|
9
9
|
import { Portal } from '../../ui/Portal/index.js';
|
|
10
|
-
import {
|
|
10
|
+
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
11
11
|
export function BetDepositLimitModal({ onConfirm }) {
|
|
12
12
|
const { enabled } = useFeatureFlag();
|
|
13
|
-
const {
|
|
14
|
-
|
|
15
|
-
type: state.type,
|
|
16
|
-
period: state.period,
|
|
17
|
-
currentLimit: state.currentLimit,
|
|
18
|
-
requestedLimit: state.requestedLimit,
|
|
19
|
-
|
|
13
|
+
const { open, type, period, currentLimit, requestedLimit, setOpen } = useGlobalStore(useShallow((state) => ({
|
|
14
|
+
open: state.betDepositLimit.open,
|
|
15
|
+
type: state.betDepositLimit.type,
|
|
16
|
+
period: state.betDepositLimit.period,
|
|
17
|
+
currentLimit: state.betDepositLimit.currentLimit,
|
|
18
|
+
requestedLimit: state.betDepositLimit.requestedLimit,
|
|
19
|
+
setOpen: state.betDepositLimit.setOpen,
|
|
20
20
|
})));
|
|
21
21
|
const isIncrease = requestedLimit > currentLimit;
|
|
22
22
|
const changeAmount = Math.abs(requestedLimit - currentLimit);
|
|
@@ -38,12 +38,12 @@ export function BetDepositLimitModal({ onConfirm }) {
|
|
|
38
38
|
return `Your ${period} ${type} limit has been lowered and is now active.`;
|
|
39
39
|
};
|
|
40
40
|
const handleConfirm = () => {
|
|
41
|
-
|
|
41
|
+
setOpen(false);
|
|
42
42
|
if (onConfirm) {
|
|
43
43
|
onConfirm();
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
|
-
return (_jsx(Dialog.Root, { open:
|
|
47
|
-
|
|
46
|
+
return (_jsx(Dialog.Root, { open: open && enabled, onOpenChange: (details) => {
|
|
47
|
+
setOpen(details.open);
|
|
48
48
|
}, closeOnInteractOutside: false, lazyMount: true, unmountOnExit: true, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+3)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+4)] flex items-center justify-center", children: _jsxs(Dialog.Content, { className: "mx-auto max-h-[90vh] min-w-[21.438rem] max-w-[21.438rem] overflow-y-auto rounded-xl p-3xl lg:min-w-[25rem] lg:max-w-[25rem]", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs("div", { className: "flex flex-col items-center", children: [_jsx("div", { className: "mx-auto flex size-12 items-center justify-center rounded-full bg-bg-brand-secondary", children: _jsx(AlertTriangleIcon, { className: "size-6 text-text-brand-700" }) }), _jsx("h2", { className: "mt-lg text-center font-semibold text-lg text-text-primary-900 xl:mt-xl", children: title }), _jsx("p", { className: "mt-xs text-center text-sm text-text-secondary-700 leading-relaxed", children: getDescription() }), _jsxs("div", { className: "mt-lg flex w-full select-none flex-col gap-y-2 rounded-xl border border-border-primary bg-bg-secondary px-5 py-4 text-sm", children: [_jsxs("div", { className: "flex justify-between py-0.5", children: [_jsx("span", { className: "text-text-tertiary-600", children: isIncrease ? 'Current limit:' : 'Previous limit:' }), _jsx("span", { className: "font-semibold text-text-primary-900", children: formatPeso(currentLimit) })] }), _jsxs("div", { className: "flex justify-between py-0.5", children: [_jsx("span", { className: "text-text-tertiary-600", children: isIncrease ? 'Requested limit:' : 'New limit:' }), _jsx("span", { className: "font-semibold text-text-primary-900", children: formatPeso(requestedLimit) })] }), _jsxs("div", { className: "flex justify-between py-0.5", children: [_jsx("span", { className: "text-text-tertiary-600", children: isIncrease ? 'Increase amount:' : 'Decrease amount:' }), _jsx("span", { className: "font-semibold text-text-primary-900", children: formatPeso(changeAmount) })] }), _jsxs("div", { className: "flex justify-between py-0.5", children: [_jsx("span", { className: "text-text-tertiary-600", children: isIncrease ? 'Status:' : 'Effective:' }), _jsx("span", { className: "font-semibold text-text-primary-900", children: isIncrease ? 'Pending Approval' : 'Immediately' })] })] }), _jsx("div", { className: "mt-3xl flex w-full flex-col gap-2 text-center lg:mt-4xl", children: _jsx(Button, { className: "w-full", onClick: handleConfirm, type: "button", children: "Confirm" }) })] })] }) })] }) }));
|
|
49
49
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const AurixPayQRPHDepositContext: (props: {
|
|
2
2
|
value: {
|
|
3
|
-
status: "idle" | "generating-qr-code" | "qr-code-generated"
|
|
3
|
+
status: "idle" | "confirmed" | "failed" | "generating-qr-code" | "qr-code-generated";
|
|
4
4
|
deposit: import("../../../../types").Deposit | null;
|
|
5
5
|
errorMessage: {
|
|
6
6
|
name: string;
|
|
@@ -13,7 +13,7 @@ export declare const AurixPayQRPHDepositContext: (props: {
|
|
|
13
13
|
} & {
|
|
14
14
|
children?: import("react").ReactNode | undefined;
|
|
15
15
|
}) => React.ReactNode, useAurixPayQRPHDepositContext: () => {
|
|
16
|
-
status: "idle" | "generating-qr-code" | "qr-code-generated"
|
|
16
|
+
status: "idle" | "confirmed" | "failed" | "generating-qr-code" | "qr-code-generated";
|
|
17
17
|
deposit: import("../../../../types").Deposit | null;
|
|
18
18
|
errorMessage: {
|
|
19
19
|
name: string;
|
package/dist/components/DepositWithdrawal/Deposit/AurixPayQRPHDeposit/useAurixPayQRPHDeposit.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface GenerateQRCodeInput {
|
|
|
5
5
|
promo?: string | null;
|
|
6
6
|
}
|
|
7
7
|
export declare function useAurixPayQRPHDeposit(): {
|
|
8
|
-
status: "idle" | "generating-qr-code" | "qr-code-generated"
|
|
8
|
+
status: "idle" | "confirmed" | "failed" | "generating-qr-code" | "qr-code-generated";
|
|
9
9
|
deposit: Deposit | null;
|
|
10
10
|
errorMessage: {
|
|
11
11
|
name: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LimitPeriod, LimitType } from '
|
|
1
|
+
import type { LimitPeriod, LimitType } from '../../client/hooks/useGlobalStore';
|
|
2
2
|
import type { DepositWithdrawalProps } from './DepositWithdrawal.lazy';
|
|
3
3
|
export interface DepositWithdrawalContextType extends DepositWithdrawalProps {
|
|
4
4
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function ResponsibleGamingLimits(props: any): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import dynamic from 'next/dynamic';
|
|
4
|
+
const Component = dynamic(() => import('./ResponsibleGamingLimitsForm.lazy.js').then((m) => m.ResponsibleGamingLimitsForm), {
|
|
5
|
+
ssr: false,
|
|
6
|
+
loading: () => null,
|
|
7
|
+
});
|
|
8
|
+
export function ResponsibleGamingLimits(props) {
|
|
9
|
+
return _jsx(Component, { ...props });
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function ResponsibleGamingLimits(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Tabs } from '../../ui/Tabs/index.js';
|
|
4
|
+
import Link from 'next/link';
|
|
5
|
+
import { useCallback, useState } from 'react';
|
|
6
|
+
import { useForm } from 'react-hook-form';
|
|
7
|
+
import { twMerge } from 'tailwind-merge';
|
|
8
|
+
import { useShallow } from 'zustand/shallow';
|
|
9
|
+
import { BetDepositLimitModal } from '@opexa/portal-components/BetDepositLimit';
|
|
10
|
+
import { RefreshCcw01Icon } from '../../icons/RefreshCcw01Icon.js';
|
|
11
|
+
import { InfoCircleIcon } from '../../icons/InfoCircleIcon.js';
|
|
12
|
+
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
13
|
+
import { Progress } from '../../ui/Progress/index.js';
|
|
14
|
+
import { Tooltip } from '../../ui/Tooltip/index.js';
|
|
15
|
+
import { Field } from '../../ui/Field/index.js';
|
|
16
|
+
import { Button } from '../../ui/Button/index.js';
|
|
17
|
+
const INITIAL_BET_LIMITS = [
|
|
18
|
+
{
|
|
19
|
+
period: 'daily',
|
|
20
|
+
label: 'Daily Bet Limit',
|
|
21
|
+
limit: 5000,
|
|
22
|
+
used: 3000,
|
|
23
|
+
resetsLabel: 'Resets daily',
|
|
24
|
+
active: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
period: 'monthly',
|
|
28
|
+
label: 'Monthly Bet Limit',
|
|
29
|
+
limit: 50000,
|
|
30
|
+
used: 0,
|
|
31
|
+
resetsLabel: 'Resets May 30, 2026',
|
|
32
|
+
active: false,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
const INITIAL_DEPOSIT_LIMITS = [
|
|
36
|
+
{
|
|
37
|
+
period: 'daily',
|
|
38
|
+
label: 'Daily Deposit Limit',
|
|
39
|
+
limit: 10000,
|
|
40
|
+
used: 0,
|
|
41
|
+
resetsLabel: 'Resets daily',
|
|
42
|
+
active: false,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
period: 'monthly',
|
|
46
|
+
label: 'Monthly Deposit Limit',
|
|
47
|
+
limit: 100000,
|
|
48
|
+
used: 0,
|
|
49
|
+
resetsLabel: 'Resets May 30, 2026',
|
|
50
|
+
active: false,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
function getNewLimitKey(tab, period) {
|
|
54
|
+
return `${tab}-${period}`;
|
|
55
|
+
}
|
|
56
|
+
function formatPeso(amount) {
|
|
57
|
+
return `₱${amount.toLocaleString('en-PH')}`;
|
|
58
|
+
}
|
|
59
|
+
function getUsedPercent(used, limit) {
|
|
60
|
+
if (limit === 0)
|
|
61
|
+
return 0;
|
|
62
|
+
return Math.min(Math.round((used / limit) * 100), 100);
|
|
63
|
+
}
|
|
64
|
+
function getProgressColor(pct) {
|
|
65
|
+
if (pct >= 80)
|
|
66
|
+
return 'bg-[#D92D20]';
|
|
67
|
+
if (pct >= 50)
|
|
68
|
+
return 'bg-[#F79009]';
|
|
69
|
+
return 'bg-[#FAC515]';
|
|
70
|
+
}
|
|
71
|
+
function tabToLimitType(tab) {
|
|
72
|
+
return tab === 'Bet' ? 'bet' : 'deposit';
|
|
73
|
+
}
|
|
74
|
+
export function ResponsibleGamingLimits() {
|
|
75
|
+
const openModal = useGlobalStore(useShallow((state) => state.betDepositLimit.openModal));
|
|
76
|
+
const form = useForm({
|
|
77
|
+
defaultValues: {},
|
|
78
|
+
});
|
|
79
|
+
const [activeTab, setActiveTab] = useState('Deposit');
|
|
80
|
+
const [betLimits, setBetLimits] = useState(INITIAL_BET_LIMITS);
|
|
81
|
+
const [depositLimits, setDepositLimits] = useState(INITIAL_DEPOSIT_LIMITS);
|
|
82
|
+
const limits = activeTab === 'Bet' ? betLimits : depositLimits;
|
|
83
|
+
const applyConfirmedLimit = useCallback(() => {
|
|
84
|
+
const { type, period, requestedLimit } = useGlobalStore.getState().betDepositLimit;
|
|
85
|
+
const updateLimits = (cards) => cards.map((card) => card.period === period ? { ...card, limit: requestedLimit } : card);
|
|
86
|
+
if (type === 'bet') {
|
|
87
|
+
setBetLimits(updateLimits);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
setDepositLimits(updateLimits);
|
|
91
|
+
}
|
|
92
|
+
}, []);
|
|
93
|
+
const saveLimit = useCallback((card, inputValue) => {
|
|
94
|
+
const key = getNewLimitKey(activeTab, card.period);
|
|
95
|
+
const parsed = parseFloat(String(inputValue).replace(/[^0-9.]/g, ''));
|
|
96
|
+
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
openModal(tabToLimitType(activeTab), card.period, card.limit, parsed);
|
|
100
|
+
form.setValue(key, '');
|
|
101
|
+
}, [activeTab, form, openModal]);
|
|
102
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "bg-bg-secondary m-5 mx-auto my-10 rounded-xl px-4 py-6 lg:px-8 lg:py-10", children: [_jsxs("div", { className: "mb-6", children: [_jsx("h1", { className: "text-text-primary-brand text-3xl font-bold lg:block", children: "Responsible Gaming" }), _jsxs("p", { className: "text-text-disabled mt-1 text-sm", children: ["Set limits for your gaming activity, including how much you can bet or deposit.", _jsx("br", { className: "hidden sm:inline" }), "These limits help you stay within the boundaries you choose."] })] }), _jsxs("div", { className: "bg-bg-primary border-border-dark mb-6 flex flex-col items-start justify-between gap-3 rounded-xl border px-4 py-4 shadow-xs sm:flex-row sm:items-center", children: [_jsxs("div", { children: [_jsx("p", { className: "text-text-primary-brand text-sm font-semibold", children: "Learn More About Responsible Gaming" }), _jsx("p", { className: "text-text-disabled mt-0.5 text-sm", children: "Find helpful tips, safety reminders, and support resources to help you stay informed and in control while playing." })] }), _jsx(Link, { href: "/responsible-gaming", className: twMerge('border-border-dark text-text-primary-brand inline-flex shrink-0 items-center justify-center gap-1.5 rounded-lg border px-4 py-2.5 text-sm font-semibold shadow-xs transition-colors'), children: "Visit Responsible Gaming" })] }), _jsx(Tabs.Root, { value: activeTab, onValueChange: (details) => setActiveTab(details.value), className: "mb-6 w-fit", children: _jsxs(Tabs.List, { children: [_jsx(Tabs.Trigger, { value: "Deposit", children: "Deposit" }), _jsx(Tabs.Trigger, { value: "Bet", children: "Bet" }), _jsx(Tabs.Indicator, {})] }) }), _jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: limits.map((card) => {
|
|
103
|
+
const pct = getUsedPercent(card.used, card.limit);
|
|
104
|
+
const key = getNewLimitKey(activeTab, card.period);
|
|
105
|
+
return (_jsxs("div", { className: "border-border-dark bg-bg-primary flex flex-col gap-4 rounded-xl border p-5 shadow-xs", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("span", { className: twMerge('inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium', card.active
|
|
106
|
+
? 'border border-[#085D3A] bg-[#053321] text-[#75E0A7]'
|
|
107
|
+
: 'border border-[#912018] bg-[#55160c] text-[#FDA29B]'), children: [_jsx("span", { className: twMerge('size-1.5 rounded-full', card.active ? 'bg-[#17B26A]' : 'bg-[#F04438]') }), card.active ? 'Active' : 'Inactive'] }), _jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-[#b0841f] bg-[#191304] px-2.5 py-1 text-xs font-medium text-[#e2aa28]", children: [_jsx(RefreshCcw01Icon, { className: "size-3" }), card.resetsLabel] })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-semibold text-text-primary-brand", children: card.label }), _jsx("p", { className: "mt-1 text-2xl font-bold text-button-primary-bg", children: formatPeso(card.limit) })] }), _jsxs("div", { children: [_jsxs("div", { className: "text-text-disabled flex items-center justify-between text-xs", children: [_jsxs("span", { children: [formatPeso(card.used), " used"] }), _jsxs("span", { children: [pct, "%"] })] }), _jsx(Progress.Root, { value: pct, max: 100, variant: "unstyled", className: "relative mt-1.5 h-2 w-full", children: _jsx(Progress.Track, { className: "bg-bg-dark h-2 w-full rounded-full", children: _jsx(Progress.Range, { className: twMerge('h-full rounded-full transition-all duration-700 ease-in-out', getProgressColor(pct)) }) }) }), _jsxs("p", { className: "text-text-disabled mt-1.5 text-xs", children: ["Remaining: ", formatPeso(card.limit - card.used)] })] }), _jsxs("div", { children: [_jsxs("div", { className: "mb-2 flex items-center gap-1 text-sm font-medium text-text-primary-brand", children: [_jsx("span", { children: "Set new limit" }), _jsxs(Tooltip.Root, { openDelay: 0, closeDelay: 100, children: [_jsx(Tooltip.Trigger, { type: "button", className: "inline-flex", "aria-label": "Limit change information", children: _jsx(InfoCircleIcon, { className: "size-4 text-text-disabled" }) }), _jsx(Tooltip.Positioner, { children: _jsxs(Tooltip.Content, { className: "max-w-64 rounded-lg bg-[#0C111D] px-2.5 py-2 text-xs font-medium text-text-primary-brand", children: [_jsx(Tooltip.Arrow, {}), "Enter a new limit amount. Limits can only be lowered immediately. Limit increases take 24 hours to apply."] }) })] })] }), _jsxs("form", { className: "flex w-full items-center gap-2", onSubmit: form.handleSubmit((values) => {
|
|
108
|
+
console.log({
|
|
109
|
+
component: 'ResponsibleGamingLimits',
|
|
110
|
+
activeTab,
|
|
111
|
+
card,
|
|
112
|
+
values,
|
|
113
|
+
});
|
|
114
|
+
saveLimit(card, values[key] ?? '');
|
|
115
|
+
}), children: [_jsxs(Field.Root, { className: "relative w-full", children: [_jsx("span", { className: "text-text-disabled absolute top-1/2 left-2 shrink-0 -translate-y-1/2 text-sm", children: "\u20B1" }), _jsx(Field.Input, { className: "pl-6", type: "number", min: 0, placeholder: "0", ...form.register(key) })] }), _jsx(Button, { size: "md", variant: "solid", colorScheme: "primary", type: "submit", className: "w-fit shrink-0", children: "Save" })] })] })] }, card.period));
|
|
116
|
+
}) })] }), _jsx(BetDepositLimitModal, { onConfirm: applyConfirmedLimit })] }));
|
|
117
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function ResponsibleGamingLimitsForm(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Tabs } from '../../ui/Tabs/index.js';
|
|
4
|
+
import Link from 'next/link';
|
|
5
|
+
import { useCallback, useState } from 'react';
|
|
6
|
+
import { useForm } from 'react-hook-form';
|
|
7
|
+
import { twMerge } from 'tailwind-merge';
|
|
8
|
+
import { useShallow } from 'zustand/shallow';
|
|
9
|
+
import { BetDepositLimitModal, } from '../BetDepositLimit/index.js';
|
|
10
|
+
import { RefreshCcw01Icon } from '../../icons/RefreshCcw01Icon.js';
|
|
11
|
+
import { InfoCircleIcon } from '../../icons/InfoCircleIcon.js';
|
|
12
|
+
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
13
|
+
import { Progress } from '../../ui/Progress/index.js';
|
|
14
|
+
import { Tooltip } from '../../ui/Tooltip/index.js';
|
|
15
|
+
import { Field } from '../../ui/Field/index.js';
|
|
16
|
+
import { Button } from '../../ui/Button/index.js';
|
|
17
|
+
const INITIAL_BET_LIMITS = [
|
|
18
|
+
{
|
|
19
|
+
period: 'daily',
|
|
20
|
+
label: 'Daily Bet Limit',
|
|
21
|
+
limit: 5000,
|
|
22
|
+
used: 3000,
|
|
23
|
+
resetsLabel: 'Resets daily',
|
|
24
|
+
active: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
period: 'monthly',
|
|
28
|
+
label: 'Monthly Bet Limit',
|
|
29
|
+
limit: 50000,
|
|
30
|
+
used: 0,
|
|
31
|
+
resetsLabel: 'Resets May 30, 2026',
|
|
32
|
+
active: false,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
const INITIAL_DEPOSIT_LIMITS = [
|
|
36
|
+
{
|
|
37
|
+
period: 'daily',
|
|
38
|
+
label: 'Daily Deposit Limit',
|
|
39
|
+
limit: 10000,
|
|
40
|
+
used: 0,
|
|
41
|
+
resetsLabel: 'Resets daily',
|
|
42
|
+
active: false,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
period: 'monthly',
|
|
46
|
+
label: 'Monthly Deposit Limit',
|
|
47
|
+
limit: 100000,
|
|
48
|
+
used: 0,
|
|
49
|
+
resetsLabel: 'Resets May 30, 2026',
|
|
50
|
+
active: false,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
function getNewLimitKey(tab, period) {
|
|
54
|
+
return `${tab}-${period}`;
|
|
55
|
+
}
|
|
56
|
+
function formatPeso(amount) {
|
|
57
|
+
return `₱${amount.toLocaleString('en-PH')}`;
|
|
58
|
+
}
|
|
59
|
+
function getUsedPercent(used, limit) {
|
|
60
|
+
if (limit === 0)
|
|
61
|
+
return 0;
|
|
62
|
+
return Math.min(Math.round((used / limit) * 100), 100);
|
|
63
|
+
}
|
|
64
|
+
function getProgressColor(pct) {
|
|
65
|
+
if (pct >= 80)
|
|
66
|
+
return 'bg-[#D92D20]';
|
|
67
|
+
if (pct >= 50)
|
|
68
|
+
return 'bg-[#F79009]';
|
|
69
|
+
return 'bg-[#FAC515]';
|
|
70
|
+
}
|
|
71
|
+
function tabToLimitType(tab) {
|
|
72
|
+
return tab === 'Bet' ? 'bet' : 'deposit';
|
|
73
|
+
}
|
|
74
|
+
export function ResponsibleGamingLimitsForm() {
|
|
75
|
+
const openModal = useGlobalStore(useShallow((state) => state.betDepositLimit.openModal));
|
|
76
|
+
const form = useForm({
|
|
77
|
+
defaultValues: {},
|
|
78
|
+
});
|
|
79
|
+
const [activeTab, setActiveTab] = useState('Deposit');
|
|
80
|
+
const [betLimits, setBetLimits] = useState(INITIAL_BET_LIMITS);
|
|
81
|
+
const [depositLimits, setDepositLimits] = useState(INITIAL_DEPOSIT_LIMITS);
|
|
82
|
+
const limits = activeTab === 'Bet' ? betLimits : depositLimits;
|
|
83
|
+
const applyConfirmedLimit = useCallback(() => {
|
|
84
|
+
const { type, period, requestedLimit } = useGlobalStore.getState().betDepositLimit;
|
|
85
|
+
const updateLimits = (cards) => cards.map((card) => card.period === period ? { ...card, limit: requestedLimit } : card);
|
|
86
|
+
if (type === 'bet') {
|
|
87
|
+
setBetLimits(updateLimits);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
setDepositLimits(updateLimits);
|
|
91
|
+
}
|
|
92
|
+
}, []);
|
|
93
|
+
const saveLimit = useCallback((card, inputValue) => {
|
|
94
|
+
const key = getNewLimitKey(activeTab, card.period);
|
|
95
|
+
const parsed = parseFloat(String(inputValue).replace(/[^0-9.]/g, ''));
|
|
96
|
+
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
openModal(tabToLimitType(activeTab), card.period, card.limit, parsed);
|
|
100
|
+
form.setValue(key, '');
|
|
101
|
+
}, [activeTab, form, openModal]);
|
|
102
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "bg-bg-secondary m-5 mx-auto my-10 rounded-xl px-4 py-6 lg:px-8 lg:py-10", children: [_jsxs("div", { className: "mb-6", children: [_jsx("h1", { className: "text-text-primary-brand text-3xl font-bold lg:block", children: "Responsible Gaming" }), _jsxs("p", { className: "text-text-disabled mt-1 text-sm", children: ["Set limits for your gaming activity, including how much you can bet or deposit.", _jsx("br", { className: "hidden sm:inline" }), "These limits help you stay within the boundaries you choose."] })] }), _jsxs("div", { className: "bg-bg-primary border-border-dark mb-6 flex flex-col items-start justify-between gap-3 rounded-xl border px-4 py-4 shadow-xs sm:flex-row sm:items-center", children: [_jsxs("div", { children: [_jsx("p", { className: "text-text-primary-brand text-sm font-semibold", children: "Learn More About Responsible Gaming" }), _jsx("p", { className: "text-text-disabled mt-0.5 text-sm", children: "Find helpful tips, safety reminders, and support resources to help you stay informed and in control while playing." })] }), _jsx(Link, { href: "/responsible-gaming", className: twMerge('border-border-dark text-text-primary-brand inline-flex shrink-0 items-center justify-center gap-1.5 rounded-lg border px-4 py-2.5 text-sm font-semibold shadow-xs transition-colors'), children: "Visit Responsible Gaming" })] }), _jsx(Tabs.Root, { value: activeTab, onValueChange: (details) => setActiveTab(details.value), className: "mb-6 w-fit", children: _jsxs(Tabs.List, { children: [_jsx(Tabs.Trigger, { value: "Deposit", children: "Deposit" }), _jsx(Tabs.Trigger, { value: "Bet", children: "Bet" }), _jsx(Tabs.Indicator, {})] }) }), _jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: limits.map((card) => {
|
|
103
|
+
const pct = getUsedPercent(card.used, card.limit);
|
|
104
|
+
const key = getNewLimitKey(activeTab, card.period);
|
|
105
|
+
return (_jsxs("div", { className: "border-border-dark bg-bg-primary flex flex-col gap-4 rounded-xl border p-5 shadow-xs", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("span", { className: twMerge('inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium', card.active
|
|
106
|
+
? 'border border-[#085D3A] bg-[#053321] text-[#75E0A7]'
|
|
107
|
+
: 'border border-[#912018] bg-[#55160c] text-[#FDA29B]'), children: [_jsx("span", { className: twMerge('size-1.5 rounded-full', card.active ? 'bg-[#17B26A]' : 'bg-[#F04438]') }), card.active ? 'Active' : 'Inactive'] }), _jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-[#b0841f] bg-[#191304] px-2.5 py-1 text-xs font-medium text-[#e2aa28]", children: [_jsx(RefreshCcw01Icon, { className: "size-3" }), card.resetsLabel] })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-semibold text-text-primary-brand", children: card.label }), _jsx("p", { className: "mt-1 text-2xl font-bold text-button-primary-bg", children: formatPeso(card.limit) })] }), _jsxs("div", { children: [_jsxs("div", { className: "text-text-disabled flex items-center justify-between text-xs", children: [_jsxs("span", { children: [formatPeso(card.used), " used"] }), _jsxs("span", { children: [pct, "%"] })] }), _jsx(Progress.Root, { value: pct, max: 100, variant: "unstyled", className: "relative mt-1.5 h-2 w-full", children: _jsx(Progress.Track, { className: "bg-bg-dark h-2 w-full rounded-full", children: _jsx(Progress.Range, { className: twMerge('h-full rounded-full transition-all duration-700 ease-in-out', getProgressColor(pct)) }) }) }), _jsxs("p", { className: "text-text-disabled mt-1.5 text-xs", children: ["Remaining: ", formatPeso(card.limit - card.used)] })] }), _jsxs("div", { children: [_jsxs("div", { className: "mb-2 flex items-center gap-1 text-sm font-medium text-text-primary-brand", children: [_jsx("span", { children: "Set new limit" }), _jsxs(Tooltip.Root, { openDelay: 0, closeDelay: 100, children: [_jsx(Tooltip.Trigger, { type: "button", className: "inline-flex", "aria-label": "Limit change information", children: _jsx(InfoCircleIcon, { className: "size-4 text-text-disabled" }) }), _jsx(Tooltip.Positioner, { children: _jsxs(Tooltip.Content, { className: "max-w-64 rounded-lg bg-[#0C111D] px-2.5 py-2 text-xs font-medium text-text-primary-brand", children: [_jsx(Tooltip.Arrow, {}), "Enter a new limit amount. Limits can only be lowered immediately. Limit increases take 24 hours to apply."] }) })] })] }), _jsxs("form", { className: "flex w-full items-center gap-2", onSubmit: form.handleSubmit((values) => {
|
|
108
|
+
console.log({
|
|
109
|
+
component: 'ResponsibleGamingLimits',
|
|
110
|
+
activeTab,
|
|
111
|
+
card,
|
|
112
|
+
values,
|
|
113
|
+
});
|
|
114
|
+
saveLimit(card, values[key] ?? '');
|
|
115
|
+
}), children: [_jsxs(Field.Root, { className: "relative w-full", children: [_jsx("span", { className: "text-text-disabled absolute top-1/2 left-2 shrink-0 -translate-y-1/2 text-sm", children: "\u20B1" }), _jsx(Field.Input, { className: "pl-6", type: "number", min: 0, placeholder: "0", ...form.register(key) })] }), _jsx(Button, { size: "md", variant: "solid", colorScheme: "primary", type: "submit", className: "w-fit shrink-0", children: "Save" })] })] })] }, card.period));
|
|
116
|
+
}) })] }), _jsx(BetDepositLimitModal, { onConfirm: applyConfirmedLimit })] }));
|
|
117
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ResponsibleGamingLimits";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ResponsibleGamingLimits.js";
|