@opexa/portal-components 0.0.324 → 0.0.326

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.
Files changed (75) hide show
  1. package/dist/client/hooks/useSignUpMutation.d.ts +1 -1
  2. package/dist/client/hooks/useSignUpMutation.js +6 -1
  3. package/dist/client/hooks/useUpdateSessionMutation.js +12 -4
  4. package/dist/client/services/getSession.js +1 -1
  5. package/dist/client/services/updateSession.d.ts +1 -0
  6. package/dist/components/Banner/Banner.client.d.ts +12 -0
  7. package/dist/components/Banner/Banner.client.js +49 -0
  8. package/dist/components/Disclaimer/DisclaimerV1.d.ts +1 -0
  9. package/dist/components/Disclaimer/DisclaimerV1.js +8 -9
  10. package/dist/components/PortalProvider/PortalProvider.js +4 -5
  11. package/dist/components/PortalProvider/SetupCellxpertCxd.d.ts +1 -0
  12. package/dist/components/PortalProvider/SetupCellxpertCxd.js +28 -0
  13. package/dist/components/SignIn/utils.d.ts +8 -0
  14. package/dist/components/SignIn/utils.js +26 -0
  15. package/dist/constants/Branches.d.ts +2 -0
  16. package/dist/constants/Branches.js +42 -0
  17. package/dist/constants/StorageKey.d.ts +1 -0
  18. package/dist/constants/StorageKey.js +1 -0
  19. package/dist/handlers/getSession.d.ts +1 -1
  20. package/dist/handlers/getSession.js +5 -2
  21. package/dist/handlers/index.d.ts +7 -7
  22. package/dist/handlers/patchSession.js +10 -2
  23. package/dist/handlers/postAuthenticate.js +3 -1
  24. package/dist/handlers/postSession.js +3 -1
  25. package/dist/middleware.d.ts +1 -1
  26. package/dist/middleware.js +4 -0
  27. package/dist/services/account.d.ts +2 -1
  28. package/dist/third-parties/FacebookPixel/FacebookPixel.d.ts +4 -0
  29. package/dist/third-parties/FacebookPixel/FacebookPixel.js +4 -0
  30. package/dist/third-parties/FacebookPixel/api.d.ts +0 -0
  31. package/dist/third-parties/FacebookPixel/api.js +1 -0
  32. package/dist/third-parties/FacebookPixel/index.d.ts +1 -0
  33. package/dist/third-parties/FacebookPixel/index.js +1 -0
  34. package/dist/third-parties/GoogleRecaptcha/GoogleRecaptcha.d.ts +4 -0
  35. package/dist/third-parties/GoogleRecaptcha/GoogleRecaptcha.js +4 -0
  36. package/dist/third-parties/GoogleRecaptcha/api.d.ts +0 -0
  37. package/dist/third-parties/GoogleRecaptcha/api.js +1 -0
  38. package/dist/third-parties/GoogleRecaptcha/index.d.ts +1 -0
  39. package/dist/third-parties/GoogleRecaptcha/index.js +1 -0
  40. package/dist/third-parties/index.d.ts +2 -0
  41. package/dist/third-parties/index.js +2 -0
  42. package/dist/types/index.d.ts +5 -3
  43. package/dist/ui/Badge/Badge.d.ts +12 -12
  44. package/dist/ui/Badge/badge.anatomy.d.ts +1 -1
  45. package/dist/ui/Badge/badge.recipe.d.ts +3 -3
  46. package/dist/ui/Carousel/Carousel.d.ts +45 -45
  47. package/dist/ui/Carousel/carousel.recipe.d.ts +5 -5
  48. package/dist/ui/Checkbox/Checkbox.d.ts +23 -23
  49. package/dist/ui/Checkbox/checkbox.recipe.d.ts +3 -3
  50. package/dist/ui/Clipboard/Clipboard.d.ts +18 -18
  51. package/dist/ui/Clipboard/clipboard.recipe.d.ts +3 -3
  52. package/dist/ui/Collapsible/Collapsible.d.ts +20 -20
  53. package/dist/ui/Collapsible/collapsible.recipe.d.ts +5 -5
  54. package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
  55. package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
  56. package/dist/ui/Dialog/Dialog.d.ts +88 -88
  57. package/dist/ui/Dialog/dialog.recipe.d.ts +8 -8
  58. package/dist/ui/Menu/Menu.d.ts +144 -144
  59. package/dist/ui/Menu/menu.recipe.d.ts +8 -8
  60. package/dist/ui/PasswordInput/PasswordInput.d.ts +18 -18
  61. package/dist/ui/PasswordInput/passwordInput.recipe.d.ts +3 -3
  62. package/dist/ui/Popover/Popover.d.ts +55 -55
  63. package/dist/ui/Popover/popover.recipe.d.ts +5 -5
  64. package/dist/ui/Progress/Progress.d.ts +27 -27
  65. package/dist/ui/Progress/progress.recipe.d.ts +3 -3
  66. package/dist/ui/QrCode/QrCode.d.ts +25 -25
  67. package/dist/ui/QrCode/qrCode.recipe.d.ts +5 -5
  68. package/dist/ui/Select/Select.d.ts +45 -45
  69. package/dist/ui/Select/select.recipe.d.ts +3 -3
  70. package/dist/ui/Table/Table.d.ts +21 -21
  71. package/dist/ui/Table/table.anatomy.d.ts +1 -1
  72. package/dist/ui/Table/table.recipe.d.ts +3 -3
  73. package/dist/ui/Tabs/Tabs.d.ts +15 -15
  74. package/dist/ui/Tabs/tabs.recipe.d.ts +3 -3
  75. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { type RegisterMemberAccountViaMobileInput } from '../../services/account';
