@opexa/portal-components 0.0.331 → 0.0.333
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/useGoogleClientIdQuery.d.ts +2 -0
- package/dist/client/hooks/useGoogleClientIdQuery.js +13 -0
- package/dist/client/hooks/useUnlinkGoogleMutation.d.ts +3 -0
- package/dist/client/hooks/useUnlinkGoogleMutation.js +31 -0
- package/dist/components/AccountInfo/AccountInfo.d.ts +2 -0
- package/dist/components/AccountInfo/AccountInfo.js +32 -4
- package/dist/components/PortalProvider/LinkGoogleAccountObserver.d.ts +1 -0
- package/dist/components/PortalProvider/LinkGoogleAccountObserver.js +23 -0
- package/dist/components/PortalProvider/PortalProvider.js +3 -1
- package/dist/components/PortalProvider/SessionWatcher.d.ts +1 -0
- package/dist/components/PortalProvider/SessionWatcher.js +22 -0
- package/dist/components/SignIn/GoogleSignInTrigger.d.ts +5 -0
- package/dist/components/SignIn/GoogleSignInTrigger.js +46 -0
- package/dist/components/SignIn/MobileNumberSignIn.js +6 -1
- package/dist/components/SignIn/SignIn.lazy.d.ts +1 -0
- package/dist/components/SignIn/index.d.ts +1 -0
- package/dist/components/SignIn/index.js +1 -0
- package/dist/components/SignUp/SignUpTrigger.d.ts +1 -2
- package/dist/handlers/getSession.js +8 -0
- package/dist/handlers/index.d.ts +7 -7
- package/dist/handlers/postAuthenticate.js +3 -0
- package/dist/handlers/postSession.js +3 -0
- package/dist/services/account.d.ts +10 -0
- package/dist/services/account.js +4 -1
- package/dist/services/queries.d.ts +2 -1
- package/dist/services/queries.js +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/ui/AlertDialog/AlertDialog.d.ts +55 -55
- package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +5 -5
- package/dist/ui/Carousel/Carousel.d.ts +45 -45
- package/dist/ui/Carousel/carousel.recipe.d.ts +5 -5
- package/dist/ui/Combobox/Combobox.d.ts +42 -42
- package/dist/ui/Combobox/combobox.recipe.d.ts +3 -3
- package/dist/ui/Dialog/Dialog.d.ts +55 -55
- package/dist/ui/Dialog/dialog.recipe.d.ts +5 -5
- 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 +198 -198
- package/dist/ui/Menu/menu.recipe.d.ts +11 -11
- package/dist/ui/Popover/Popover.d.ts +88 -88
- package/dist/ui/Popover/popover.recipe.d.ts +8 -8
- package/dist/ui/SegmentGroup/SegmentGroup.d.ts +18 -18
- package/dist/ui/SegmentGroup/segmentGroup.recipe.d.ts +3 -3
- package/dist/ui/Select/Select.d.ts +45 -45
- package/dist/ui/Select/select.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/mutationKeys.d.ts +1 -0
- package/dist/utils/mutationKeys.js +4 -0
- package/dist/utils/queryKeys.d.ts +1 -0
- package/dist/utils/queryKeys.js +1 -0
- package/package.json +1 -1
- package/dist/components/Banner/Banner.client.d.ts +0 -12
- package/dist/components/Banner/Banner.client.js +0 -49
- package/dist/components/DigitainLauncher/Loading.d.ts +0 -1
- package/dist/components/DigitainLauncher/Loading.js +0 -5
- package/dist/components/KYC/BasicInformation.d.ts +0 -1
- package/dist/components/KYC/BasicInformation.js +0 -101
- package/dist/components/KYC/IdentityVerification.d.ts +0 -1
- package/dist/components/KYC/IdentityVerification.js +0 -120
- package/dist/components/KYC/Indicator.d.ts +0 -1
- package/dist/components/KYC/Indicator.js +0 -8
- package/dist/components/KYC/KYC.lazy.d.ts +0 -6
- package/dist/components/KYC/KYC.lazy.js +0 -45
- package/dist/components/KYC/KYCContext.d.ts +0 -6
- package/dist/components/KYC/KYCContext.js +0 -2
- package/dist/components/KYC/PersonalInformation.d.ts +0 -1
- package/dist/components/KYC/PersonalInformation.js +0 -122
- package/dist/components/KYC/useKYC.d.ts +0 -25
- package/dist/components/KYC/useKYC.js +0 -38
- package/dist/components/SignIn/utils.d.ts +0 -8
- package/dist/components/SignIn/utils.js +0 -26
- package/dist/constants/Branches.d.ts +0 -2
- package/dist/constants/Branches.js +0 -42
- package/dist/images/responsible-gaming-yellow.png +0 -0
- package/dist/third-parties/FacebookPixel/FacebookPixel.d.ts +0 -4
- package/dist/third-parties/FacebookPixel/FacebookPixel.js +0 -4
- package/dist/third-parties/FacebookPixel/api.d.ts +0 -0
- package/dist/third-parties/FacebookPixel/api.js +0 -1
- package/dist/third-parties/FacebookPixel/index.d.ts +0 -1
- package/dist/third-parties/FacebookPixel/index.js +0 -1
- package/dist/third-parties/GoogleRecaptcha/GoogleRecaptcha.d.ts +0 -4
- package/dist/third-parties/GoogleRecaptcha/GoogleRecaptcha.js +0 -4
- package/dist/third-parties/GoogleRecaptcha/api.d.ts +0 -0
- package/dist/third-parties/GoogleRecaptcha/api.js +0 -1
- package/dist/third-parties/GoogleRecaptcha/index.d.ts +0 -1
- package/dist/third-parties/GoogleRecaptcha/index.js +0 -1
- package/dist/third-parties/index.d.ts +0 -2
- package/dist/third-parties/index.js +0 -2
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { getGoogleClientId } from '../../services/account.js';
|
|
3
|
+
import { getGoogleClientIdQueryKey } from '../../utils/queryKeys.js';
|
|
4
|
+
export const useGoogleClientIdQuery = (options) => {
|
|
5
|
+
const query = useQuery({
|
|
6
|
+
...options,
|
|
7
|
+
queryKey: getGoogleClientIdQueryKey(),
|
|
8
|
+
queryFn: async ({ signal }) => {
|
|
9
|
+
return await getGoogleClientId({ signal });
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
return query;
|
|
13
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useMutation } from '@tanstack/react-query';
|
|
2
|
+
import invariant from 'tiny-invariant';
|
|
3
|
+
import { unlinkGoogle } from '../../services/account.js';
|
|
4
|
+
import { getQueryClient } from '../../utils/getQueryClient.js';
|
|
5
|
+
import { getUnlinkGoogleMutationKey } from '../../utils/mutationKeys.js';
|
|
6
|
+
import { getAccountQueryKey } from '../../utils/queryKeys.js';
|
|
7
|
+
import { getSession } from '../services/getSession.js';
|
|
8
|
+
export const useUnlinkGoogleMutation = (config) => {
|
|
9
|
+
const queryClient = getQueryClient();
|
|
10
|
+
return useMutation({
|
|
11
|
+
...config,
|
|
12
|
+
mutationKey: getUnlinkGoogleMutationKey(),
|
|
13
|
+
mutationFn: async (input) => {
|
|
14
|
+
const session = await getSession();
|
|
15
|
+
invariant(session.status === 'authenticated');
|
|
16
|
+
await unlinkGoogle(input.id, {
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: `Bearer ${session.token}`,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
queryClient.setQueryData(getAccountQueryKey(), (prev) => {
|
|
22
|
+
if (!prev)
|
|
23
|
+
return prev;
|
|
24
|
+
return {
|
|
25
|
+
...prev,
|
|
26
|
+
googleId: null,
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
4
|
+
import { GoogleOAuthProvider, useGoogleLogin } from '@react-oauth/google';
|
|
4
5
|
import { differenceInYears, format } from 'date-fns';
|
|
5
6
|
import Image from 'next/image';
|
|
6
7
|
import { useEffect } from 'react';
|
|
@@ -8,10 +9,14 @@ import { useForm } from 'react-hook-form';
|
|
|
8
9
|
import { twMerge } from 'tailwind-merge';
|
|
9
10
|
import { z } from 'zod';
|
|
10
11
|
import { useAccountQuery } from '../../client/hooks/useAccountQuery.js';
|
|
12
|
+
import { useGoogleClientIdQuery } from '../../client/hooks/useGoogleClientIdQuery.js';
|
|
11
13
|
import { useLocaleInfo } from '../../client/hooks/useLocaleInfo.js';
|
|
12
14
|
import { useMobileNumberParser } from '../../client/hooks/useMobileNumberParser.js';
|
|
15
|
+
import { useSessionQuery } from '../../client/hooks/useSessionQuery.js';
|
|
16
|
+
import { useUnlinkGoogleMutation } from '../../client/hooks/useUnlinkGoogleMutation.js';
|
|
13
17
|
import { useUpdateAccountMutation } from '../../client/hooks/useUpdateAccountMutation.js';
|
|
14
18
|
import { toaster } from '../../client/utils/toaster.js';
|
|
19
|
+
import { AUTH_ENDPOINT, PLATFORM_CODE } from '../../constants/index.js';
|
|
15
20
|
import { FacebookIcon } from '../../icons/FacebookIcon.js';
|
|
16
21
|
import { GoogleIcon } from '../../icons/GoogleIcon.js';
|
|
17
22
|
import avatar from '../../images/placeholder-avatar.png';
|
|
@@ -19,12 +24,12 @@ import { Button } from '../../ui/Button/index.js';
|
|
|
19
24
|
import { Field } from '../../ui/Field/index.js';
|
|
20
25
|
import { IconButton } from '../../ui/IconButton/index.js';
|
|
21
26
|
export function AccountInfo(props) {
|
|
22
|
-
return (_jsxs("div", { className: twMerge('space-y-3xl', props.className), children: [_jsx(ProfileInfo, {}), _jsx(ContactInfo, {}), _jsx(PersonalInfo, {}), _jsx(SSO, {})] }));
|
|
27
|
+
return (_jsxs("div", { className: twMerge('space-y-3xl', props.className), children: [_jsx(ProfileInfo, {}), _jsx(ContactInfo, {}), _jsx(PersonalInfo, {}), _jsx(SSO, { google: props.googleSso, facebook: props.facebookSso })] }));
|
|
23
28
|
}
|
|
24
29
|
function ProfileInfo() {
|
|
25
30
|
const accountQuery = useAccountQuery();
|
|
26
31
|
const account = accountQuery.data;
|
|
27
|
-
return (_jsxs("div", { children: [_jsx("h2", { className: "font-semibold text-sm text-text-secondary-700", children: "Profile Info" }), _jsx("div", { className: "mt-5 rounded-xl border border-border-secondary bg-bg-primary-alt", children: _jsx("div", { className:
|
|
32
|
+
return (_jsxs("div", { children: [_jsx("h2", { className: "font-semibold text-sm text-text-secondary-700", children: "Profile Info" }), _jsx("div", { className: "mt-5 rounded-xl border border-border-secondary bg-bg-primary-alt", children: _jsx("div", { className: "border-border-secondary px-4 py-5", children: _jsxs("div", { className: "flex items-center gap-xl", children: [_jsx(Image, { src: avatar, alt: "", width: 80, height: 80, className: "size-14 shrink-0 rounded-md object-cover" }), _jsxs("div", { children: [_jsx("h3", { className: "font-semibold text-lg text-text-secondary-700 leading-tight", children: account?.name }), _jsx("p", { className: "text-text-tertiary-600 leading-tight", children: account?.id })] })] }) }) })] }));
|
|
28
33
|
}
|
|
29
34
|
function PersonalInfo() {
|
|
30
35
|
const accountQuery = useAccountQuery();
|
|
@@ -144,6 +149,29 @@ function ContactInfo() {
|
|
|
144
149
|
});
|
|
145
150
|
}), children: [_jsxs("div", { className: "px-xl py-5 lg:px-3xl lg:py-5", children: [_jsxs(Field.Root, { invalid: !!form.formState.errors.mobileNumber, children: [_jsx(Field.Label, { children: "Mobile Number" }), _jsxs("div", { className: "relative", children: [_jsx(localeInfo.country.flag, { className: "-translate-y-1/2 pointer-events-none absolute top-1/2 left-3.5 size-5" }), _jsx(Field.Input, { className: "pl-10.5", readOnly: account?.mobileNumber != null, ...form.register('mobileNumber') })] }), _jsx(Field.ErrorText, { children: form.formState.errors.mobileNumber?.message })] }), _jsxs(Field.Root, { className: "mt-6", invalid: !!form.formState.errors.emailAddress, children: [_jsx(Field.Label, { children: "Email address" }), _jsx(Field.Input, { ...form.register('emailAddress') }), _jsx(Field.ErrorText, { children: form.formState.errors.emailAddress?.message })] })] }), form.formState.isDirty && (_jsxs("div", { className: "flex justify-end gap-lg border-border-secondary border-t px-xl py-lg lg:px-3xl lg:py-xl", children: [_jsx(Button, { size: "sm", variant: "outline", fullWidth: false, disabled: updateAccountMutation.isPending, onClick: () => form.reset(), children: "Cancel" }), _jsx(Button, { type: "submit", size: "sm", fullWidth: false, disabled: updateAccountMutation.isPending || !form.formState.isValid, children: "Save Changes" })] }))] })] }));
|
|
146
151
|
}
|
|
147
|
-
function SSO() {
|
|
148
|
-
|
|
152
|
+
function SSO({ google, facebook }) {
|
|
153
|
+
const googleClientIdQuery = useGoogleClientIdQuery({ enabled: !!google });
|
|
154
|
+
const googleClientId = googleClientIdQuery.data;
|
|
155
|
+
if (!facebook && !google)
|
|
156
|
+
return null;
|
|
157
|
+
return (_jsxs("div", { children: [_jsx("h2", { className: "font-semibold text-sm text-text-secondary-700", children: "Account Connections" }), _jsxs("div", { className: "mt-5 rounded-xl border border-border-secondary bg-bg-primary-alt px-4 py-5 shadow-xs", children: [googleClientId && (_jsx(GoogleOAuthProvider, { clientId: googleClientId, children: _jsx(LinkGoogleAccount, {}) })), facebook /* FIXME: replace with facebookClientId or something */ && (_jsxs("div", { className: "mt-6 flex items-center", children: [_jsxs("div", { className: "flex grow items-center gap-sm", children: [_jsx(IconButton, { variant: "outline", colorScheme: "gray", children: _jsx(FacebookIcon, { className: "size-6" }) }), _jsxs("div", { children: [_jsx("p", { className: "font-medium text-sm leading-tight", children: "Facebook" }), _jsx("p", { className: "mt-xs text-text-success-primary-600 text-xs leading-tight", children: "Connected" })] })] }), _jsx("button", { type: "button", className: "font-semibold text-button-tertiary-error-fg text-sm", children: "Disconnect" })] }))] })] }));
|
|
149
158
|
}
|
|
159
|
+
const LinkGoogleAccount = () => {
|
|
160
|
+
const accountQuery = useAccountQuery();
|
|
161
|
+
const account = accountQuery.data;
|
|
162
|
+
const sessionQuery = useSessionQuery();
|
|
163
|
+
const session = sessionQuery.data;
|
|
164
|
+
const unlinkGoogleAccountMutation = useUnlinkGoogleMutation();
|
|
165
|
+
const loginGoogle = useGoogleLogin({
|
|
166
|
+
flow: 'auth-code',
|
|
167
|
+
state: encodeURIComponent(`${window.location.origin},${PLATFORM_CODE},${session?.token}`),
|
|
168
|
+
ux_mode: 'redirect',
|
|
169
|
+
redirect_uri: `${AUTH_ENDPOINT}/google/link`,
|
|
170
|
+
scope: 'openid profile email phone',
|
|
171
|
+
});
|
|
172
|
+
if (!account)
|
|
173
|
+
return null;
|
|
174
|
+
return (_jsxs("div", { className: "flex items-center gap-sm", children: [_jsxs("div", { className: "flex grow items-center gap-sm", children: [_jsx(IconButton, { variant: "outline", colorScheme: "gray", children: _jsx(GoogleIcon, { className: "size-6" }) }), !account.googleId ? (_jsxs("div", { children: [_jsx("p", { className: "font-medium text-sm leading-tight", children: "Google" }), _jsx("p", { className: "mt-xs text-text-secondary-700 text-xs leading-tight", children: "Not Connected" })] })) : (_jsxs("div", { children: [_jsx("p", { className: "font-medium text-sm leading-tight", children: "Google" }), _jsx("p", { className: "mt-xs text-text-success-primary-600 text-xs leading-tight", children: "Connected" })] }))] }), account.googleId ? (_jsx("button", { type: "button", onClick: () => {
|
|
175
|
+
unlinkGoogleAccountMutation.mutate({ id: account.id });
|
|
176
|
+
}, disabled: unlinkGoogleAccountMutation.isPending, className: "font-semibold text-button-tertiary-error-fg text-sm", children: "Disconnect" })) : (_jsx(Button, { onClick: () => loginGoogle(), fullWidth: false, children: "Connect" }))] }));
|
|
177
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function LinkGoogleAccountObserver(): null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useSearchParams } from 'next/navigation';
|
|
3
|
+
import { useTimeout } from 'usehooks-ts';
|
|
4
|
+
import { toaster } from '../../client/utils/toaster.js';
|
|
5
|
+
export function LinkGoogleAccountObserver() {
|
|
6
|
+
const searchParams = useSearchParams();
|
|
7
|
+
const code = searchParams.get('message') ?? searchParams.get('status');
|
|
8
|
+
useTimeout(() => {
|
|
9
|
+
if (code === 'duplicate') {
|
|
10
|
+
return toaster.error({
|
|
11
|
+
title: 'Duplicate Account',
|
|
12
|
+
description: 'An account with this email already exists. Please try signing in instead.',
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
if (code === 'linked') {
|
|
16
|
+
return toaster.success({
|
|
17
|
+
title: 'Google Account Linked Successfully',
|
|
18
|
+
description: 'Your Google account has been successfully connected.',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}, code ? 100 : null);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
@@ -7,7 +7,9 @@ import { prefetchSessionQuery } from '../../server/utils/prefetchSessionQuery.js
|
|
|
7
7
|
import { prefetchWalletQuery } from '../../server/utils/prefetchWalletQuery.js';
|
|
8
8
|
import { getQueryClient } from '../../utils/getQueryClient.js';
|
|
9
9
|
import { FeatureFlag } from './FeatureFlag.js';
|
|
10
|
+
import { LinkGoogleAccountObserver } from './LinkGoogleAccountObserver.js';
|
|
10
11
|
import { Providers } from './Providers.js';
|
|
12
|
+
import { SessionWatcher } from './SessionWatcher.js';
|
|
11
13
|
import { SetupCellxpertCxd } from './SetupCellxpertCxd.js';
|
|
12
14
|
import { SetupDomain } from './SetupDomain.js';
|
|
13
15
|
import { Snackbar } from './Snackbar.js';
|
|
@@ -19,5 +21,5 @@ export async function PortalProvider({ recaptchaSiteKey, children, }) {
|
|
|
19
21
|
prefetchAccountQuery(),
|
|
20
22
|
prefetchWalletQuery(),
|
|
21
23
|
]);
|
|
22
|
-
return (_jsxs(Fragment, { children: [_jsx(Providers, { recaptchaSiteKey: recaptchaSiteKey, children: _jsxs(HydrationBoundary, { state: dehydrate(queryClient), children: [children, _jsx(Suspense, { children: _jsx(SetupDomain, {}) }), _jsx(Suspense, { children: _jsx(SetupCellxpertCxd, {}) })] }) }), _jsx(Snackbar, {}), _jsx(Suspense, { children: _jsx(FeatureFlag, {}) })] }));
|
|
24
|
+
return (_jsxs(Fragment, { children: [_jsx(Providers, { recaptchaSiteKey: recaptchaSiteKey, children: _jsxs(HydrationBoundary, { state: dehydrate(queryClient), children: [children, _jsx(SessionWatcher, {}), _jsx(Suspense, { children: _jsx(SetupDomain, {}) }), _jsx(Suspense, { children: _jsx(SetupCellxpertCxd, {}) })] }) }), _jsx(Snackbar, {}), _jsx(Suspense, { children: _jsx(LinkGoogleAccountObserver, {}) }), _jsx(Suspense, { children: _jsx(FeatureFlag, {}) })] }));
|
|
23
25
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function SessionWatcher(): null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useRouter } from 'next/navigation';
|
|
3
|
+
import { useTimeout } from 'usehooks-ts';
|
|
4
|
+
import { useSessionHealthQuery } from '../../client/hooks/useSessionHealthQuery.js';
|
|
5
|
+
import { useSessionQuery } from '../../client/hooks/useSessionQuery.js';
|
|
6
|
+
import { useSignOutMutation } from '../../client/hooks/useSignOutMutation.js';
|
|
7
|
+
export function SessionWatcher() {
|
|
8
|
+
const router = useRouter();
|
|
9
|
+
const sessionQuery = useSessionQuery();
|
|
10
|
+
const sessionHealthQuery = useSessionHealthQuery({
|
|
11
|
+
enabled: sessionQuery.data?.status === 'authenticated',
|
|
12
|
+
refetchInterval: 1000 * 5,
|
|
13
|
+
});
|
|
14
|
+
const signOutMutation = useSignOutMutation({
|
|
15
|
+
onSuccess() {
|
|
16
|
+
router.refresh();
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
const healthy = sessionHealthQuery.data ?? true;
|
|
20
|
+
useTimeout(() => signOutMutation.mutate(), !healthy ? 250 : null);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
2
|
+
export interface GoogleSignInTriggerProps extends ComponentPropsWithRef<'button'> {
|
|
3
|
+
asChild?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const GoogleSignInTrigger: (props: GoogleSignInTriggerProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ark } from '@ark-ui/react';
|
|
4
|
+
import { GoogleOAuthProvider, useGoogleLogin } from '@react-oauth/google';
|
|
5
|
+
import { useGoogleClientIdQuery } from '../../client/hooks/useGoogleClientIdQuery.js';
|
|
6
|
+
import { useSignInMutation } from '../../client/hooks/useSignInMutation.js';
|
|
7
|
+
import { toaster } from '../../client/utils/toaster.js';
|
|
8
|
+
import { AUTH_ENDPOINT, PLATFORM_CODE } from '../../constants/index.js';
|
|
9
|
+
import { GoogleIcon } from '../../icons/GoogleIcon.js';
|
|
10
|
+
import { httpRequest } from '../../services/httpRequest.js';
|
|
11
|
+
import { Button } from '../../ui/Button/index.js';
|
|
12
|
+
export const GoogleSignInTrigger = (props) => {
|
|
13
|
+
const googleClientIdQuery = useGoogleClientIdQuery();
|
|
14
|
+
const googleClientId = googleClientIdQuery.data;
|
|
15
|
+
if (!googleClientId)
|
|
16
|
+
return null;
|
|
17
|
+
return (_jsx(GoogleOAuthProvider, { clientId: googleClientId, children: _jsx(Trigger, { ...props }) }));
|
|
18
|
+
};
|
|
19
|
+
const Trigger = ({ children, asChild, onClick, ...props }) => {
|
|
20
|
+
const signIn = useSignInMutation();
|
|
21
|
+
const signInGoogle = useGoogleLogin({
|
|
22
|
+
flow: 'auth-code',
|
|
23
|
+
scope: 'openid profile email phone',
|
|
24
|
+
state: encodeURIComponent(`${window.location.origin},${PLATFORM_CODE}`),
|
|
25
|
+
ux_mode: 'popup',
|
|
26
|
+
redirect_uri: 'postmessage',
|
|
27
|
+
onSuccess: async (cred) => {
|
|
28
|
+
const { token } = await httpRequest.json(`${AUTH_ENDPOINT}/google/auth?state=${cred.state}&code=${cred.code}&scope=${cred.scope}`);
|
|
29
|
+
signIn.mutate({
|
|
30
|
+
type: 'SOCIALS',
|
|
31
|
+
token,
|
|
32
|
+
}, {
|
|
33
|
+
onError: () => {
|
|
34
|
+
toaster.error({
|
|
35
|
+
title: 'Account Not Found',
|
|
36
|
+
description: 'The Google account you used isn’t connected to any existing account in our system. Please connect it to continue.',
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
return (_jsx(ark.button, { type: "button", onClick: (e) => {
|
|
43
|
+
onClick?.(e);
|
|
44
|
+
signInGoogle();
|
|
45
|
+
}, asChild: !children ? true : asChild, ...props, children: children ?? (_jsxs(Button, { variant: "outline", colorScheme: "gray", className: "bg-bg-primary", children: [_jsx(GoogleIcon, { className: "size-6" }), "Continue with Google"] })) }));
|
|
46
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
3
|
+
import dynamic from 'next/dynamic';
|
|
3
4
|
import Image from 'next/image';
|
|
4
5
|
import { useRouter } from 'next/navigation';
|
|
5
6
|
import { useRef } from 'react';
|
|
@@ -22,6 +23,10 @@ import { Checkbox } from '../../ui/Checkbox/index.js';
|
|
|
22
23
|
import { Field } from '../../ui/Field/index.js';
|
|
23
24
|
import { PinInput } from '../../ui/PinInput/index.js';
|
|
24
25
|
import { useSignInContext, useSignInPropsContext } from './SignInContext.js';
|
|
26
|
+
const GoogleSignInButton = dynamic(() => import('./GoogleSignInTrigger.js').then((m) => m.GoogleSignInTrigger), {
|
|
27
|
+
ssr: false,
|
|
28
|
+
loading: () => null,
|
|
29
|
+
});
|
|
25
30
|
export function MobileNumberSignIn() {
|
|
26
31
|
const signInProps = useSignInPropsContext();
|
|
27
32
|
const router = useRouter();
|
|
@@ -148,7 +153,7 @@ export function MobileNumberSignIn() {
|
|
|
148
153
|
globalStore.responsibleGaming.setNext('SIGN_IN');
|
|
149
154
|
globalStore.signIn.setOpen(false);
|
|
150
155
|
}
|
|
151
|
-
}, children: "Responsible Gaming" }), ' ', "guidelines."] }), _jsx(Checkbox.HiddenInput, {})] }), _jsx(Field.ErrorText, { className: "ml-6 text-xs", children: o.fieldState.error?.message })] })) })] }), signInProps.showPublicPlayProhibition && (_jsxs("div", { className: "mt-3xl text-center text-sm", children: ["Prohibition to play in open and public places", _jsxs("div", { className: "mx-auto mt-5 flex h-13 w-fit items-center justify-center gap-3xl rounded-[60px] bg-[#1D0201] px-5 py-2", children: [_jsx("div", { className: "flex size-5xl items-center justify-center overflow-hidden rounded-full bg-white", children: _jsx(Image, { src: pagcorLogo, alt: "", draggable: false, height: 62, width: 186, className: "h-9.5 w-auto object-contain" }) }), _jsx(Image, { src: responsibleGamingLogo, alt: "", height: 62, width: 186, className: "h-10 w-auto", draggable: false })] })] })), _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: "Don't have an account?" }), _jsx("button", { type: "submit", className: "font-semibold text-button-tertiary-fg", onClick: () => {
|
|
156
|
+
}, children: "Responsible Gaming" }), ' ', "guidelines."] }), _jsx(Checkbox.HiddenInput, {})] }), _jsx(Field.ErrorText, { className: "ml-6 text-xs", children: o.fieldState.error?.message })] })) })] }), signInProps.showPublicPlayProhibition && (_jsxs("div", { className: "mt-3xl text-center text-sm", children: ["Prohibition to play in open and public places", _jsxs("div", { className: "mx-auto mt-5 flex h-13 w-fit items-center justify-center gap-3xl rounded-[60px] bg-[#1D0201] px-5 py-2", children: [_jsx("div", { className: "flex size-5xl items-center justify-center overflow-hidden rounded-full bg-white", children: _jsx(Image, { src: pagcorLogo, alt: "", draggable: false, height: 62, width: 186, className: "h-9.5 w-auto object-contain" }) }), _jsx(Image, { src: responsibleGamingLogo, alt: "", height: 62, width: 186, className: "h-10 w-auto", draggable: false })] })] })), _jsxs("div", { className: "mt-6 flex items-center gap-2", children: [_jsx("div", { className: "h-px flex-grow bg-text-tertiary-600/50" }), _jsx("span", { className: "font-semibold text-sm text-text-tertiary-600", children: "Log in directly with" }), _jsx("div", { className: "h-px flex-grow bg-text-tertiary-600/50" })] }), _jsx("div", { className: "mt-6", children: signInProps.googleSso && _jsx(GoogleSignInButton, {}) }), _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: "Don't have an account?" }), _jsx("button", { type: "submit", className: "font-semibold text-button-tertiary-fg", onClick: () => {
|
|
152
157
|
globalStore.signIn.setOpen(false);
|
|
153
158
|
globalStore.signUp.setOpen(true);
|
|
154
159
|
}, children: "Sign up" })] })] })), context.step === 2 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "mt-xl text-center font-semibold text-lg", children: "Check your Phone" }), _jsxs("p", { className: "mt-xs text-center text-sm text-text-secondary-700", 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 }) => {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ComponentPropsWithRef } from 'react';
|
|
2
|
-
interface SignUpTriggerProps extends ComponentPropsWithRef<'button'> {
|
|
2
|
+
export interface SignUpTriggerProps extends ComponentPropsWithRef<'button'> {
|
|
3
3
|
asChild?: boolean;
|
|
4
4
|
}
|
|
5
5
|
export declare function SignUpTrigger(props: SignUpTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export {};
|
|
@@ -22,9 +22,17 @@ export async function getSession(request) {
|
|
|
22
22
|
}
|
|
23
23
|
if (!accessToken) {
|
|
24
24
|
try {
|
|
25
|
+
const forwarded = request.headers.get('x-forwarded-for');
|
|
26
|
+
const ipaddress = forwarded?.split(',')[0];
|
|
25
27
|
const data = await refreshSession({
|
|
26
28
|
headers: {
|
|
27
29
|
Authorization: `Bearer ${refreshToken}`,
|
|
30
|
+
...(ipaddress && {
|
|
31
|
+
'X-Forwarded-For': ipaddress,
|
|
32
|
+
}),
|
|
33
|
+
...(ipaddress && {
|
|
34
|
+
'X-User-Real-Ip': ipaddress,
|
|
35
|
+
}),
|
|
28
36
|
},
|
|
29
37
|
});
|
|
30
38
|
const response = NextResponse.json({
|
package/dist/handlers/index.d.ts
CHANGED
|
@@ -6,13 +6,6 @@ interface Context {
|
|
|
6
6
|
params: Promise<Params>;
|
|
7
7
|
}
|
|
8
8
|
export declare const GET: (req: NextRequest, { params }: Context) => Promise<NextResponse<{
|
|
9
|
-
ok: false;
|
|
10
|
-
message: string;
|
|
11
|
-
__error?: unknown;
|
|
12
|
-
} | {
|
|
13
|
-
ok: true;
|
|
14
|
-
data: import("../types").Session;
|
|
15
|
-
}> | NextResponse<{
|
|
16
9
|
ok: true;
|
|
17
10
|
data?: never;
|
|
18
11
|
} | {
|
|
@@ -26,6 +19,13 @@ export declare const GET: (req: NextRequest, { params }: Context) => Promise<Nex
|
|
|
26
19
|
} | {
|
|
27
20
|
ok: true;
|
|
28
21
|
data: Record<string, unknown>;
|
|
22
|
+
}> | NextResponse<{
|
|
23
|
+
ok: false;
|
|
24
|
+
message: string;
|
|
25
|
+
__error?: unknown;
|
|
26
|
+
} | {
|
|
27
|
+
ok: true;
|
|
28
|
+
data: import("../types").Session;
|
|
29
29
|
}>>;
|
|
30
30
|
export declare const DELETE: (req: NextRequest, { params }: Context) => Promise<NextResponse<{
|
|
31
31
|
ok: true;
|
|
@@ -361,6 +361,16 @@ export interface GoogleClientIdQuery {
|
|
|
361
361
|
googleClientId?: string | null;
|
|
362
362
|
}
|
|
363
363
|
export declare const getGoogleClientId: (options?: GraphQLRequestOptions) => Promise<string | null>;
|
|
364
|
+
export interface UnlinkGoogleMutation {
|
|
365
|
+
unlinkGoogle: boolean;
|
|
366
|
+
}
|
|
367
|
+
export interface UnlinkGoogleInput {
|
|
368
|
+
id: string;
|
|
369
|
+
}
|
|
370
|
+
export interface UnlinkGoogleMutationVariables {
|
|
371
|
+
input: UnlinkGoogleInput;
|
|
372
|
+
}
|
|
373
|
+
export declare const unlinkGoogle: (id: string, options?: GraphQLRequestOptions) => Promise<void>;
|
|
364
374
|
export interface GenerateSumsubVerificationTokenMutation {
|
|
365
375
|
generateSumsubVerificationToken: string;
|
|
366
376
|
}
|
package/dist/services/account.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cache } from 'react';
|
|
2
2
|
import { ACCOUNT_GRAPHQL_ENDPOINT } from '../constants/index.js';
|
|
3
3
|
import { graphqlRequest } from './graphqlRequest.js';
|
|
4
|
-
import { ANNOUNCEMENTS, APPROVE_MEMBER_VERIFICATION__NEXT, CREATE_MEMBER_VERIFICATION, CREATE_MEMBER_VERIFICATION__NEXT, DELETE_MEMBER_ACCOUNT, GENERATE_SUMSUB_VERIFICATION_TOKEN, GOOGLE_CLIENT_ID, MEMBER_ACCOUNT, MEMBER_VERIFICATION, PAYMENT_SETTINGS, POINTS_CLUB_SETTINGS, PROFILE_COMPLETION, REFERRAL_CODE, REGISTER_MAYA_MEMBER_ACCOUNT, REGISTER_MEMBER_ACCOUNT, REGISTER_MEMBER_ACCOUNT__NEXT, REGISTER_MEMBER_ACCOUNT_BY_MOBILE_NUMBER, REGISTER_MEMBER_ACCOUNT_BY_NAME, REGISTER_MEMBER_ACCOUNT_VIA_MOBILE, RESET_PASSWORD, UPDATE_MEMBER_ACCOUNT, UPDATE_MEMBER_VERIFICATION, UPDATE_MEMBER_VERIFICATION__NEXT, UPDATE_REFERRAL_CODE, VERIFY_MOBILE_NUMBER, } from './queries.js';
|
|
4
|
+
import { ANNOUNCEMENTS, APPROVE_MEMBER_VERIFICATION__NEXT, CREATE_MEMBER_VERIFICATION, CREATE_MEMBER_VERIFICATION__NEXT, DELETE_MEMBER_ACCOUNT, GENERATE_SUMSUB_VERIFICATION_TOKEN, GOOGLE_CLIENT_ID, MEMBER_ACCOUNT, MEMBER_VERIFICATION, PAYMENT_SETTINGS, POINTS_CLUB_SETTINGS, PROFILE_COMPLETION, REFERRAL_CODE, REGISTER_MAYA_MEMBER_ACCOUNT, REGISTER_MEMBER_ACCOUNT, REGISTER_MEMBER_ACCOUNT__NEXT, REGISTER_MEMBER_ACCOUNT_BY_MOBILE_NUMBER, REGISTER_MEMBER_ACCOUNT_BY_NAME, REGISTER_MEMBER_ACCOUNT_VIA_MOBILE, RESET_PASSWORD, UNLINK_GOOGLE, UPDATE_MEMBER_ACCOUNT, UPDATE_MEMBER_VERIFICATION, UPDATE_MEMBER_VERIFICATION__NEXT, UPDATE_REFERRAL_CODE, VERIFY_MOBILE_NUMBER, } from './queries.js';
|
|
5
5
|
import { sha256 } from './sha256.js';
|
|
6
6
|
export const getMemberAccount = cache(async (options) => {
|
|
7
7
|
const res = await graphqlRequest(ACCOUNT_GRAPHQL_ENDPOINT, MEMBER_ACCOUNT, undefined, options);
|
|
@@ -257,6 +257,9 @@ export const getGoogleClientId = cache(async (options) => {
|
|
|
257
257
|
const res = await graphqlRequest(ACCOUNT_GRAPHQL_ENDPOINT, GOOGLE_CLIENT_ID, undefined, options);
|
|
258
258
|
return res.googleClientId ?? null;
|
|
259
259
|
});
|
|
260
|
+
export const unlinkGoogle = cache(async (id, options) => {
|
|
261
|
+
await graphqlRequest(ACCOUNT_GRAPHQL_ENDPOINT, UNLINK_GOOGLE, { input: { id } }, options);
|
|
262
|
+
});
|
|
260
263
|
export const generateSumsubVerificationToken = async (options) => {
|
|
261
264
|
const res = await graphqlRequest(ACCOUNT_GRAPHQL_ENDPOINT, GENERATE_SUMSUB_VERIFICATION_TOKEN, undefined, options);
|
|
262
265
|
return res.generateSumsubVerificationToken;
|
|
@@ -67,7 +67,7 @@ export declare const MEMBER = "\n query Member {\n member {\n dateTimeL
|
|
|
67
67
|
/**
|
|
68
68
|
* _aka_ `Query.self`
|
|
69
69
|
*/
|
|
70
|
-
export declare const MEMBER_ACCOUNT = "\n query MemberAccount {\n memberAccount: self {\n ... on MemberAccount {\n id\n name\n status\n realName\n emailAddress\n mobileNumber\n birthDay\n verified\n verificationStatus\n nickName\n validId\n mobileNumberVerified\n mobileNumberVerificationRequired\n transactionPassword\n secretAnswerSubmitted\n dateTimeCreated\n dateTimeLastUpdated\n }\n }\n }\n";
|
|
70
|
+
export declare const MEMBER_ACCOUNT = "\n query MemberAccount {\n memberAccount: self {\n ... on MemberAccount {\n id\n name\n status\n realName\n emailAddress\n mobileNumber\n birthDay\n verified\n verificationStatus\n nickName\n validId\n mobileNumberVerified\n mobileNumberVerificationRequired\n transactionPassword\n secretAnswerSubmitted\n dateTimeCreated\n dateTimeLastUpdated\n googleId\n }\n }\n }\n";
|
|
71
71
|
export declare const MEMBER_VERIFICATION = "\n \n fragment FileFragment on File {\n id\n url\n status\n }\n\n\n query MemberVerification {\n memberAccount: self {\n ... on MemberAccount {\n verification {\n id\n status\n address\n permanentAddress\n sourceOfIncome\n natureOfWork\n nationality\n placeOfBirth\n idFrontImage {\n ...FileFragment\n }\n selfieImage {\n ...FileFragment\n }\n }\n }\n }\n }\n";
|
|
72
72
|
export declare const REGISTER_MEMBER_ACCOUNT = "\n mutation RegisterMemberAccount(\n $input: RegisterMemberAccountInput!\n $referralCode: String\n $verificationCode: String\n $reCAPTCHAResponse: String\n ) {\n registerMemberAccount(\n input: $input\n referralCode: $referralCode\n verificationCode: $verificationCode\n reCAPTCHAResponse: $reCAPTCHAResponse\n ) {\n ... on AccountNameNotAvailableError {\n name: __typename\n message\n }\n ... on InvalidPlatformError {\n name: __typename\n message\n }\n ... on InvalidPlatformError {\n name: __typename\n message\n }\n ... on InvalidReCAPTCHAResponseError {\n name: __typename\n message\n }\n ... on InvalidSMSVerificationCodeError {\n name: __typename\n message\n }\n ... on MinimumAgeRequirementError {\n name: __typename\n message\n }\n ... on MobileNumberNotAvailableError {\n name: __typename\n message\n }\n ... on ReCAPTCHAVerificationFailedError {\n name: __typename\n message\n }\n }\n }\n";
|
|
73
73
|
export declare const REGISTER_MEMBER_ACCOUNT_BY_NAME = "\n mutation RegisterMemberAccountByName(\n $input: RegisterMemberAccountByNameInput!\n $reCAPTCHAResponse: String!\n ) {\n registerMemberAccountByName(\n input: $input\n reCAPTCHAResponse: $reCAPTCHAResponse\n ) {\n ... on AccountNameNotAvailableError {\n name: __typename\n message\n }\n ... on InvalidPlatformError {\n name: __typename\n message\n }\n ... on InvalidReCAPTCHAResponseError {\n name: __typename\n message\n }\n }\n }\n";
|
|
@@ -125,6 +125,7 @@ export declare const MARK_GAME_AS_FAVORITE = "\n mutation MarkGameAsFavorite($i
|
|
|
125
125
|
export declare const UNMARK_GAME_AS_FAVORITE = "\n mutation UnmarkGameAsFavorite($input: UnmarkGameAsFavoriteInput!) {\n unmarkGameAsFavorite(input: $input)\n }\n";
|
|
126
126
|
export declare const FAVORITE_GAMES = "\n query FavoriteGames {\n favoriteGames {\n ... on Game {\n id\n name\n type\n provider\n }\n }\n }\n";
|
|
127
127
|
export declare const GOOGLE_CLIENT_ID = "\n query GoogleClientId {\n googleClientId\n }\n";
|
|
128
|
+
export declare const UNLINK_GOOGLE = "\n mutation UnlinkGoogle($input: UnlinkGoogleInput!) {\n unlinkGoogle(input: $input)\n }\n";
|
|
128
129
|
export declare const TOURNAMENTS = "\n query Tournaments(\n $first: Int\n $after: Cursor\n $filter: TournamentFilterInput\n ) {\n tournaments(first: $first, after: $after, filter: $filter) {\n totalCount\n pageInfo {\n hasNextPage\n endCursor\n }\n edges {\n node {\n ... on MultiplierTournament {\n id\n type\n name\n winnersCount\n status\n description\n activationStartDateTime\n activationEndDateTime\n topPayouts {\n id\n multiplier\n amount\n member {\n id\n name\n }\n }\n currentLeaderboard {\n totalCount\n edges {\n node {\n ... on TournamentLeaderboard {\n id\n username\n multiplier\n dateTimeCreated\n }\n }\n }\n }\n previousLeaderboard {\n totalCount\n edges {\n node {\n ... on TournamentLeaderboard {\n id\n username\n multiplier\n dateTimeCreated\n }\n }\n }\n }\n enabledGameProviders\n frequency\n mode\n mobileBanner {\n id\n url\n mimeType\n }\n webBanner {\n id\n url\n mimeType\n }\n rewardSettings\n }\n }\n }\n }\n }\n";
|
|
129
130
|
export declare const TOURNAMENTS_COUNT = "\n query TournamentsCount($filter: TournamentFilterInput) {\n tournaments(filter: $filter) {\n totalCount\n }\n }\n";
|
|
130
131
|
export declare const GENERATE_SUMSUB_VERIFICATION_TOKEN = "\n mutation GenerateSumsubVerificationToken {\n generateSumsubVerificationToken\n }\n";
|
package/dist/services/queries.js
CHANGED
|
@@ -1529,6 +1529,7 @@ export const MEMBER_ACCOUNT = /* GraphQL */ `
|
|
|
1529
1529
|
secretAnswerSubmitted
|
|
1530
1530
|
dateTimeCreated
|
|
1531
1531
|
dateTimeLastUpdated
|
|
1532
|
+
googleId
|
|
1532
1533
|
}
|
|
1533
1534
|
}
|
|
1534
1535
|
}
|
|
@@ -2557,6 +2558,11 @@ export const GOOGLE_CLIENT_ID = /* GraphQL */ `
|
|
|
2557
2558
|
googleClientId
|
|
2558
2559
|
}
|
|
2559
2560
|
`;
|
|
2561
|
+
export const UNLINK_GOOGLE = /* GraphQL */ `
|
|
2562
|
+
mutation UnlinkGoogle($input: UnlinkGoogleInput!) {
|
|
2563
|
+
unlinkGoogle(input: $input)
|
|
2564
|
+
}
|
|
2565
|
+
`;
|
|
2560
2566
|
export const TOURNAMENTS = /* GraphQL */ `
|
|
2561
2567
|
query Tournaments(
|
|
2562
2568
|
$first: Int
|
package/dist/types/index.d.ts
CHANGED