@opexa/portal-components 0.0.116 → 0.0.118
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/components/Bonus/Bonus.client.js +1 -1
- package/dist/components/Cashback/Cashback.client.js +1 -1
- package/dist/components/CustomPromo/CustomPromo.d.ts +7 -0
- package/dist/components/CustomPromo/CustomPromo.js +11 -0
- package/dist/components/CustomPromo/index.d.ts +1 -0
- package/dist/components/CustomPromo/index.js +1 -0
- package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/OnlineBankDepositContext.d.ts +2 -2
- package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/useOnlineBankDeposit.d.ts +1 -1
- package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/QRPHDepositContext.d.ts +2 -2
- package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/useQRPHDeposit.d.ts +1 -1
- package/dist/components/Disclaimer/DisclaimerV1.js +1 -1
- package/dist/components/GameLaunch/GameLaunch.lazy.js +1 -1
- package/dist/components/GamesSearch/GamesSearch.js +1 -1
- package/dist/components/Jackpots/JackpotsCarousel/JackpotsCarouselItem.module.css +184 -184
- package/dist/components/Jackpots/JackpotsList/JackpotsListItem.module.css +184 -184
- package/dist/components/News/News.js +1 -1
- package/dist/components/Promo/Promo.client.js +1 -1
- package/dist/components/Promos/Cashback.d.ts +1 -1
- package/dist/components/Promos/Cashback.js +1 -1
- package/dist/components/Promos/CustomPromo.d.ts +7 -0
- package/dist/components/Promos/CustomPromo.js +7 -0
- package/dist/components/Promos/Promo.js +1 -1
- package/dist/components/Promos/PromosCarousel.d.ts +12 -0
- package/dist/components/Promos/PromosCarousel.js +7 -4
- package/dist/components/Promos/PromosGrid.d.ts +3 -0
- package/dist/components/Promos/PromosGrid.js +7 -4
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuest.d.ts +1 -4
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuest.js +38 -30
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuestRules.d.ts +6 -0
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuestRules.js +15 -0
- package/dist/components/Quests/OnboardingQuest/OnboardingQuest.d.ts +1 -4
- package/dist/components/Quests/OnboardingQuest/OnboardingQuest.js +27 -3
- package/dist/components/Quests/OnboardingQuest/OnboardingQuestRules.d.ts +6 -0
- package/dist/components/Quests/OnboardingQuest/OnboardingQuestRules.js +15 -0
- package/dist/components/Quests/WageringQuest/WageringQuest.d.ts +1 -4
- package/dist/components/Quests/WageringQuest/WageringQuest.js +15 -11
- package/dist/components/Quests/WageringQuest/WageringQuestRules.d.ts +7 -0
- package/dist/components/Quests/WageringQuest/WageringQuestRules.js +17 -0
- package/dist/components/Search/Search.lazy.js +1 -1
- package/dist/components/SignIn/MobileNumberSignIn.js +3 -1
- package/dist/components/SignUp/SignUpForm.js +100 -10
- package/dist/components/Tournaments/TournamentsCarousel/TournamentsCarouselItem.module.css +184 -184
- package/dist/components/Tournaments/TournamentsList/TournamentItem.module.css +184 -184
- package/dist/constants/BranchCode.d.ts +4 -0
- package/dist/constants/BranchCode.js +42 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/icons/CalendarIcon.js +1 -1
- package/dist/services/queries.js +2369 -2369
- package/dist/styles/theme.css +699 -699
- package/dist/types/index.d.ts +7 -0
- package/dist/ui/DatePicker/DatePicker.d.ts +1080 -2088
- package/dist/ui/DatePicker/datePicker.recipe.d.ts +39 -81
- package/dist/ui/DatePicker/datePicker.recipe.js +19 -0
- package/dist/ui/Select/Select.d.ts +45 -45
- package/dist/ui/Select/select.recipe.d.ts +3 -3
- package/dist/ui/Select/select.recipe.js +2 -2
- package/package.json +163 -163
- package/dist/client/hooks/index.d.ts +0 -65
- package/dist/client/hooks/index.js +0 -65
- package/dist/client/services/index.d.ts +0 -4
- package/dist/client/services/index.js +0 -4
- package/dist/client/utils/index.d.ts +0 -3
- package/dist/client/utils/index.js +0 -3
- package/dist/components/Empty.d.ts +0 -10
- package/dist/components/Empty.js +0 -7
- package/dist/components/Games/GameContext.d.ts +0 -2
- package/dist/components/Games/GameContext.js +0 -2
- package/dist/components/InfiniteScroll.d.ts +0 -10
- package/dist/components/InfiniteScroll.js +0 -25
- package/dist/components/JackpotCounter/JackpotCounter.client.d.ts +0 -2
- package/dist/components/JackpotCounter/JackpotCounter.client.js +0 -66
- package/dist/components/JackpotCounter/JackpotCounter.d.ts +0 -17
- package/dist/components/JackpotCounter/JackpotCounter.js +0 -21
- package/dist/components/JackpotCounter/JackpotCounterItem.d.ts +0 -18
- package/dist/components/JackpotCounter/JackpotCounterItem.js +0 -109
- package/dist/components/JackpotCounter/JackpotCounterItem.module.css +0 -184
- package/dist/components/JackpotCounter/index.d.ts +0 -1
- package/dist/components/JackpotCounter/index.js +0 -1
- package/dist/components/Jackpots/JackpotDesktop.d.ts +0 -1
- package/dist/components/Jackpots/JackpotDesktop.js +0 -45
- package/dist/components/Jackpots/JackpotGameProviders.d.ts +0 -5
- package/dist/components/Jackpots/JackpotGameProviders.js +0 -41
- package/dist/components/Jackpots/JackpotItemDesktop.d.ts +0 -9
- package/dist/components/Jackpots/JackpotItemDesktop.js +0 -43
- package/dist/components/Jackpots/JackpotItemMobile.d.ts +0 -9
- package/dist/components/Jackpots/JackpotItemMobile.js +0 -44
- package/dist/components/Jackpots/JackpotMobile.d.ts +0 -1
- package/dist/components/Jackpots/JackpotMobile.js +0 -46
- package/dist/components/Jackpots/JackpotRules.d.ts +0 -5
- package/dist/components/Jackpots/JackpotRules.js +0 -11
- package/dist/components/Jackpots/Jackpots.client.d.ts +0 -2
- package/dist/components/Jackpots/Jackpots.client.js +0 -29
- package/dist/components/Jackpots/JackpotsContext.d.ts +0 -4
- package/dist/components/Jackpots/JackpotsContext.js +0 -3
- package/dist/components/Jackpots/useJackpotData.d.ts +0 -14
- package/dist/components/Jackpots/useJackpotData.js +0 -93
- package/dist/components/Jackpots/useJackpotItemData.d.ts +0 -20
- package/dist/components/Jackpots/useJackpotItemData.js +0 -87
- package/dist/components/KYC/Header.d.ts +0 -1
- package/dist/components/KYC/Header.js +0 -6
- package/dist/components/KYC/Step1.d.ts +0 -1
- package/dist/components/KYC/Step1.js +0 -12
- package/dist/components/KYC/Step2.d.ts +0 -1
- package/dist/components/KYC/Step2.js +0 -12
- package/dist/components/KYC/Step3.d.ts +0 -1
- package/dist/components/KYC/Step3.js +0 -11
- package/dist/components/KYC/Step4.d.ts +0 -1
- package/dist/components/KYC/Step4.js +0 -6
- package/dist/components/Messages/MessageItem.d.ts +0 -4
- package/dist/components/Messages/MessageItem.js +0 -34
- package/dist/components/PortalProvider/WebVitals.d.ts +0 -1
- package/dist/components/PortalProvider/WebVitals.js +0 -8
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuestModal.d.ts +0 -8
- package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuestModal.js +0 -8
- package/dist/components/Quests/WageringQuest/WageringQuestModal.d.ts +0 -9
- package/dist/components/Quests/WageringQuest/WageringQuestModal.js +0 -8
- package/dist/components/TournamentCounter/TournamentCounter.client.d.ts +0 -2
- package/dist/components/TournamentCounter/TournamentCounter.client.js +0 -50
- package/dist/components/TournamentCounter/TournamentCounter.d.ts +0 -8
- package/dist/components/TournamentCounter/TournamentCounter.js +0 -21
- package/dist/components/TournamentCounter/TournamentCounterItem.d.ts +0 -8
- package/dist/components/TournamentCounter/TournamentCounterItem.js +0 -106
- package/dist/components/TournamentCounter/index.d.ts +0 -1
- package/dist/components/TournamentCounter/index.js +0 -1
- package/dist/components/Tournaments/TournamentDesktop.d.ts +0 -1
- package/dist/components/Tournaments/TournamentDesktop.js +0 -57
- package/dist/components/Tournaments/TournamentGameProviders.d.ts +0 -5
- package/dist/components/Tournaments/TournamentGameProviders.js +0 -38
- package/dist/components/Tournaments/TournamentItemDesktop.d.ts +0 -7
- package/dist/components/Tournaments/TournamentItemDesktop.js +0 -56
- package/dist/components/Tournaments/TournamentItemMobile.d.ts +0 -7
- package/dist/components/Tournaments/TournamentItemMobile.js +0 -54
- package/dist/components/Tournaments/TournamentMobile.d.ts +0 -1
- package/dist/components/Tournaments/TournamentMobile.js +0 -55
- package/dist/components/Tournaments/TournamentRules.d.ts +0 -5
- package/dist/components/Tournaments/TournamentRules.js +0 -11
- package/dist/components/Tournaments/Tournaments.client.d.ts +0 -2
- package/dist/components/Tournaments/Tournaments.client.js +0 -20
- package/dist/components/Tournaments/TournamentsContext.d.ts +0 -4
- package/dist/components/Tournaments/TournamentsContext.js +0 -3
- package/dist/components/Tournaments/useTournamentData.d.ts +0 -10
- package/dist/components/Tournaments/useTournamentData.js +0 -72
- package/dist/components/Tournaments/useTournamentItemData.d.ts +0 -16
- package/dist/components/Tournaments/useTournamentItemData.js +0 -64
- package/dist/components/index.d.ts +0 -33
- package/dist/components/index.js +0 -33
- package/dist/constants/envVars.d.ts +0 -5
- package/dist/constants/envVars.js +0 -28
- package/dist/constants/gameProviders.d.ts +0 -5
- package/dist/constants/gameProviders.js +0 -362
- package/dist/constants/gameTypes.d.ts +0 -4
- package/dist/constants/gameTypes.js +0 -64
- package/dist/constants/headerKeys.d.ts +0 -1
- package/dist/constants/headerKeys.js +0 -1
- package/dist/constants/secretQuestions.d.ts +0 -3
- package/dist/constants/secretQuestions.js +0 -24
- package/dist/constants/storageKeys.d.ts +0 -2
- package/dist/constants/storageKeys.js +0 -2
- package/dist/icons/index.d.ts +0 -65
- package/dist/icons/index.js +0 -65
- package/dist/images/hacksaw-gaming.png +0 -0
- package/dist/server/services/index.d.ts +0 -4
- package/dist/server/services/index.js +0 -4
- package/dist/server/utils/index.d.ts +0 -29
- package/dist/server/utils/index.js +0 -29
- package/dist/ui/Presence.d.ts +0 -2
- package/dist/ui/Presence.js +0 -7
- package/dist/ui/Prose.d.ts +0 -2
- package/dist/ui/Prose.js +0 -5
- package/dist/ui/index.d.ts +0 -26
- package/dist/ui/index.js +0 -26
- package/dist/utils/index.d.ts +0 -17
- package/dist/utils/index.js +0 -17
- package/dist/utils/isMobile.d.ts +0 -5
- package/dist/utils/isMobile.js +0 -9
|
@@ -3,16 +3,29 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { addDays, isEqual, startOfDay } from 'date-fns';
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
|
-
import { useCheckInDailyCheckInQuestMutation } from '../../../client/hooks/
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
6
|
+
import { useCheckInDailyCheckInQuestMutation } from '../../../client/hooks/useCheckInDailyCheckInQuestMutation.js';
|
|
7
|
+
import { useDisclosure } from '../../../client/hooks/useDisclosure.js';
|
|
8
|
+
import { useLocaleInfo } from '../../../client/hooks/useLocaleInfo.js';
|
|
9
|
+
import { toaster } from '../../../client/utils/toaster.js';
|
|
10
|
+
import { CalendarIcon } from '../../../icons/CalendarIcon.js';
|
|
11
|
+
import { CheckIcon } from '../../../icons/CheckIcon.js';
|
|
12
|
+
import { ClockStopWatchIcon } from '../../../icons/ClockStopWatchIcon.js';
|
|
13
|
+
import { InfoCircleIcon } from '../../../icons/InfoCircleIcon.js';
|
|
14
|
+
import { Badge } from '../../../ui/Badge/index.js';
|
|
15
|
+
import { Button } from '../../../ui/Button/index.js';
|
|
16
|
+
import { dataAttr } from '../../../utils/dataAttr.js';
|
|
17
|
+
import { formatNumber } from '../../../utils/formatNumber.js';
|
|
18
|
+
import { getQueryClient } from '../../../utils/getQueryClient.js';
|
|
19
|
+
import { parseDecimal } from '../../../utils/parseDecimal.js';
|
|
20
|
+
import { getAvailableQuestsQueryKey } from '../../../utils/queryKeys.js';
|
|
11
21
|
import CountdownTimer from '../CountdownTimer.js';
|
|
12
|
-
import {
|
|
13
|
-
|
|
22
|
+
import { useQuestContext } from '../QuestsContext.js';
|
|
23
|
+
import { DailyCheckInQuestRules } from './DailyCheckInQuestRules.js';
|
|
24
|
+
export function DailyCheckInQuest() {
|
|
25
|
+
const quest = useQuestContext();
|
|
14
26
|
const queryClient = getQueryClient();
|
|
15
|
-
const
|
|
27
|
+
const disclosure = useDisclosure();
|
|
28
|
+
const localeInfo = useLocaleInfo();
|
|
16
29
|
const [isExpired, setIsExpired] = useState(false);
|
|
17
30
|
const { name, description, status, lastCheckInDate, progressPercentage, checkInStreak, thirdDayBonusAmount, sixthDayBonusAmount, seventhDayBonusAmount, endDateTime, id, } = quest;
|
|
18
31
|
const today = startOfDay(new Date());
|
|
@@ -20,26 +33,23 @@ export function DailyCheckInQuest({ quest }) {
|
|
|
20
33
|
? isEqual(today, startOfDay(new Date(lastCheckInDate)))
|
|
21
34
|
: false;
|
|
22
35
|
const checkedInRewards = {
|
|
23
|
-
3: thirdDayBonusAmount,
|
|
24
|
-
6: sixthDayBonusAmount,
|
|
25
|
-
7: seventhDayBonusAmount,
|
|
36
|
+
3: parseDecimal(thirdDayBonusAmount, 0),
|
|
37
|
+
6: parseDecimal(sixthDayBonusAmount, 0),
|
|
38
|
+
7: parseDecimal(seventhDayBonusAmount, 0),
|
|
26
39
|
};
|
|
27
40
|
const dailyCheckedInData = Array.from({ length: 7 }, (_, i) => {
|
|
28
41
|
const day = i + 1;
|
|
29
42
|
return {
|
|
30
43
|
day,
|
|
31
|
-
reward: checkedInRewards[day]
|
|
44
|
+
reward: checkedInRewards[day] ? checkedInRewards[day] : null,
|
|
32
45
|
};
|
|
33
46
|
});
|
|
34
|
-
const
|
|
47
|
+
const checkInDailyQuestMutation = useCheckInDailyCheckInQuestMutation({
|
|
35
48
|
onSuccess() {
|
|
36
49
|
toaster.success({
|
|
37
50
|
title: 'Check-in successful 🎉',
|
|
38
51
|
description: 'You’ve successfully checked in for today! Keep it up to maintain your streak!',
|
|
39
52
|
});
|
|
40
|
-
queryClient.invalidateQueries({
|
|
41
|
-
queryKey: getAvailableQuestsQueryKey(),
|
|
42
|
-
});
|
|
43
53
|
},
|
|
44
54
|
onError(e) {
|
|
45
55
|
toaster.error({
|
|
@@ -48,26 +58,24 @@ export function DailyCheckInQuest({ quest }) {
|
|
|
48
58
|
});
|
|
49
59
|
},
|
|
50
60
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "border-border-primary bg-bg-tertiary flex h-full w-full flex-col space-y-6 rounded-2xl border px-4 pb-6 pt-5", children: [_jsxs("div", { className: "flex flex-col space-y-2", children: [_jsxs("div", { className: "flex max-h-7.5 items-start justify-between", children: [_jsx(CountdownTimer, { endDateTime: endDateTime, renderAction: (timeLeft) => (_jsxs(Badge.Root, { size: "lg", colorScheme: "brand", round: false, children: [_jsx(Badge.Icon, { children: _jsx(ClockStopWatchIcon, {}) }), _jsxs(Badge.Label, { children: [timeLeft.days, "d:", timeLeft.hours, "h:", timeLeft.minutes, "m:", timeLeft.seconds, "s"] })] })), onEnd: () => setIsExpired(true) }), _jsx("div", { role: "button", className: "bg-bg-primary border-border-secondary flex size-9 cursor-pointer items-center justify-center rounded-md border", onClick: () => disclosure.setOpen(true), children: _jsx(InfoCircleIcon, { className: "text-text-disabled size-5" }) })] }), _jsx("p", { className: "text-xl font-semibold", children: name }), _jsx("p", { className: "text-text-secondary-700 text-wrap text-sm font-normal", dangerouslySetInnerHTML: { __html: description } })] }), _jsxs("div", { className: "flex w-full flex-col space-y-2", children: [_jsx("div", { className: "grid grid-cols-7", children: dailyCheckedInData.map((item) => {
|
|
62
|
+
const reward = item.reward
|
|
63
|
+
? `+${formatNumber(item.reward, {
|
|
64
|
+
currency: localeInfo.currency.code,
|
|
65
|
+
minDecimalPlaces: 0,
|
|
66
|
+
maxDecimalPlaces: 0,
|
|
67
|
+
})}`
|
|
68
|
+
: '-';
|
|
57
69
|
return (_jsx("div", { className: twMerge('flex items-center justify-center', item.day <= (checkInStreak || 0)
|
|
58
70
|
? 'text-brand-400'
|
|
59
71
|
: 'text-text-secondary-700'), children: _jsx("p", { children: reward }) }, item.day));
|
|
60
|
-
}) }), _jsx("div", { className: "bg-bg-primary h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "bg-utility-brand-600 h-full rounded-full transition-all duration-300", style: { width: `${progressPercentage}%` } }) }), _jsx("div", { className: "grid grid-cols-7", children: dailyCheckedInData.map((item) => (
|
|
72
|
+
}) }), _jsx("div", { className: "bg-bg-primary h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "bg-utility-brand-600 h-full rounded-full transition-all duration-300", style: { width: `${progressPercentage}%` } }) }), _jsx("div", { className: "grid grid-cols-7 place-items-center", children: dailyCheckedInData.map((item) => (_jsxs("div", { className: "text-text-secondary-700 ui-active:text-brand-400 group relative size-fit", "data-active": dataAttr(item.day <= (checkInStreak ?? 0)), children: [_jsx(CalendarIcon, { className: "h-4.5 w-auto" }), _jsx("p", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-2xs leading-none", children: item.day })] }, item.day))) })] }), _jsx(Button, { onClick: () => checkInDailyQuestMutation.mutate(id), className: "disabled:bg-bg-primary disabled:text-text-disabled", disabled: isExpired ||
|
|
61
73
|
status === 'COMPLETED' ||
|
|
62
74
|
status === 'FAILED' ||
|
|
63
|
-
hasCheckedInToday
|
|
75
|
+
hasCheckedInToday ||
|
|
76
|
+
checkInDailyQuestMutation.isPending, children: hasCheckedInToday && status === 'IN_PROGRESS' ? (_jsx(CountdownTimer, { endDateTime: startOfDay(addDays(new Date(), 1)).toISOString(), renderAction: (timeLeft) => (_jsxs("div", { className: "flex items-center space-x-0.5", children: [_jsx(CheckIcon, { className: "size-5" }), _jsxs("p", { children: [timeLeft.hours, "h:", timeLeft.minutes, "m:", timeLeft.seconds, "s"] })] })), onEnd: () => {
|
|
64
77
|
queryClient.invalidateQueries({
|
|
65
78
|
queryKey: getAvailableQuestsQueryKey(),
|
|
66
79
|
});
|
|
67
|
-
} })) : ('Check-In') })] })] }));
|
|
68
|
-
}
|
|
69
|
-
function CalendarWithDayNumber({ day, currentCheckedInDays, }) {
|
|
70
|
-
return (_jsxs("div", { className: twMerge('group relative h-fit w-fit', day <= currentCheckedInDays
|
|
71
|
-
? 'text-brand-400'
|
|
72
|
-
: 'text-text-secondary-700'), children: [_jsx(CalendarIcon, {}), _jsx("div", { className: "absolute inset-0 mt-1 flex items-center justify-center text-2xs lg:mt-[2px]", children: _jsx("p", { className: "text-center", children: day }) })] }));
|
|
80
|
+
} })) : ('Check-In') })] }), _jsx(DailyCheckInQuestRules, { open: disclosure.open, onOpenChange: disclosure.setOpen })] }));
|
|
73
81
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useControllableState } from '../../../client/hooks/useControllableState.js';
|
|
4
|
+
import { XIcon } from '../../../icons/XIcon.js';
|
|
5
|
+
import { Button } from '../../../ui/Button/index.js';
|
|
6
|
+
import { Dialog } from '../../../ui/Dialog/index.js';
|
|
7
|
+
import { Portal } from '../../../ui/Portal/index.js';
|
|
8
|
+
export function DailyCheckInQuestRules(props) {
|
|
9
|
+
const [open, setOpen] = useControllableState({
|
|
10
|
+
value: props.open,
|
|
11
|
+
defaultValue: props.defaultOpen ?? false,
|
|
12
|
+
onChange: props.onOpenChange,
|
|
13
|
+
});
|
|
14
|
+
return (_jsx(Dialog.Root, { lazyMount: true, unmountOnExit: true, open: open, onOpenChange: (details) => setOpen(details.open), 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 max-w-[343px] rounded-xl px-4 pb-0 pt-5", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs("div", { className: "flex flex-col space-y-5", children: [_jsx("h2", { className: "text-text-primary-900 text-lg font-semibold", children: "Daily Check-In Rules" }), _jsxs("ol", { className: "text-text-tertiary-600 group list-disc text-wrap pl-4 text-sm font-normal", children: [_jsx("li", { children: "Earn rewards just for checking in each day!" }), _jsx("li", { children: "Stay consistent to unlock special rewards on the 3rd, 5th, and 7th day." }), _jsx("li", { children: "Missing a day will reset your streak, starting again from Day 1." }), _jsx("li", { children: "Each check-in unlocks the next one on the following day." }), _jsx("li", { children: "Successfully check in for 7 consecutive days to complete the quest and reset the cycle." })] })] }), _jsx("div", { className: "pb-4 pt-6", children: _jsx(Button, { onClick: () => setOpen(false), children: "Ok" }) })] }) })] }) }));
|
|
15
|
+
}
|
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useShallow } from 'zustand/shallow';
|
|
3
|
+
import { useDisclosure } from '../../../client/hooks/useDisclosure.js';
|
|
4
|
+
import { useGlobalStore } from '../../../client/hooks/useGlobalStore.js';
|
|
5
|
+
import { CheckIcon } from '../../../icons/CheckIcon.js';
|
|
6
|
+
import { ClockStopWatchIcon } from '../../../icons/ClockStopWatchIcon.js';
|
|
7
|
+
import { CoinsHandIcon } from '../../../icons/CoinsHandIcon.js';
|
|
8
|
+
import { FileCheck02Icon } from '../../../icons/FileCheck02Icon.js';
|
|
9
|
+
import { InfoCircleIcon } from '../../../icons/InfoCircleIcon.js';
|
|
10
|
+
import { Badge } from '../../../ui/Badge/index.js';
|
|
11
|
+
import { Button } from '../../../ui/Button/index.js';
|
|
12
|
+
import { Checkbox } from '../../../ui/Checkbox/index.js';
|
|
13
|
+
import { useQuestContext } from '../QuestsContext.js';
|
|
14
|
+
import { OnboardingQuestRules } from './OnboardingQuestRules.js';
|
|
15
|
+
export function OnboardingQuest() {
|
|
16
|
+
const quest = useQuestContext();
|
|
17
|
+
const disclosure = useDisclosure();
|
|
18
|
+
const globalStore = useGlobalStore(useShallow((ctx) => ({
|
|
19
|
+
kyc: ctx.kyc,
|
|
20
|
+
depositWithdrawal: ctx.depositWithdrawal,
|
|
21
|
+
})));
|
|
22
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "border-border-primary bg-bg-tertiary flex h-full w-full flex-col space-y-6 rounded-2xl border px-4 pb-6 pt-5", children: [_jsxs("div", { className: "flex flex-col space-y-2", children: [_jsxs("div", { className: "flex max-h-7.5 items-start justify-between", children: [_jsxs(Badge.Root, { size: "lg", colorScheme: "brand", round: false, children: [_jsx(Badge.Icon, { children: _jsx(ClockStopWatchIcon, {}) }), _jsx(Badge.Label, { children: "123" })] }), _jsx("div", { role: "button", className: "bg-bg-primary border-border-secondary flex size-9 cursor-pointer items-center justify-center rounded-md border", children: _jsx(InfoCircleIcon, { className: "text-text-disabled size-5" }) })] }), _jsx("h2", { className: "text-xl font-semibold", children: quest.name }), _jsx("p", { className: "text-text-secondary-700 text-wrap text-sm font-normal", dangerouslySetInnerHTML: { __html: quest.description } })] }), _jsxs("div", { className: "w-full grow space-y-2", children: [_jsxs(Checkbox.Root, { children: [_jsx(Checkbox.Control, { className: "bg-transparent", children: _jsx(Checkbox.Indicator, { asChild: true, children: _jsx(CheckIcon, {}) }) }), _jsx(Checkbox.Label, { className: "text-sm font-medium leading-tight", children: "Complete personal verification" }), _jsx(Checkbox.HiddenInput, {})] }), _jsxs(Checkbox.Root, { children: [_jsx(Checkbox.Control, { className: "bg-transparent", children: _jsx(Checkbox.Indicator, { asChild: true, children: _jsx(CheckIcon, {}) }) }), _jsx(Checkbox.Label, { className: "text-sm font-medium leading-tight", children: "Make your first deposit" }), _jsx(Checkbox.HiddenInput, {})] })] }), _jsxs("div", { className: "flex gap-lg", children: [_jsxs(Button, { size: "sm", onClick: () => {
|
|
23
|
+
globalStore.kyc.setOpen(true);
|
|
24
|
+
}, children: [_jsx(FileCheck02Icon, { className: "size-5" }), "Verify"] }), _jsxs(Button, { size: "sm", onClick: () => {
|
|
25
|
+
globalStore.depositWithdrawal.setTab('DEPOSIT');
|
|
26
|
+
globalStore.depositWithdrawal.setOpen(true);
|
|
27
|
+
}, children: [_jsx(CoinsHandIcon, { className: "size-5" }), "Deposit"] })] })] }), _jsx(OnboardingQuestRules, { open: disclosure.open, onOpenChange: disclosure.setOpen })] }));
|
|
4
28
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useControllableState } from '../../../client/hooks/useControllableState.js';
|
|
4
|
+
import { XIcon } from '../../../icons/XIcon.js';
|
|
5
|
+
import { Button } from '../../../ui/Button/index.js';
|
|
6
|
+
import { Dialog } from '../../../ui/Dialog/index.js';
|
|
7
|
+
import { Portal } from '../../../ui/Portal/index.js';
|
|
8
|
+
export function OnboardingQuestRules(props) {
|
|
9
|
+
const [open, setOpen] = useControllableState({
|
|
10
|
+
value: props.open,
|
|
11
|
+
defaultValue: props.defaultOpen ?? false,
|
|
12
|
+
onChange: props.onOpenChange,
|
|
13
|
+
});
|
|
14
|
+
return (_jsx(Dialog.Root, { lazyMount: true, unmountOnExit: true, open: open, onOpenChange: (details) => setOpen(details.open), 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 max-w-[343px] rounded-xl px-4 pb-0 pt-5", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs("div", { className: "flex flex-col space-y-5", children: [_jsx("h2", { className: "text-text-primary-900 text-lg font-semibold", children: "Welcome Quest Rules" }), _jsxs("ol", { className: "text-text-tertiary-600 group list-disc text-wrap pl-4 text-sm font-normal", children: [_jsx("li", { children: "Begin your quest whenever you're ready" }), _jsx("li", { children: "Tackle the tasks in any order you like" }), _jsx("li", { children: "Finish all tasks and we'll credit your reward automatically!" })] })] }), _jsx("div", { className: "pb-4 pt-6", children: _jsx(Button, { onClick: () => setOpen(false), children: "Ok" }) })] }) })] }) }));
|
|
15
|
+
}
|
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { useDisclosure } from '../../../client/hooks/useDisclosure.js';
|
|
6
|
+
import { useLocaleInfo } from '../../../client/hooks/useLocaleInfo.js';
|
|
7
|
+
import { ClockStopWatchIcon } from '../../../icons/ClockStopWatchIcon.js';
|
|
8
|
+
import { InfoCircleIcon } from '../../../icons/InfoCircleIcon.js';
|
|
9
|
+
import { Badge } from '../../../ui/Badge/index.js';
|
|
10
|
+
import { parseDecimal } from '../../../utils/parseDecimal.js';
|
|
7
11
|
import CountdownTimer from '../CountdownTimer.js';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
import { useQuestContext } from '../QuestsContext.js';
|
|
13
|
+
import { WageringQuestModal } from './WageringQuestRules.js';
|
|
14
|
+
export function WageringQuest() {
|
|
15
|
+
const quest = useQuestContext();
|
|
16
|
+
const disclosure = useDisclosure();
|
|
17
|
+
const localeInfo = useLocaleInfo();
|
|
11
18
|
const [isExpired, setIsExpired] = useState(false);
|
|
12
19
|
const { progressPercentage, turnover, targetTurnover, name, description, endDateTime, bonus, status, } = quest;
|
|
13
|
-
return (_jsxs(_Fragment, { children: [_jsx(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} }), _jsxs("div", { className: "border-border-primary bg-bg-tertiary flex h-full w-full flex-col space-y-6 rounded-2xl border px-4 pb-6 pt-5", children: [_jsxs("div", { className: "flex flex-col space-y-2", children: [_jsxs("div", { className: "flex max-h-7.5 items-start justify-between", children: [_jsx(CountdownTimer, { endDateTime: endDateTime, renderAction: (timeLeft) => (_jsxs(Badge.Root, { size: "lg", colorScheme: "brand", round: false, children: [_jsx(Badge.Icon, { children: _jsx(ClockStopWatchIcon, {}) }), _jsxs(Badge.Label, { children: [timeLeft.days, "d:", timeLeft.hours, "h:", timeLeft.minutes, "m:", timeLeft.seconds, "s"] })] })), onEnd: () => setIsExpired(true) }), _jsx("div", { role: "button", className: "bg-bg-primary border-border-secondary flex size-9 cursor-pointer items-center justify-center rounded-md border", onClick: () => setShowRules((prev) => !prev), children: _jsx(InfoCircleIcon, { className: "text-text-disabled size-5" }) })] }), _jsx("p", { className: "text-xl font-semibold", children: name }), _jsx("p", { className: "text-text-secondary-700 text-wrap text-sm font-normal", dangerouslySetInnerHTML: { __html: description } })] }), _jsxs("div", { className: "flex w-full flex-col space-y-2", children: [_jsxs("div", { className: "text-text-primary-brand group flex items-center justify-between", children: [_jsxs("p", { children: ["Progress ", parseInt(progressPercentage).toFixed(2), "%"] }), _jsxs("p", { children: [turnover, _jsxs("span", { className: "text-text-quarterary-brand", children: ["/", targetTurnover, " PHP"] })] })] }), _jsx("div", { className: "bg-bg-primary h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "bg-utility-brand-600 h-full rounded-full transition-all duration-300", style: { width: `${progressPercentage}%` } }) })] }), _jsx("div", { className: "flex h-full items-end", children: _jsx("div", { className: "bg-button-secondary-bg border-bg-primary-hover w-full rounded-md border px-3.5 py-2.5 text-center text-white", children: _jsxs("p", { className: twMerge(isExpired || status === 'COMPLETED' || status === 'FAILED'
|
|
17
|
-
? ['opacity-50 grayscale']
|
|
18
|
-
: ''), children: ["Complete to get ", _jsxs("span", { className: "text-brand-400", children: ["\u20B1", bonus] }), ' ', "bonus!"] }) }) })] })] }));
|
|
20
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "border-border-primary bg-bg-tertiary flex h-full w-full flex-col space-y-6 rounded-2xl border px-4 pb-6 pt-5", children: [_jsxs("div", { className: "flex flex-col space-y-2", children: [_jsxs("div", { className: "flex max-h-7.5 items-start justify-between", children: [_jsx(CountdownTimer, { endDateTime: endDateTime, renderAction: (timeLeft) => (_jsxs(Badge.Root, { size: "lg", colorScheme: "brand", round: false, children: [_jsx(Badge.Icon, { children: _jsx(ClockStopWatchIcon, {}) }), _jsxs(Badge.Label, { children: [timeLeft.days, "d:", timeLeft.hours, "h:", timeLeft.minutes, "m:", timeLeft.seconds, "s"] })] })), onEnd: () => setIsExpired(true) }), _jsx("div", { role: "button", className: "bg-bg-primary border-border-secondary flex size-9 cursor-pointer items-center justify-center rounded-md border", onClick: () => disclosure.setOpen(true), children: _jsx(InfoCircleIcon, { className: "text-text-disabled size-5" }) })] }), _jsx("p", { className: "text-xl font-semibold", children: name }), _jsx("p", { className: "text-text-secondary-700 text-wrap text-sm font-normal", dangerouslySetInnerHTML: { __html: description } })] }), _jsxs("div", { className: "flex w-full flex-col space-y-2", children: [_jsxs("div", { className: "text-text-primary-brand group flex items-center justify-between", children: [_jsxs("p", { children: ["Progress ", parseDecimal(progressPercentage, 0).toFixed(2), "%"] }), _jsxs("p", { children: [turnover, _jsxs("span", { className: "text-text-quarterary-brand", children: ["/", targetTurnover, " ", localeInfo.currency.code] })] })] }), _jsx("div", { className: "bg-bg-primary h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "bg-utility-brand-600 h-full rounded-full transition-all duration-300", style: { width: `${progressPercentage}%` } }) })] }), _jsx("div", { className: "flex h-full items-end", children: _jsx("div", { className: "bg-button-secondary-bg border-bg-primary-hover w-full rounded-md border px-3.5 py-2.5 text-center text-white", children: _jsxs("p", { className: twMerge(isExpired || status === 'COMPLETED' || status === 'FAILED'
|
|
21
|
+
? 'opacity-50 grayscale'
|
|
22
|
+
: ''), children: ["Complete to get ", _jsxs("span", { className: "text-brand-400", children: ["\u20B1", bonus] }), ' ', "bonus!"] }) }) })] }), _jsx(WageringQuestModal, { open: disclosure.open, onOpenChange: disclosure.setOpen })] }));
|
|
19
23
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useControllableState } from '../../../client/hooks/useControllableState.js';
|
|
4
|
+
import { XIcon } from '../../../icons/XIcon.js';
|
|
5
|
+
import { Button } from '../../../ui/Button/index.js';
|
|
6
|
+
import { Dialog } from '../../../ui/Dialog/index.js';
|
|
7
|
+
import { Portal } from '../../../ui/Portal/index.js';
|
|
8
|
+
import { useQuestContext } from '../QuestsContext.js';
|
|
9
|
+
export function WageringQuestModal(props) {
|
|
10
|
+
const quest = useQuestContext();
|
|
11
|
+
const [open, setOpen] = useControllableState({
|
|
12
|
+
value: props.open,
|
|
13
|
+
defaultValue: props.defaultOpen ?? false,
|
|
14
|
+
onChange: props.onOpenChange,
|
|
15
|
+
});
|
|
16
|
+
return (_jsx(Dialog.Root, { lazyMount: true, unmountOnExit: true, open: open, onOpenChange: (details) => setOpen(details.open), 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 max-w-[343px] rounded-xl px-4 pb-0 pt-5", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs("div", { className: "flex flex-col space-y-5", children: [_jsx("h2", { className: "text-text-primary-900 text-lg font-semibold", children: quest.name }), _jsxs("ol", { className: "text-text-tertiary-600 group list-disc text-wrap pl-4 text-sm font-normal", children: [_jsx("li", { children: "Earn extra rewards just by playing Slots, every bet counts, win or lose!" }), _jsx("li", { children: "Reach the wagering requirement in bets to complete the quest and claim your reward." })] })] }), _jsx("div", { className: "pb-4 pt-6", children: _jsx(Button, { onClick: () => setOpen(false), children: "Ok" }) })] }) })] }) }));
|
|
17
|
+
}
|
|
@@ -18,7 +18,7 @@ import { Dialog } from '../../ui/Dialog/index.js';
|
|
|
18
18
|
import { Field } from '../../ui/Field/index.js';
|
|
19
19
|
import { IconButton } from '../../ui/IconButton/index.js';
|
|
20
20
|
import { Portal } from '../../ui/Portal/index.js';
|
|
21
|
-
import { Presence } from '../../ui/Presence.js';
|
|
21
|
+
import { Presence } from '../../ui/Presence/index.js';
|
|
22
22
|
import { callIfFn } from '../../utils/callIfFn.js';
|
|
23
23
|
import { getGameImageUrl } from '../../utils/getGameImageUrl.js';
|
|
24
24
|
import { GameLaunchTrigger } from '../GameLaunch/index.js';
|
|
@@ -88,7 +88,9 @@ export function MobileNumberSignIn() {
|
|
|
88
88
|
: 'Failed to send verification code',
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
|
-
}), children: [_jsxs(Field.Root, { invalid: !!step1Form.formState.errors.mobileNumber, children: [_jsx(Field.Label, { children: "Mobile Number" }), _jsxs("div", { className: "relative", children: [
|
|
91
|
+
}), children: [_jsxs(Field.Root, { invalid: !!step1Form.formState.errors.mobileNumber, children: [_jsx(Field.Label, { children: "Mobile Number" }), _jsxs("div", { className: "relative", children: [_jsxs("div", { className: "absolute left-3.5 top-1/2 flex shrink-0 -translate-y-1/2 items-center gap-md", children: [_jsx(localeInfo.country.flag, { className: "size-5" }), _jsx("span", { className: "text-text-placeholder", children: localeInfo.mobileNumber.areaCode })] }), _jsx(Field.Input, { style: {
|
|
92
|
+
paddingLeft: `calc(2.75rem + ${localeInfo.mobileNumber.areaCode.length}ch)`,
|
|
93
|
+
}, ...step1Form.register('mobileNumber') })] }), _jsx(Field.ErrorText, { children: step1Form.formState.errors.mobileNumber?.message })] }), _jsx(Button, { type: "submit", className: "mt-3xl", disabled: step1Form.formState.isSubmitting, children: "Log In" }), _jsx(Controller, { control: step1Form.control, name: "termsAccepted", render: (o) => (_jsxs(Field.Root, { invalid: o.fieldState.invalid, className: "mt-xl", children: [_jsxs(Checkbox.Root, { checked: o.field.value, onCheckedChange: (details) => {
|
|
92
94
|
o.field.onChange(details.checked);
|
|
93
95
|
}, children: [_jsx(Checkbox.Control, { children: _jsx(Checkbox.Indicator, { asChild: true, children: _jsx(CheckIcon, {}) }) }), _jsxs(Checkbox.Label, { children: ["I am at least 21 years of age and I accept the", ' ', _jsx("span", { className: "text-brand-400 whitespace-nowrap underline underline-offset-2", children: "Terms and Conditions." })] }), _jsx(Checkbox.HiddenInput, {})] }), _jsx(Field.ErrorText, { className: "ml-6 text-xs", children: o.fieldState.error?.message })] })) })] }), _jsxs("div", { className: "relative mt-6 text-center", children: [_jsx("hr", { className: "-translte-y-1/2 text-text-tertiary-600/50 absolute top-1/2 w-full" }), _jsx("span", { className: "text-text-tertiary-600 bg-bg-primary-alt relative px-md text-center text-sm font-semibold", children: "Log in directly with" })] }), _jsxs("div", { className: "mt-6", children: [_jsxs(Button, { variant: "outline", colorScheme: "gray", onClick: () => {
|
|
94
96
|
dialog.setOpen(false);
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { createListCollection, parseDate } from '@ark-ui/react';
|
|
3
4
|
import { useDialogContext } from '@ark-ui/react/dialog';
|
|
4
5
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
5
6
|
import { ObjectId } from '@opexa/object-id';
|
|
7
|
+
import { differenceInYears, format } from 'date-fns';
|
|
8
|
+
import { noop } from 'lodash-es';
|
|
6
9
|
import { useSearchParams } from 'next/navigation';
|
|
7
10
|
import { useRef, useState } from 'react';
|
|
8
11
|
import { Controller, useForm } from 'react-hook-form';
|
|
@@ -15,14 +18,30 @@ import { useMobileNumberParser } from '../../client/hooks/useMobileNumberParser.
|
|
|
15
18
|
import { useSendVerificationCodeMutation } from '../../client/hooks/useSendVerificationCodeMutation.js';
|
|
16
19
|
import { useSignInMutation } from '../../client/hooks/useSignInMutation.js';
|
|
17
20
|
import { useSignUpMutation } from '../../client/hooks/useSignUpMutation.js';
|
|
21
|
+
import { useUpdateAccountMutation } from '../../client/hooks/useUpdateAccountMutation.js';
|
|
18
22
|
import { toaster } from '../../client/utils/toaster.js';
|
|
23
|
+
import { BRANCH_CODES } from '../../constants/index.js';
|
|
19
24
|
import { ArrowLeftIcon } from '../../icons/ArrowLeftIcon.js';
|
|
25
|
+
import { CalendarIcon } from '../../icons/CalendarIcon.js';
|
|
20
26
|
import { CheckIcon } from '../../icons/CheckIcon.js';
|
|
27
|
+
import { ChevronDownIcon } from '../../icons/ChevronDownIcon.js';
|
|
28
|
+
import { ChevronLeftIcon } from '../../icons/ChevronLeftIcon.js';
|
|
29
|
+
import { ChevronRightIcon } from '../../icons/ChevronRightIcon.js';
|
|
30
|
+
import { FacebookIcon } from '../../icons/FacebookIcon.js';
|
|
31
|
+
import { GoogleIcon } from '../../icons/GoogleIcon.js';
|
|
21
32
|
import { ObjectType } from '../../services/ObjectType.js';
|
|
22
33
|
import { Button } from '../../ui/Button/index.js';
|
|
23
34
|
import { Checkbox } from '../../ui/Checkbox/index.js';
|
|
35
|
+
import { DatePicker } from '../../ui/DatePicker/index.js';
|
|
24
36
|
import { Field } from '../../ui/Field/index.js';
|
|
25
37
|
import { PinInput } from '../../ui/PinInput/index.js';
|
|
38
|
+
import { Select } from '../../ui/Select/index.js';
|
|
39
|
+
import { createPoll } from '../../utils/createPoll.js';
|
|
40
|
+
const branchCollection = createListCollection({
|
|
41
|
+
items: BRANCH_CODES,
|
|
42
|
+
itemToValue: (item) => item.code,
|
|
43
|
+
itemToString: (item) => `${item.code} - ${item.name}`,
|
|
44
|
+
});
|
|
26
45
|
export function SignUpForm() {
|
|
27
46
|
const [step, setStep] = useState(1);
|
|
28
47
|
const dialog = useDialogContext();
|
|
@@ -30,6 +49,7 @@ export function SignUpForm() {
|
|
|
30
49
|
const signInStore = useGlobalStore(useShallow((ctx) => ctx.signIn));
|
|
31
50
|
const signUpMutation = useSignUpMutation();
|
|
32
51
|
const signInMutation = useSignInMutation();
|
|
52
|
+
const updateAccountMutation = useUpdateAccountMutation();
|
|
33
53
|
const sendVerificationCodeMutation = useSendVerificationCodeMutation();
|
|
34
54
|
const localeInfo = useLocaleInfo();
|
|
35
55
|
const mobileNumberParser = useMobileNumberParser();
|
|
@@ -50,15 +70,39 @@ export function SignUpForm() {
|
|
|
50
70
|
});
|
|
51
71
|
}
|
|
52
72
|
}),
|
|
73
|
+
realName: z
|
|
74
|
+
.string()
|
|
75
|
+
.min(2, 'Real name must be 2 or more characters')
|
|
76
|
+
.max(50, 'Real name must not be more than 50 characters')
|
|
77
|
+
.trim(),
|
|
78
|
+
birthDay: z
|
|
79
|
+
.date({
|
|
80
|
+
invalid_type_error: 'Date of birth is required',
|
|
81
|
+
required_error: 'Date of birth is required',
|
|
82
|
+
})
|
|
83
|
+
.superRefine((val, ctx) => {
|
|
84
|
+
const now = new Date();
|
|
85
|
+
const age = differenceInYears(now, val);
|
|
86
|
+
if (age < 21) {
|
|
87
|
+
return ctx.addIssue({
|
|
88
|
+
code: z.ZodIssueCode.custom,
|
|
89
|
+
message: 'You must be at least 21 years old',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}),
|
|
93
|
+
branchCode: z.string().min(1, 'Branch is required').trim(),
|
|
53
94
|
});
|
|
54
95
|
const Step2Definition = z.object({
|
|
55
96
|
verificationCode: z.array(z.string().min(1).max(1).trim()).min(6).max(6),
|
|
56
97
|
});
|
|
57
98
|
const step1Form = useForm({
|
|
99
|
+
mode: 'all',
|
|
58
100
|
resolver: zodResolver(Step1Definition),
|
|
59
101
|
defaultValues: {
|
|
60
102
|
mobileNumber: '',
|
|
61
103
|
termsAccepted: false,
|
|
104
|
+
branchCode: BRANCH_CODES[0].code,
|
|
105
|
+
realName: '',
|
|
62
106
|
},
|
|
63
107
|
});
|
|
64
108
|
const step2Form = useForm({
|
|
@@ -72,6 +116,8 @@ export function SignUpForm() {
|
|
|
72
116
|
duration: 1000 * 60,
|
|
73
117
|
});
|
|
74
118
|
const form2Ref = useRef(null);
|
|
119
|
+
const birthDay = step1Form.watch('birthDay');
|
|
120
|
+
const branchCode = step1Form.watch('branchCode', '');
|
|
75
121
|
return (_jsxs(_Fragment, { children: [step === 1 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "mt-xl text-center text-lg font-semibold", children: "Create an account" }), _jsx("p", { className: "text-text-secondary-700 mt-xs text-center text-sm", children: "Register instantly and start playing!" }), _jsxs("form", { className: "mt-3xl", onSubmit: step1Form.handleSubmit(async (data) => {
|
|
76
122
|
try {
|
|
77
123
|
await sendVerificationCodeMutation.mutateAsync({
|
|
@@ -88,9 +134,33 @@ export function SignUpForm() {
|
|
|
88
134
|
: 'Failed to send verification code',
|
|
89
135
|
});
|
|
90
136
|
}
|
|
91
|
-
}), children: [_jsxs(Field.Root, { invalid: !!step1Form.formState.errors.mobileNumber, children: [_jsx(Field.Label, { children: "Mobile Number" }), _jsxs("div", { className: "relative", children: [
|
|
137
|
+
}), children: [_jsxs(Field.Root, { invalid: !!step1Form.formState.errors.mobileNumber, children: [_jsx(Field.Label, { children: "Mobile Number" }), _jsxs("div", { className: "relative", children: [_jsxs("div", { className: "absolute left-3.5 top-1/2 flex shrink-0 -translate-y-1/2 items-center gap-md", children: [_jsx(localeInfo.country.flag, { className: "size-5" }), _jsx("span", { className: "text-text-placeholder", children: localeInfo.mobileNumber.areaCode })] }), _jsx(Field.Input, { style: {
|
|
138
|
+
paddingLeft: `calc(2.75rem + ${localeInfo.mobileNumber.areaCode.length}ch)`,
|
|
139
|
+
}, ...step1Form.register('mobileNumber') })] }), _jsx(Field.ErrorText, { children: step1Form.formState.errors.mobileNumber?.message })] }), _jsxs(Field.Root, { invalid: !!step1Form.formState.errors.realName, className: "mt-xl", children: [_jsx(Field.Label, { children: "Real Name" }), _jsx(Field.Input, { placeholder: "Enter your real name", ...step1Form.register('realName') }), _jsx(Field.ErrorText, { children: step1Form.formState.errors.realName?.message })] }), _jsxs(Field.Root, { invalid: !!step1Form.formState.errors.birthDay, className: "mt-xl", children: [_jsxs(DatePicker.Root, { size: "md", variant: "outline", placeholder: "MM/DD/YYYY", lazyMount: true, unmountOnExit: true, fixedWeeks: true, selectionMode: "single", value: birthDay ? [parseDate(birthDay)] : [], onValueChange: (details) => {
|
|
140
|
+
const value = details.value.at(0)?.toDate(DEVICE_TIMEZONE);
|
|
141
|
+
if (value) {
|
|
142
|
+
step1Form.setValue('birthDay', value, {
|
|
143
|
+
shouldDirty: true,
|
|
144
|
+
shouldTouch: true,
|
|
145
|
+
shouldValidate: true,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}, children: [_jsx(DatePicker.Label, { children: "Date of Birth" }), _jsxs(DatePicker.Control, { children: [_jsx(DatePicker.Input, {}), _jsx(DatePicker.Trigger, { children: _jsx(CalendarIcon, {}) })] }), _jsx(DatePicker.Positioner, { children: _jsx(DatePicker.Content, { children: _jsx(DatePicker.View, { view: "day", children: _jsx(DatePicker.Context, { children: (api) => (_jsxs(_Fragment, { children: [_jsxs(DatePicker.ViewControl, { children: [_jsx(DatePicker.PrevTrigger, { children: _jsx(ChevronLeftIcon, {}) }), _jsx(DatePicker.ViewTrigger, { children: _jsx(DatePicker.RangeText, {}) }), _jsx(DatePicker.NextTrigger, { children: _jsx(ChevronRightIcon, {}) })] }), _jsxs(DatePicker.Table, { children: [_jsx(DatePicker.TableHead, { children: _jsx(DatePicker.TableRow, { children: api.weekDays.map((weekDay, id) => (_jsx(DatePicker.TableHeader, { children: weekDay.short.substring(0, 2) }, id))) }) }), _jsx(DatePicker.TableBody, { children: api.weeks.map((week, id) => (_jsx(DatePicker.TableRow, { children: week.map((day, id) => (_jsx(DatePicker.TableCell, { value: day, children: _jsx(DatePicker.TableCellTrigger, { children: day.day }) }, id))) }, id))) })] })] })) }) }) }) })] }), _jsx(Field.ErrorText, { children: step1Form.formState.errors.birthDay?.message })] }), _jsxs(Field.Root, { invalid: !!step1Form.formState.errors.branchCode, className: "mt-xl", children: [_jsxs(Select.Root, { value: [branchCode], onValueChange: (details) => {
|
|
149
|
+
step1Form.setValue('branchCode', details.value.at(0) ?? BRANCH_CODES[0].code, {
|
|
150
|
+
shouldDirty: true,
|
|
151
|
+
shouldTouch: true,
|
|
152
|
+
shouldValidate: true,
|
|
153
|
+
});
|
|
154
|
+
}, collection: branchCollection, positioning: {
|
|
155
|
+
sameWidth: true,
|
|
156
|
+
placement: 'bottom',
|
|
157
|
+
}, lazyMount: true, unmountOnExit: true, children: [_jsx(Select.Label, { children: "Branch" }), _jsxs(Select.Trigger, { children: [_jsx(Select.ValueText, {}), _jsx(Select.Indicator, { asChild: true, children: _jsx(ChevronDownIcon, {}) })] }), _jsx(Select.Positioner, { children: _jsx(Select.Content, { children: branchCollection.items.map((item) => (_jsx(Select.Item, { item: item, children: branchCollection.stringifyItem(item) }, item.code))) }) })] }), _jsx(Field.ErrorText, { children: step1Form.formState.errors.branchCode?.message })] }), _jsx(Controller, { control: step1Form.control, name: "termsAccepted", render: (o) => (_jsxs(Field.Root, { className: "mt-2xl", invalid: o.fieldState.invalid, children: [_jsxs(Checkbox.Root, { checked: o.field.value, onCheckedChange: (details) => {
|
|
92
158
|
o.field.onChange(details.checked);
|
|
93
|
-
}, children: [_jsx(Checkbox.Control, { children: _jsx(Checkbox.Indicator, { asChild: true, children: _jsx(CheckIcon, {}) }) }), _jsxs(Checkbox.Label, { children: ["I am at least 21 years of age and I accept the", ' ', _jsx("span", { className: "text-brand-400 whitespace-nowrap underline underline-offset-2", children: "Terms and Conditions." })] }), ' ', _jsx(Checkbox.HiddenInput, {})] }), _jsx(Field.ErrorText, { className: "ml-6 text-xs", children: o.fieldState.error?.message })] })) })] }), _jsxs("div", { className: "mt-6
|
|
159
|
+
}, children: [_jsx(Checkbox.Control, { children: _jsx(Checkbox.Indicator, { asChild: true, children: _jsx(CheckIcon, {}) }) }), _jsxs(Checkbox.Label, { children: ["I am at least 21 years of age and I accept the", ' ', _jsx("span", { className: "text-brand-400 whitespace-nowrap underline underline-offset-2", children: "Terms and Conditions." })] }), ' ', _jsx(Checkbox.HiddenInput, {})] }), _jsx(Field.ErrorText, { className: "ml-6 text-xs", children: o.fieldState.error?.message })] })) }), _jsx(Button, { type: "submit", className: "mt-3xl", disabled: step1Form.formState.isSubmitting, children: "Create Account" })] }), _jsxs("div", { className: "relative mt-6 text-center", children: [_jsx("hr", { className: "-translte-y-1/2 text-text-tertiary-600/50 absolute top-1/2 w-full" }), _jsx("span", { className: "text-text-tertiary-600 bg-bg-primary-alt relative px-md text-center text-sm font-semibold", children: "Log in directly with" })] }), _jsxs("div", { className: "mt-6", children: [_jsxs(Button, { variant: "outline", colorScheme: "gray", onClick: () => {
|
|
160
|
+
dialog.setOpen(false);
|
|
161
|
+
}, className: "border-border-primary bg-bg-primary text-text-secondary-700", children: [_jsx(GoogleIcon, { className: "size-6" }), "Sign in with Google"] }), _jsxs(Button, { variant: "outline", colorScheme: "gray", onClick: () => {
|
|
162
|
+
dialog.setOpen(false);
|
|
163
|
+
}, className: "border-border-primary bg-bg-primary text-text-secondary-700 mt-lg", children: [_jsx(FacebookIcon, { className: "size-6" }), "Sign in with Facebook"] })] }), _jsxs("div", { className: "mt-6 flex w-full items-center justify-center gap-xs text-sm", children: [_jsx("span", { className: "text-text-tertiary-600", children: "Already have an account?" }), _jsx("button", { type: "submit", className: "text-button-tertiary-fg font-semibold", onClick: () => {
|
|
94
164
|
dialog.setOpen(false);
|
|
95
165
|
signInStore.setOpen(true);
|
|
96
166
|
}, children: "Log In" })] })] })), step === 2 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "mt-xl text-center text-lg font-semibold", children: "Check your Phone" }), _jsxs("p", { className: "text-text-secondary-700 mt-xs text-center text-sm", children: ["We\u2019ve sent a verification code to your mobile number", ' ', _jsx("span", { className: "font-semibold", children: mobileNumberParser.format(step1Form.getValues('mobileNumber')) }), ' ', "via text"] }), _jsxs("form", { ref: form2Ref, className: "mt-5", onSubmit: step2Form.handleSubmit(async ({ verificationCode }) => {
|
|
@@ -107,16 +177,35 @@ export function SignUpForm() {
|
|
|
107
177
|
});
|
|
108
178
|
const name = mobileNumberParser.format(mobileNumber);
|
|
109
179
|
const password = `${name}${id}`;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
180
|
+
const poll = createPoll(async () => {
|
|
181
|
+
try {
|
|
182
|
+
await signInMutation.mutateAsync({
|
|
183
|
+
type: 'NAME_AND_PASSWORD',
|
|
184
|
+
name,
|
|
185
|
+
password,
|
|
186
|
+
});
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
}, {
|
|
193
|
+
until: (ok) => ok,
|
|
194
|
+
maxAttempt: 5,
|
|
195
|
+
});
|
|
196
|
+
const ok = await poll();
|
|
197
|
+
if (!ok) {
|
|
118
198
|
signInStore.setOpen(true);
|
|
119
199
|
}
|
|
200
|
+
else {
|
|
201
|
+
await updateAccountMutation
|
|
202
|
+
.mutateAsync({
|
|
203
|
+
branchCode: step1Form.getValues('branchCode'),
|
|
204
|
+
realName: step1Form.getValues('realName'),
|
|
205
|
+
birthDay: format(step1Form.getValues('birthDay'), 'yyyy-MM-dd'),
|
|
206
|
+
})
|
|
207
|
+
.catch(noop);
|
|
208
|
+
}
|
|
120
209
|
dialog.setOpen(false);
|
|
121
210
|
step1Form.reset();
|
|
122
211
|
step2Form.reset();
|
|
@@ -148,3 +237,4 @@ export function SignUpForm() {
|
|
|
148
237
|
cooldown.stop();
|
|
149
238
|
}, children: [_jsx(ArrowLeftIcon, { className: "size-5" }), "Back"] })] })] }))] }));
|
|
150
239
|
}
|
|
240
|
+
const DEVICE_TIMEZONE = Intl.DateTimeFormat().resolvedOptions().timeZone;
|