2
2
  import type { Mutation } from '../../types';
3
- export interface SignUpMutationInput extends Omit<RegisterMemberAccountViaMobileInput, 'domain'> {
3
+ export interface SignUpMutationInput extends Omit<RegisterMemberAccountViaMobileInput, 'domain' | 'cellxpertCxd'> {
4
4
  }
5
5
  export declare const useSignUpMutation: Mutation<void, SignUpMutationInput>;
@@ -8,7 +8,12 @@ export const useSignUpMutation = (config) => {
8
8
  mutationKey: getSignUpMutationKey(),
9
9
  mutationFn: async (input) => {
10
10
  const session = await getSession();
11
- return await registerMemberAccountViaMobile(input, {
11
+ return await registerMemberAccountViaMobile({
12
+ ...input,
13
+ ...(session.cellxpertCxd && {
14
+ cellxpertCxd: session.cellxpertCxd,
15
+ }),
16
+ }, {
12
17
  headers: {
13
18
  ...(session.domain && {
14
19
  Domain: session.domain,
@@ -13,11 +13,19 @@ export const useUpdateSessionMutation = (config) => {
13
13
  queryClient.setQueryData(getSessionQueryKey(), (prev) => {
14
14
  if (!prev)
15
15
  return prev;
16
- if (!input.domain)
17
- return prev;
16
+ const domain = input.domain ?? prev.domain;
17
+ const cellxpertCxd = input.cellxpertCxd ?? prev.cellxpertCxd;
18
+ if (prev.status === 'unauthenticated') {
19
+ return {
20
+ status: 'unauthenticated',
21
+ domain,
22
+ cellxpertCxd,
23
+ };
24
+ }
18
25
  return {
19
- ...prev,
20
- ...input,
26
+ status: 'authenticated',
27
+ token: prev.token,
28
+ domain,
21
29
  };
22
30
  });
23
31
  return ok;
@@ -2,5 +2,5 @@ import { cache } from 'react';
2
2
  import { httpRequest, } from '../../services/httpRequest.js';
3
3
  export const getSession = cache(async (options) => {
4
4
  const res = await httpRequest.json('/api/sessions', options);
5
- return res.ok ? res.data : { status: 'unauthenticated', domain: null };
5
+ return res.ok ? res.data : { status: 'unauthenticated' };
6
6
  });
@@ -1,5 +1,6 @@
1
1
  import { type HttpRequestOptions } from '../../services/httpRequest';
2
2
  export interface UpdateSessionInput {
3
3
  domain?: string;
4
+ cellxpertCxd?: string;
4
5
  }
5
6
  export declare const updateSession: (input: UpdateSessionInput, options?: HttpRequestOptions) => Promise<boolean>;
@@ -0,0 +1,12 @@
1
+ import type { ImageProps } from 'next/image';
2
+ export interface BannerEntry {
3
+ src: ImageProps['src'];
4
+ redirectUrl?: string;
5
+ }
6
+ export interface BannerProps {
7
+ banners: BannerEntry[];
8
+ imageWidth?: number | [mobile: number, desktop: number];
9
+ imageHeight?: number | [mobile: number, desktop: number];
10
+ className?: string;
11
+ }
12
+ export declare function Banner__client(props: BannerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import emblaCarouselAutoplay from 'embla-carousel-autoplay';
4
+ import useEmblaCarousel, {} from 'embla-carousel-react';
5
+ import isMobile from 'is-mobile';
6
+ import Image from 'next/image';
7
+ import Link from 'next/link';
8
+ import { Fragment, useEffect, useState } from 'react';
9
+ import { twMerge } from 'tailwind-merge';
10
+ import { dataAttr } from '../../utils/dataAttr.js';
11
+ export function Banner__client(props) {
12
+ const [emblaRef, emblaApi] = useEmblaCarousel({
13
+ loop: true,
14
+ align: 'start',
15
+ }, [
16
+ emblaCarouselAutoplay({
17
+ playOnInit: true,
18
+ delay: 5000,
19
+ }),
20
+ ]);
21
+ const [currentIndex, setCurrentIndex] = useState(0);
22
+ useEffect(() => {
23
+ function handler(detail) {
24
+ setCurrentIndex(detail?.selectedScrollSnap() ?? 0);
25
+ }
26
+ emblaApi?.on('scroll', handler);
27
+ emblaApi?.on('init', handler);
28
+ return () => {
29
+ emblaApi?.on('init', handler);
30
+ emblaApi?.off('scroll', handler);
31
+ };
32
+ }, [emblaApi]);
33
+ const imageWidth = !props.imageWidth
34
+ ? [400, 1200]
35
+ : Array.isArray(props.imageWidth)
36
+ ? props.imageWidth
37
+ : [props.imageWidth, props.imageWidth];
38
+ const imageHeight = !props.imageHeight
39
+ ? [225, 300]
40
+ : Array.isArray(props.imageHeight)
41
+ ? props.imageHeight
42
+ : [props.imageHeight, props.imageHeight];
43
+ return (_jsxs("div", { className: twMerge('relative', props.className), children: [_jsx("div", { ref: emblaRef, className: "overflow-hidden", children: _jsx("div", { className: "flex gap-2", children: props.banners.map((banner, index) => {
44
+ const img = (_jsx(Image, { src: banner.src, alt: "", width: isMobile() ? imageWidth[0] : imageWidth[1], height: isMobile() ? imageHeight[0] : imageHeight[1], className: "block h-auto w-full", priority: index === 0 }));
45
+ return (_jsx(Fragment, { children: !banner.redirectUrl ? (_jsx("div", { className: "w-full shrink-0", children: img })) : (_jsx(Link, { href: banner.redirectUrl, className: "block w-full shrink-0", "aria-label": `Open ${banner.redirectUrl}`, children: img })) }, index));
46
+ }) }) }), _jsx("div", { className: "absolute bottom-lg left-1/2 flex w-fit -translate-x-1/2 gap-2", children: props.banners.map((_, index) => (_jsx("button", { type: "button", className: "ui-active:bg-brand-500 bg-gray-300 size-3 shrink-0 rounded-full border border-white transition-all duration-300 ui-active:w-9", onClick: () => {
47
+ emblaApi?.scrollTo(index);
48
+ }, "aria-label": `Go to slide ${index + 1}`, "data-active": dataAttr(index === currentIndex) }, index))) })] }));
49
+ }
@@ -2,6 +2,7 @@ import type { ImageProps } from 'next/image';
2
2
  export interface DisclaimerV1Props {
3
3
  version: '1';
4
4
  logo: ImageProps['src'];
5
+ siteName: string;
5
6
  termsOfUseUrl?: string;
6
7
  }
7
8
  export declare function DisclaimerV1(props: DisclaimerV1Props): import("react/jsx-runtime").JSX.Element;
@@ -3,7 +3,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import Image from 'next/image';
4
4
  import Link from 'next/link';
5
5
  import { useRef, useState } from 'react';
6
- import { useTimeout } from 'usehooks-ts';
7
6
  import { useShallow } from 'zustand/shallow';
8
7
  import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
9
8
  import { AlertCircleIcon } from '../../icons/AlertCircleIcon.js';
@@ -25,7 +24,6 @@ export function DisclaimerV1(props) {
25
24
  })));
26
25
  const checked = globalStore.termsOfUse.accepted;
27
26
  const [warn, setWarn] = useState(false);
28
- useTimeout(() => setWarn(false), warn ? 5000 : null);
29
27
  return (_jsx(Dialog.Root, { open: disclaimer.open, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, initialFocusEl: () => acceptTriggerRef.current, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+1)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+2)]", children: _jsxs(Dialog.Content, { className: "flex h-full w-full flex-col items-start overflow-y-auto p-3xl lg:mx-auto lg:h-auto lg:w-[400px] lg:rounded-xl", children: [_jsx("button", { type: "button", onClick: () => {
30
28
  if (!checked) {
31
29
  setWarn(true);
@@ -33,13 +31,14 @@ export function DisclaimerV1(props) {
33
31
  else {
34
32
  disclaimer.close();
35
33
  }
36
- }, className: "absolute top-6.5 right-6.5", "aria-label": "Close", children: _jsx(XIcon, { className: "size-6 text-text-quinary" }) }), _jsx(Image, { src: props.logo, alt: "", width: 142, height: 30, className: "mx-auto h-auto w-[8.875rem]", draggable: false }), _jsxs("div", { className: "w-full grow", children: [_jsxs("div", { className: "mt-5 flex items-center justify-center gap-3xl", children: [_jsx(Image, { src: pagcorLogo, alt: "", height: 74, width: 88, className: "h-[5.5rem] w-auto shrink-0", draggable: false }), _jsx(Image, { src: responsibleGamingLogo, alt: "", height: 62, width: 185, className: "h-[3.875rem] w-auto shrink-0", draggable: false })] }), _jsx("p", { className: "mt-4 text-center text-sm", children: "The following individuals are prohibited from registering or participating in this online gaming platform." }), _jsx("div", { className: "mt-5", children: _jsx("ul", { className: "space-y-1", children: items.map((item, index) => (_jsxs("li", { className: "flex items-start gap-md text-sm text-text-secondary-700", children: [_jsx("div", { className: "mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full bg-bg-brand-solid", children: _jsx("div", { className: "size-1.5 rounded-full bg-cyan-950" }) }), item] }, index))) }) }), _jsx(Field.Root, { invalid: warn, className: "mt-2xl", children: _jsxs(Checkbox.Root, { checked: checked, onCheckedChange: (e) => {
37
- if (e.checked === 'indeterminate')
38
- return;
39
- globalStore.termsOfUse.setAccepted(e.checked);
40
- }, children: [_jsx(Checkbox.Control, { children: _jsx(Checkbox.Indicator, { asChild: true, children: _jsx(CheckIcon, {}) }) }), _jsxs("div", { className: "!text-sm !leading-tight", children: [_jsxs(Checkbox.Label, { className: "text-sm leading-tight", children: ["I am at least 21 years of age, I accept the", ' ', _jsx(Link, { href: props.termsOfUseUrl ?? '/terms-of-use', className: "text-brand-400 underline underline-offset-2", onClick: () => {
41
- globalStore.termsOfUse.setOpen(false);
42
- }, children: "Terms of Use" }), ' ', "and I am not playing in open or public space."] }), _jsxs(Field.ErrorText, { className: "mt-0 flex items-center gap-1 text-xs leading-none", children: [_jsx(AlertCircleIcon, { className: "size-3.5 text-error-400" }), "You must accept the Terms of Use to continue."] })] }), _jsx(Checkbox.HiddenInput, {})] }) }), _jsx("p", { className: "mt-2xl text-center text-sm", children: "Funds or credits in the account of any individual found ineligible to participate will be forfeited and turned over to the government as required by law." })] }), _jsx(Button, { ref: acceptTriggerRef, type: "button", className: "mt-4xl", onClick: disclaimer.close, disabled: !checked, children: "Accept" }), _jsx(Button, { variant: "outline", type: "button", className: "mt-lg", onClick: () => {
34
+ }, className: "absolute top-6.5 right-6.5", "aria-label": "Close", children: _jsx(XIcon, { className: "size-6 text-text-quinary" }) }), _jsx(Image, { src: props.logo, alt: "", width: 142, height: 30, className: "mx-auto h-auto w-[8.875rem]", draggable: false }), _jsxs("div", { className: "w-full grow", children: [_jsxs("div", { className: "mt-5 flex items-center justify-center gap-3xl", children: [_jsx(Image, { src: pagcorLogo, alt: "", height: 74, width: 88, className: "h-[5.5rem] w-auto shrink-0", draggable: false }), _jsx(Image, { src: responsibleGamingLogo, alt: "", height: 62, width: 185, className: "h-[3.875rem] w-auto shrink-0", draggable: false })] }), _jsx("p", { className: "mt-4 text-center text-sm", children: "The following individuals are prohibited from registering or participating in this online gaming platform." }), _jsx("div", { className: "mt-5", children: _jsx("ul", { className: "space-y-1", children: items.map((item, index) => (_jsxs("li", { className: "flex items-start gap-md text-sm text-text-secondary-700", children: [_jsx("div", { className: "mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full bg-bg-brand-solid", children: _jsx("div", { className: "size-1.5 rounded-full bg-cyan-950" }) }), item] }, index))) }) }), _jsxs(Field.Root, { invalid: warn, className: "mt-2xl", children: [_jsxs(Checkbox.Root, { checked: checked, onCheckedChange: (e) => {
35
+ if (e.checked === 'indeterminate')
36
+ return;
37
+ globalStore.termsOfUse.setAccepted(e.checked);
38
+ setWarn(!e.checked);
39
+ }, children: [_jsx(Checkbox.Control, { children: _jsx(Checkbox.Indicator, { asChild: true, children: _jsx(CheckIcon, {}) }) }), _jsxs(Checkbox.Label, { className: "text-sm", children: ["I am at least 21 years of age, I accept the", ' ', _jsx(Link, { href: props.termsOfUseUrl ?? '/terms-of-use', className: "text-brand-400 underline underline-offset-2", onClick: () => {
40
+ globalStore.termsOfUse.setOpen(false);
41
+ }, children: "Terms of Use" }), ' ', "and I am not playing in open or public space."] }), _jsx(Checkbox.HiddenInput, {})] }), _jsxs(Field.ErrorText, { className: "!mt-2xl flex items-center justify-center gap-2 text-error-600 text-sm", children: [_jsx(AlertCircleIcon, { className: "size-4 shrink-0 text-error-600" }), "Please agree to ", props.siteName, "\u2019s Terms of Use to proceed."] })] }), _jsx("p", { className: "mt-2xl text-center text-sm", children: "Funds or credits in the account of any individual found ineligible to participate will be forfeited and turned over to the government as required by law." })] }), _jsx(Button, { ref: acceptTriggerRef, type: "button", className: "mt-4xl", onClick: disclaimer.close, disabled: !checked, children: "Accept" }), _jsx(Button, { variant: "outline", type: "button", className: "mt-lg", onClick: () => {
43
42
  if (!checked) {
44
43
  setWarn(true);
45
44
  }
@@ -1,7 +1,6 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { dehydrate, HydrationBoundary } from '@tanstack/react-query';
3
- import { Suspense } from 'react';
4
- import { INTERNALS__REPORT_WEB_VITALS } from '../../constants/index.js';
3
+ import { Fragment, Suspense } from 'react';
5
4
  import { prefetchAccountQuery } from '../../server/utils/prefetchAccountQuery.js';
6
5
  import { prefetchPlatformQuery } from '../../server/utils/prefetchPlatformQuery.js';
7
6
  import { prefetchSessionQuery } from '../../server/utils/prefetchSessionQuery.js';
@@ -9,9 +8,9 @@ import { prefetchWalletQuery } from '../../server/utils/prefetchWalletQuery.js';
9
8
  import { getQueryClient } from '../../utils/getQueryClient.js';
10
9
  import { FeatureFlag } from './FeatureFlag.js';
11
10
  import { Providers } from './Providers.js';
11
+ import { SetupCellxpertCxd } from './SetupCellxpertCxd.js';
12
12
  import { SetupDomain } from './SetupDomain.js';
13
13
  import { Snackbar } from './Snackbar.js';
14
- import { WebVitals } from './WebVitals.js';
15
14
  export async function PortalProvider({ recaptchaSiteKey, children, }) {
16
15
  const queryClient = getQueryClient();
17
16
  await Promise.allSettled([
@@ -20,5 +19,5 @@ export async function PortalProvider({ recaptchaSiteKey, children, }) {
20
19
  prefetchAccountQuery(),
21
20
  prefetchWalletQuery(),
22
21
  ]);
23
- return (_jsxs(_Fragment, { children: [INTERNALS__REPORT_WEB_VITALS && _jsx(WebVitals, {}), _jsx(Providers, { recaptchaSiteKey: recaptchaSiteKey, children: _jsxs(HydrationBoundary, { state: dehydrate(queryClient), children: [children, _jsx(Suspense, { fallback: null, children: _jsx(SetupDomain, {}) })] }) }), _jsx(Snackbar, {}), _jsx(Suspense, { fallback: null, children: _jsx(FeatureFlag, {}) })] }));
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
23
  }
@@ -0,0 +1 @@
1
+ export declare function SetupCellxpertCxd(): null;
@@ -0,0 +1,28 @@
1
+ 'use client';
2
+ import { useSearchParams } from 'next/navigation';
3
+ import { useTimeout } from 'usehooks-ts';
4
+ import { z } from 'zod';
5
+ import { useSessionQuery } from '../../client/hooks/useSessionQuery.js';
6
+ import { useUpdateSessionMutation } from '../../client/hooks/useUpdateSessionMutation.js';
7
+ const CellxpertCxdSchema = z
8
+ .string()
9
+ .min(200)
10
+ .trim()
11
+ .optional()
12
+ .nullable()
13
+ .catch(null);
14
+ export function SetupCellxpertCxd() {
15
+ const query = useSessionQuery();
16
+ const mutation = useUpdateSessionMutation();
17
+ const params = useSearchParams();
18
+ useTimeout(() => {
19
+ const oldValue = query.data?.cellxpertCxd;
20
+ const newValue = CellxpertCxdSchema.parse(params.get('cxd'));
21
+ if (oldValue === newValue)
22
+ return;
23
+ if (!newValue)
24
+ return;
25
+ mutation.mutate({ cellxpertCxd: newValue });
26
+ }, query.data?.status !== 'unauthenticated' ? null : 1000);
27
+ return null;
28
+ }
@@ -0,0 +1,8 @@
1
+ type Options = {
2
+ accountName?: string;
3
+ siteName?: string;
4
+ signInOptions?: 'MOBILE_NUMBER' | 'NAME_AND_PASSWORD';
5
+ };
6
+ export type ErrorCode = 'MEMBER_ACCOUNT_BLACKLISTED' | 'MEMBER_ACCOUNT_SUSPENDED' | 'INVALID_RECAPTCHA_RESPONSE' | 'MEMBER_NOT_FOUND' | 'RATE_LIMIT_REACH' | 'NOT_READY_TO_SEND_VERIFICATION_ERROR' | 'Forbidden';
7
+ export declare function getFriendlyErrorMessage(code: ErrorCode, options?: Options): string;
8
+ export {};
@@ -0,0 +1,26 @@
1
+ export function getFriendlyErrorMessage(code, options) {
2
+ const accountName = options?.accountName ?? '';
3
+ const siteName = options?.siteName ?? '';
4
+ const signInOptions = options?.signInOptions ?? 'NAME_AND_PASSWORD';
5
+ switch (code) {
6
+ case 'MEMBER_ACCOUNT_BLACKLISTED':
7
+ return `Your account ${accountName} has been blacklisted due to a serious violation of our policies. For more information or to appeal, please contact the ${siteName} Chat Support team.`;
8
+ case 'MEMBER_ACCOUNT_SUSPENDED':
9
+ return `Your account ${accountName} has been temporarily suspended. Please reach out to the ${siteName} Chat Support team to learn more and get help with resolving the issue.`;
10
+ case 'INVALID_RECAPTCHA_RESPONSE':
11
+ return 'Invalid reCAPTCHA response';
12
+ case 'MEMBER_NOT_FOUND':
13
+ return 'Account not found. Please check your username and try again.';
14
+ case 'RATE_LIMIT_REACH':
15
+ return 'Rate limit exceeded';
16
+ case 'NOT_READY_TO_SEND_VERIFICATION_ERROR':
17
+ return 'Your account is not ready to send verification requests. Please try again later.';
18
+ case 'Forbidden':
19
+ if (signInOptions === 'MOBILE_NUMBER') {
20
+ return 'Invalid verification code. Please check the code and try again.';
21
+ }
22
+ return 'Invalid username or password, please try again.';
23
+ default:
24
+ return 'Something went wrong. Please try again later.';
25
+ }
26
+ }
@@ -0,0 +1,2 @@
1
+ import type { Branch } from '../types';
2
+ export declare const BRANCHES: Branch[];
@@ -0,0 +1,42 @@
1
+ export const BRANCHES = [
2
+ {
3
+ code: 'BRCAL',
4
+ name: 'Bingo Republic 2nd floor Primark Center Deparo St., Caloocan City',
5
+ },
6
+ {
7
+ code: 'BRNAG',
8
+ name: 'Bingo Republic 3rd floor Robinsons Mall, Naga City, Camarines Sur',
9
+ },
10
+ {
11
+ code: 'BRANT',
12
+ name: 'Bingo Republic 2nd floor Robinsons Mall, San Vicente,Antique',
13
+ },
14
+ {
15
+ code: 'BRCLA',
16
+ name: 'Clark',
17
+ },
18
+ {
19
+ code: 'BRLAG',
20
+ name: 'Laguna',
21
+ },
22
+ {
23
+ code: 'BREAS',
24
+ name: 'Eastwood City, Quezon City',
25
+ },
26
+ {
27
+ code: 'BRMAR',
28
+ name: 'Bingo ng Bayan 4th floor Marikina Public Market, Marikina City',
29
+ },
30
+ {
31
+ code: 'BRILO',
32
+ name: 'Iloilo',
33
+ },
34
+ {
35
+ code: 'BRFIM',
36
+ name: 'Fisher Mall,Quezon City',
37
+ },
38
+ {
39
+ code: 'BRCAC',
40
+ name: 'Villa Caceres Hotel, Naga City,Camsur',
41
+ },
42
+ ];
@@ -2,3 +2,4 @@ export declare const ACCESS_TOKEN_COOKIE_NAME: string;
2
2
  export declare const REFRESH_TOKEN_COOKIE_NAME: string;
3
3
  export declare const DOMAIN_COOKIE_NAME: string;
4
4
  export declare const FEATURE_FLAG_LOCAL_STORAGE_KEY: string;
5
+ export declare const CELLXPERT_CXD_COOKIE_NAME: string;
@@ -2,3 +2,4 @@ export const ACCESS_TOKEN_COOKIE_NAME = 'WebPortalAuthAccessToken';
2
2
  export const REFRESH_TOKEN_COOKIE_NAME = 'WebPortalAuthRefreshToken';
3
3
  export const DOMAIN_COOKIE_NAME = 'WebPortalDomain';
4
4
  export const FEATURE_FLAG_LOCAL_STORAGE_KEY = 'WebPortalFeatureFlag';
5
+ export const CELLXPERT_CXD_COOKIE_NAME = 'WebPortalCellxpertCxd';
@@ -1,4 +1,4 @@
1
- import { NextResponse, type NextRequest } from 'next/server';
1
+ import { type NextRequest, NextResponse } from 'next/server';
2
2
  import type { Session } from '../types';
3
3
  export declare function getSession(request: NextRequest): Promise<NextResponse<{
4
4
  ok: false;
@@ -1,17 +1,19 @@
1
1
  import { addMinutes } from 'date-fns';
2
2
  import { NextResponse } from 'next/server';
3
- import { ACCESS_TOKEN_COOKIE_NAME, DOMAIN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME, } from '../constants/index.js';
3
+ import { ACCESS_TOKEN_COOKIE_NAME, CELLXPERT_CXD_COOKIE_NAME, DOMAIN_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME, } from '../constants/index.js';
4
4
  import { refreshSession } from '../services/auth.js';
5
5
  export async function getSession(request) {
6
6
  const accessToken = request.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value;
7
7
  const refreshToken = request.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value;
8
8
  const domain = request.cookies.get(DOMAIN_COOKIE_NAME)?.value;
9
+ const cellxpertCxd = request.cookies.get(CELLXPERT_CXD_COOKIE_NAME)?.value;
9
10
  if (!refreshToken) {
10
11
  const response = NextResponse.json({
11
12
  ok: true,
12
13
  data: {
13
- domain,
14
14
  status: 'unauthenticated',
15
+ domain,
16
+ cellxpertCxd,
15
17
  },
16
18
  });
17
19
  response.cookies.delete(ACCESS_TOKEN_COOKIE_NAME);
@@ -46,6 +48,7 @@ export async function getSession(request) {
46
48
  data: {
47
49
  status: 'unauthenticated',
48
50
  domain,
51
+ cellxpertCxd,
49
52
  },
50
53
  });
51
54
  response.cookies.delete(REFRESH_TOKEN_COOKIE_NAME);
@@ -6,26 +6,26 @@ interface Context {
6
6
  params: Promise<Params>;
7
7
  }
8
8
  export declare const GET: (req: NextRequest, { params }: Context) => Promise<NextResponse<{
9
- ok: true;
10
- data?: never;
11
- } | {
12
9
  ok: false;
13
10
  message: string;
14
11
  __error?: unknown;
12
+ } | {
13
+ ok: true;
14
+ data: import("../types").Session;
15
15
  }> | NextResponse<{
16
+ ok: true;
17
+ data?: never;
18
+ } | {
16
19
  ok: false;
17
20
  message: string;
18
21
  __error?: unknown;
19
- } | {
20
- ok: true;
21
- data: Record<string, unknown>;
22
22
  }> | NextResponse<{
23
23
  ok: false;
24
24
  message: string;
25
25
  __error?: unknown;
26
26
  } | {
27
27
  ok: true;
28
- data: import("../types").Session;
28
+ data: Record<string, unknown>;
29
29
  }>>;
30
30
  export declare const DELETE: (req: NextRequest, { params }: Context) => Promise<NextResponse<{
31
31
  ok: true;
@@ -1,9 +1,10 @@
1
- import { addDays } from 'date-fns';
1
+ import { addDays, addHours } from 'date-fns';
2
2
  import { NextResponse } from 'next/server';
3
3
  import { z } from 'zod';
4
- import { DOMAIN_COOKIE_NAME } from '../constants/index.js';
4
+ import { CELLXPERT_CXD_COOKIE_NAME, DOMAIN_COOKIE_NAME } from '../constants/index.js';
5
5
  const UpdateSessionDefinition = z.object({
6
6
  domain: z.string().optional().nullable(),
7
+ cellxpertCxd: z.string().optional().nullable(),
7
8
  });
8
9
  export async function patchSession(request) {
9
10
  const body = await request.json();
@@ -22,5 +23,12 @@ export async function patchSession(request) {
22
23
  sameSite: 'strict',
23
24
  });
24
25
  }
26
+ if (parsed.data.cellxpertCxd) {
27
+ response.cookies.set(CELLXPERT_CXD_COOKIE_NAME, parsed.data.cellxpertCxd, {
28
+ expires: addHours(new Date(), 6),
29
+ httpOnly: true,
30
+ sameSite: 'strict',
31
+ });
32
+ }
25
33
  return response;
26
34
  }
@@ -12,7 +12,9 @@ export async function postAuthenticate(request) {
12
12
  const body = await request.json();
13
13
  const parsed = AuthenticateDefinition.safeParse(body);
14
14
  const userAgent = request.headers.get('user-agent');
15
- const ipaddress = request.headers.get('x-forwarded-for');
15
+ const forwarded = request.headers.get('x-forwarded-for');
16
+ const realIp = request.headers.get('x-real-ip');
17
+ const ipaddress = forwarded?.split(',')[0] || realIp || 'unknown';
16
18
  if (!parsed.success) {
17
19
  return NextResponse.json({
18
20
  ok: false,
@@ -31,7 +31,9 @@ export async function postSession(request) {
31
31
  const body = await request.json();
32
32
  const parsed = CreateSessionDefinition.safeParse(body);
33
33
  const userAgent = request.headers.get('user-agent');
34
- const ipaddress = request.headers.get('x-forwarded-for');
34
+ const forwarded = request.headers.get('x-forwarded-for');
35
+ const realIp = request.headers.get('x-real-ip');
36
+ const ipaddress = forwarded?.split(',')[0] || realIp || 'unknown';
35
37
  if (!parsed.success) {
36
38
  return NextResponse.json({
37
39
  ok: false,
@@ -1,3 +1,3 @@
1
- import { type NextFetchEvent, NextResponse, type NextMiddleware, type NextRequest } from 'next/server';
1
+ import { type NextFetchEvent, type NextMiddleware, type NextRequest, NextResponse } from 'next/server';
2
2
  export declare const middleware: (req: NextRequest) => Promise<NextResponse>;
3
3
  export declare function extendMiddleware<T>(fn: (req: NextRequest, evt: NextFetchEvent, res: NextResponse) => NextResponse<T> | Promise<NextResponse<T>>): NextMiddleware;
@@ -6,11 +6,15 @@ export const middleware = async (req) => {
6
6
  const accessToken = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value;
7
7
  const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value;
8
8
  const res = NextResponse.next();
9
+ const forwarded = req.headers.get('x-forwarded-for');
10
+ const realIp = req.headers.get('x-real-ip');
11
+ const ipaddress = forwarded?.split(',')[0] || realIp || 'unknown';
9
12
  if (!accessToken && refreshToken) {
10
13
  try {
11
14
  const data = await refreshSession({
12
15
  headers: {
13
16
  Authorization: `Bearer ${refreshToken}`,
17
+ 'x-forwarded-for': ipaddress,
14
18
  },
15
19
  });
16
20
  res.cookies.set(ACCESS_TOKEN_COOKIE_NAME, data.accessToken, {
@@ -52,8 +52,9 @@ export interface RegisterMemberAccountViaMobileMutationVariables {
52
52
  input: {
53
53
  id: string;
54
54
  mobileNumber: string;
55
- domain?: string;
56
55
  btag?: string;
56
+ domain?: string;
57
+ cellxpertCxd?: string;
57
58
  };
58
59
  referralCode?: string;
59
60
  verificationCode?: string;
@@ -0,0 +1,4 @@
1
+ export interface FacebookPixelProps {
2
+ fbId: string;
3
+ }
4
+ export declare function FacebookPixel(props: FacebookPixelProps): null;
@@ -0,0 +1,4 @@
1
+ export function FacebookPixel(props) {
2
+ console.log(props);
3
+ return null;
4
+ }
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ export * from './FacebookPixel';
@@ -0,0 +1 @@
1
+ export * from './FacebookPixel.js';
@@ -0,0 +1,4 @@
1
+ export interface GoogleRecaptchaProps {
2
+ siteKey: string;
3
+ }
4
+ export declare function GoogleRecaptcha(props: GoogleRecaptchaProps): null;
@@ -0,0 +1,4 @@
1
+ export function GoogleRecaptcha(props) {
2
+ console.log(props);
3
+ return null;
4
+ }
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ export * from './GoogleRecaptcha';
@@ -0,0 +1 @@
1
+ export * from './GoogleRecaptcha.js';
@@ -0,0 +1,2 @@
1
+ export * from './FacebookPixel';
2
+ export * from './GoogleRecaptcha';
@@ -0,0 +1,2 @@
1
+ export * from './FacebookPixel/index.js';
2
+ export * from './GoogleRecaptcha/index.js';
@@ -7,12 +7,14 @@ import type { ImageProps } from 'next/image';
7
7
  */
8
8
  export type Session = {
9
9
  status: 'authenticated';
10
- domain?: string | null;
10
+ domain?: string;
11
11
  token: string;
12
+ cellxpertCxd?: string;
12
13
  } | {
13
14
  status: 'unauthenticated';
14
- domain?: string | null;
15
- token?: null;
15
+ domain?: string;
16
+ token?: never;
17
+ cellxpertCxd?: string;
16
18
  };
17
19
  /**
18
20
  * ------------------------------------------------------------