@opexa/portal-components 0.0.45 → 0.0.47

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 (86) hide show
  1. package/dist/client/hooks/index.d.ts +1 -0
  2. package/dist/client/hooks/index.js +1 -0
  3. package/dist/client/hooks/useCreateGCashDepositMutation.js +2 -1
  4. package/dist/client/hooks/useCreateMayaAppDepositMutation.js +2 -1
  5. package/dist/client/hooks/useCreateMayaDepositMutation.js +2 -1
  6. package/dist/client/hooks/useCreateOnlineBankDepositMutation.js +2 -1
  7. package/dist/client/hooks/useCreateQRPHDepositMutation.js +2 -1
  8. package/dist/client/hooks/useMobileNumberParser.d.ts +1 -0
  9. package/dist/client/hooks/useMobileNumberParser.js +17 -6
  10. package/dist/client/hooks/useUpdateAccountMutation.d.ts +3 -0
  11. package/dist/client/hooks/useUpdateAccountMutation.js +61 -0
  12. package/dist/components/Account/Account.js +7 -2
  13. package/dist/components/AccountInfo/AccountInfo.js +116 -8
  14. package/dist/components/AccountSecurity/AccountSecurity.js +121 -5
  15. package/dist/components/AccountVerification/AccountVerification.js +33 -6
  16. package/dist/components/BetRecords/BetRecords.js +5 -16
  17. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/OnlineBankDepositContext.d.ts +2 -2
  18. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/useOnlineBankDeposit.d.ts +1 -1
  19. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/QRPHDepositContext.d.ts +2 -2
  20. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/useQRPHDeposit.d.ts +1 -1
  21. package/dist/components/KYC/AccountVerificationContext.d.ts +14 -0
  22. package/dist/components/KYC/AccountVerificationContext.js +27 -0
  23. package/dist/components/KYC/KYC.d.ts +1 -1
  24. package/dist/components/KYC/KYC.js +12 -1
  25. package/dist/components/KYC/KYCContext.d.ts +1 -0
  26. package/dist/components/KYC/KYCContext.js +3 -0
  27. package/dist/components/KYC/KYCTrigger.d.ts +5 -0
  28. package/dist/components/KYC/KYCTrigger.js +14 -0
  29. package/dist/components/KYC/VerificationCapture.d.ts +1 -0
  30. package/dist/components/KYC/VerificationCapture.js +28 -0
  31. package/dist/components/KYC/VerificationComplete.d.ts +1 -0
  32. package/dist/components/KYC/VerificationComplete.js +9 -0
  33. package/dist/components/KYC/VerificationDetails.d.ts +1 -0
  34. package/dist/components/KYC/VerificationDetails.js +38 -0
  35. package/dist/components/KYC/index.d.ts +1 -0
  36. package/dist/components/KYC/index.js +1 -0
  37. package/dist/components/KYC/useKYC.d.ts +6 -0
  38. package/dist/components/KYC/useKYC.js +8 -0
  39. package/dist/components/Messages/Messages.d.ts +14 -1
  40. package/dist/components/Messages/Messages.js +11 -4
  41. package/dist/components/TransactionRecords/DepositRecordsTable.js +5 -17
  42. package/dist/components/TransactionRecords/TransactionRecords.js +1 -1
  43. package/dist/components/TransactionRecords/TransactionRecordsTable.js +5 -17
  44. package/dist/components/TransactionRecords/WithdrawalRecordsTable.js +5 -17
  45. package/dist/components/index.d.ts +0 -1
  46. package/dist/components/index.js +0 -1
  47. package/dist/styles/theme.css +2 -2
  48. package/dist/tsconfig.build.tsbuildinfo +1 -1
  49. package/dist/ui/AlertDialog/AlertDialog.d.ts +55 -55
  50. package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +5 -5
  51. package/dist/ui/Badge/Badge.d.ts +12 -12
  52. package/dist/ui/Badge/badge.recipe.d.ts +3 -3
  53. package/dist/ui/Checkbox/Checkbox.d.ts +23 -23
  54. package/dist/ui/Checkbox/checkbox.recipe.d.ts +3 -3
  55. package/dist/ui/Clipboard/Clipboard.d.ts +18 -18
  56. package/dist/ui/Clipboard/clipboard.recipe.d.ts +3 -3
  57. package/dist/ui/Collapsible/Collapsible.d.ts +20 -20
  58. package/dist/ui/Collapsible/collapsible.recipe.d.ts +5 -5
  59. package/dist/ui/Combobox/Combobox.d.ts +238 -238
  60. package/dist/ui/Combobox/combobox.recipe.d.ts +17 -17
  61. package/dist/ui/DatePicker/DatePicker.d.ts +192 -192
  62. package/dist/ui/DatePicker/datePicker.recipe.d.ts +8 -8
  63. package/dist/ui/Dialog/Dialog.d.ts +55 -55
  64. package/dist/ui/Dialog/dialog.recipe.d.ts +5 -5
  65. package/dist/ui/Drawer/Drawer.d.ts +33 -33
  66. package/dist/ui/Drawer/drawer.recipe.d.ts +3 -3
  67. package/dist/ui/PasswordInput/PasswordInput.d.ts +18 -18
  68. package/dist/ui/PasswordInput/passwordInput.recipe.d.ts +3 -3
  69. package/dist/ui/Popover/Popover.d.ts +88 -88
  70. package/dist/ui/Popover/popover.recipe.d.ts +8 -8
  71. package/dist/ui/Progress/Progress.d.ts +27 -27
  72. package/dist/ui/Progress/progress.recipe.d.ts +3 -3
  73. package/dist/ui/SegmentGroup/SegmentGroup.d.ts +18 -18
  74. package/dist/ui/SegmentGroup/segmentGroup.recipe.d.ts +3 -3
  75. package/dist/ui/SegmentGroup/segmentGroup.recipe.js +1 -1
  76. package/dist/ui/Select/Select.d.ts +45 -45
  77. package/dist/ui/Select/select.recipe.d.ts +3 -3
  78. package/dist/ui/Table/Table.d.ts +21 -21
  79. package/dist/ui/Table/table.recipe.d.ts +3 -3
  80. package/dist/ui/Table/table.recipe.js +1 -1
  81. package/dist/ui/Tabs/Tabs.d.ts +15 -15
  82. package/dist/ui/Tabs/tabs.recipe.d.ts +3 -3
  83. package/dist/ui/Tabs/tabs.recipe.js +1 -1
  84. package/dist/utils/queryKeys.d.ts +1 -0
  85. package/dist/utils/queryKeys.js +3 -0
  86. package/package.json +3 -3
@@ -50,5 +50,6 @@ export * from './useTournamentsQuery';
50
50
  export * from './useTransactionRecordsQuery';
51
51
  export * from './useUnmarkGameAsFavoriteMutation';
52
52
  export * from './useUnreadMessagesCountQuery';
53
+ export * from './useUpdateAccountMutation';
53
54
  export * from './useWalletQuery';
54
55
  export * from './useWithdrawalRecordsQuery';
@@ -50,5 +50,6 @@ export * from './useTournamentsQuery.js';
50
50
  export * from './useTransactionRecordsQuery.js';
51
51
  export * from './useUnmarkGameAsFavoriteMutation.js';
52
52
  export * from './useUnreadMessagesCountQuery.js';
53
+ export * from './useUpdateAccountMutation.js';
53
54
  export * from './useWalletQuery.js';
54
55
  export * from './useWithdrawalRecordsQuery.js';
@@ -3,7 +3,7 @@ import { ObjectId, ObjectType } from '@opexa/portal-sdk-core/object-id';
3
3
  import { useMutation } from '@tanstack/react-query';
4
4
  import invariant from 'tiny-invariant';
5
5
  import { ENVIRONMENT, PLATFORM_CODE } from '../../constants/index.js';
6
- import { createPoll, getCreateGCashDepositMutationKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
6
+ import { createPoll, getCreateGCashDepositMutationKey, getDepositsCountQueryKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
7
7
  import { getSession } from '../services/index.js';
8
8
  export const useCreateGCashDepositMutation = (config) => {
9
9
  const queryClient = getQueryClient();
@@ -51,6 +51,7 @@ export const useCreateGCashDepositMutation = (config) => {
51
51
  error.message = 'Failed to process GCash deposit';
52
52
  throw error;
53
53
  }
54
+ queryClient.setQueryData(getDepositsCountQueryKey(), (prev) => prev ? prev + 1 : 1);
54
55
  return res;
55
56
  },
56
57
  });
@@ -3,7 +3,7 @@ import { ObjectId, ObjectType } from '@opexa/portal-sdk-core/object-id';
3
3
  import { useMutation } from '@tanstack/react-query';
4
4
  import invariant from 'tiny-invariant';
5
5
  import { ENVIRONMENT, PLATFORM_CODE } from '../../constants/index.js';
6
- import { createPoll, getCreateMayaAppDepositMutationKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
6
+ import { createPoll, getCreateMayaAppDepositMutationKey, getDepositsCountQueryKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
7
7
  import { getSession } from '../services/index.js';
8
8
  export const useCreateMayaAppDepositMutation = (config) => {
9
9
  const queryClient = getQueryClient();
@@ -51,6 +51,7 @@ export const useCreateMayaAppDepositMutation = (config) => {
51
51
  error.message = 'Failed to process Maya deposit';
52
52
  throw error;
53
53
  }
54
+ queryClient.setQueryData(getDepositsCountQueryKey(), (prev) => prev ? prev + 1 : 1);
54
55
  return res;
55
56
  },
56
57
  });
@@ -3,7 +3,7 @@ import { ObjectId, ObjectType } from '@opexa/portal-sdk-core/object-id';
3
3
  import { useMutation } from '@tanstack/react-query';
4
4
  import invariant from 'tiny-invariant';
5
5
  import { ENVIRONMENT, PLATFORM_CODE } from '../../constants/index.js';
6
- import { createPoll, getCreateMayaDepositMutationKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
6
+ import { createPoll, getCreateMayaDepositMutationKey, getDepositsCountQueryKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
7
7
  import { getSession } from '../services/index.js';
8
8
  export const useCreateMayaDepositMutation = (config) => {
9
9
  const queryClient = getQueryClient();
@@ -51,6 +51,7 @@ export const useCreateMayaDepositMutation = (config) => {
51
51
  error.message = 'Failed to process Maya deposit';
52
52
  throw error;
53
53
  }
54
+ queryClient.setQueryData(getDepositsCountQueryKey(), (prev) => prev ? prev + 1 : 1);
54
55
  return res;
55
56
  },
56
57
  });
@@ -3,7 +3,7 @@ import { ObjectId, ObjectType } from '@opexa/portal-sdk-core/object-id';
3
3
  import { useMutation } from '@tanstack/react-query';
4
4
  import invariant from 'tiny-invariant';
5
5
  import { ENVIRONMENT, PLATFORM_CODE } from '../../constants/index.js';
6
- import { createPoll, getCreateOnlineBankDepositMutationKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
6
+ import { createPoll, getCreateOnlineBankDepositMutationKey, getDepositsCountQueryKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
7
7
  import { getSession } from '../services/index.js';
8
8
  export const useCreateOnlineBankDepositMutation = (config) => {
9
9
  const queryClient = getQueryClient();
@@ -54,6 +54,7 @@ export const useCreateOnlineBankDepositMutation = (config) => {
54
54
  error.message = 'Failed to process online bank deposit';
55
55
  throw error;
56
56
  }
57
+ queryClient.setQueryData(getDepositsCountQueryKey(), (prev) => prev ? prev + 1 : 1);
57
58
  return res;
58
59
  },
59
60
  });
@@ -3,7 +3,7 @@ import { ObjectId, ObjectType } from '@opexa/portal-sdk-core/object-id';
3
3
  import { useMutation } from '@tanstack/react-query';
4
4
  import invariant from 'tiny-invariant';
5
5
  import { ENVIRONMENT, PLATFORM_CODE } from '../../constants/index.js';
6
- import { createPoll, getCreateQRPHDepositMutationKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
6
+ import { createPoll, getCreateQRPHDepositMutationKey, getDepositsCountQueryKey, getQueryClient, getSessionQueryKey, } from '../../utils/index.js';
7
7
  import { getSession } from '../services/index.js';
8
8
  export const useCreateQRPHDepositMutation = (config) => {
9
9
  const queryClient = getQueryClient();
@@ -54,6 +54,7 @@ export const useCreateQRPHDepositMutation = (config) => {
54
54
  error.message = 'Failed to process QR PH deposit';
55
55
  throw error;
56
56
  }
57
+ queryClient.setQueryData(getDepositsCountQueryKey(), (prev) => prev ? prev + 1 : 1);
57
58
  return res;
58
59
  },
59
60
  });
@@ -5,4 +5,5 @@ export declare function useMobileNumberParser(): {
5
5
  mobileNumber: string;
6
6
  areaCode: string;
7
7
  };
8
+ equals: (mobileNumber0: unknown, mobileNumber1: unknown) => boolean;
8
9
  };
@@ -1,3 +1,4 @@
1
+ import { useCallback } from 'react';
1
2
  import { useLocaleInfo } from './useLocaleInfo.js';
2
3
  export function useMobileNumberParser() {
3
4
  const localeInfo = useLocaleInfo();
@@ -12,7 +13,7 @@ export function useMobileNumberParser() {
12
13
  * format('+639190000001'); // '+639190000001'
13
14
  * ```
14
15
  */
15
- const format = (value) => {
16
+ const format = useCallback((value) => {
16
17
  if (value.startsWith(localeInfo.mobileNumber.areaCode)) {
17
18
  return value;
18
19
  }
@@ -23,7 +24,7 @@ export function useMobileNumberParser() {
23
24
  return '+' + value;
24
25
  }
25
26
  return localeInfo.mobileNumber.areaCode + value;
26
- };
27
+ }, [localeInfo.mobileNumber.areaCode]);
27
28
  /**
28
29
  * Parses a mobile number based on the current locale information.
29
30
  * Returns the area code and the mobile number as separate values.
@@ -35,13 +36,13 @@ export function useMobileNumberParser() {
35
36
  * parse('9190000001'); // { mobileNumber: '9190000001', areaCode: '+63' }
36
37
  * ```
37
38
  */
38
- const parse = (value) => {
39
+ const parse = useCallback((value) => {
39
40
  const mobileNumber = format(value).replace(localeInfo.mobileNumber.areaCode, '');
40
41
  return {
41
42
  mobileNumber: mobileNumber,
42
43
  areaCode: localeInfo.mobileNumber.areaCode,
43
44
  };
44
- };
45
+ }, [format, localeInfo.mobileNumber.areaCode]);
45
46
  /**
46
47
  * Validates a mobile number based on the current locale information.
47
48
  * @example
@@ -52,12 +53,22 @@ export function useMobileNumberParser() {
52
53
  * validate('+639190000001'); // true
53
54
  * ```
54
55
  */
55
- const validate = (value) => {
56
+ const validate = useCallback((value) => {
56
57
  return (typeof value === 'string' && localeInfo.mobileNumber.pattern.test(value));
57
- };
58
+ }, [localeInfo.mobileNumber.pattern]);
59
+ const equals = useCallback((mobileNumber0, mobileNumber1) => {
60
+ if (!validate(mobileNumber0))
61
+ return false;
62
+ if (!validate(mobileNumber1))
63
+ return false;
64
+ const v0 = format(mobileNumber0);
65
+ const v1 = format(mobileNumber1);
66
+ return v0 === v1;
67
+ }, [format, validate]);
58
68
  return {
59
69
  validate,
60
70
  format,
61
71
  parse,
72
+ equals,
62
73
  };
63
74
  }
@@ -0,0 +1,3 @@
1
+ import { type UpdateMemberAccountDataInput } from '@opexa/portal-sdk-core';
2
+ import type { Mutation } from '../../types';
3
+ export declare const useUpdateAccountMutation: Mutation<void, UpdateMemberAccountDataInput>;
@@ -0,0 +1,61 @@
1
+ import { updateMemberAccount, } from '@opexa/portal-sdk-core';
2
+ import { useMutation } from '@tanstack/react-query';
3
+ import invariant from 'tiny-invariant';
4
+ import { ENVIRONMENT, PLATFORM_CODE } from '../../constants/index.js';
5
+ import { getAccountQueryKey, getProfileCompletionQueryKey, getQueryClient, getSessionQueryKey, getUpdateAccountMutationKey, } from '../../utils/index.js';
6
+ import { getSession } from '../services/index.js';
7
+ import { useAccountQuery } from './useAccountQuery.js';
8
+ export const useUpdateAccountMutation = (config) => {
9
+ const queryClient = getQueryClient();
10
+ const accountQuery = useAccountQuery();
11
+ return useMutation({
12
+ ...config,
13
+ mutationKey: getUpdateAccountMutationKey(),
14
+ mutationFn: async (input) => {
15
+ const session = await queryClient.fetchQuery({
16
+ queryKey: getSessionQueryKey(),
17
+ queryFn: () => getSession(),
18
+ });
19
+ invariant(session.status === 'authenticated');
20
+ invariant(accountQuery.data);
21
+ await updateMemberAccount(accountQuery.data.id, input, {
22
+ environment: ENVIRONMENT,
23
+ headers: {
24
+ 'Platform-Code': PLATFORM_CODE,
25
+ Authorization: `Bearer ${session.token}`,
26
+ },
27
+ });
28
+ queryClient.setQueryData(getAccountQueryKey(), (prev) => {
29
+ if (!prev)
30
+ return;
31
+ return {
32
+ ...prev,
33
+ name: input.name ?? prev.name,
34
+ validId: input.validId ?? prev.validId,
35
+ nickName: input.nickName ?? prev.nickName,
36
+ realName: input.realName ?? prev.realName,
37
+ birthDay: input.birthDay ?? prev.birthDay,
38
+ emailAddress: input.emailAddress ?? prev.emailAddress,
39
+ mobileNumber: input.mobileNumber ?? prev.mobileNumber,
40
+ transactionPassword: input.transactionPassword ? true : false,
41
+ secretAnswerSubmitted: input.secretAnswer ? true : false,
42
+ dateTimeLastUpdated: new Date().toISOString(),
43
+ };
44
+ });
45
+ queryClient.setQueryData(getProfileCompletionQueryKey(), (prev) => {
46
+ if (!prev)
47
+ return;
48
+ return {
49
+ ...prev,
50
+ accountPassword: input.password ? true : prev.accountPassword,
51
+ transactionPassword: input.transactionPassword
52
+ ? true
53
+ : prev.transactionPassword,
54
+ accountVerification: input.realName && input.mobileNumber
55
+ ? true
56
+ : prev.accountVerification,
57
+ };
58
+ });
59
+ },
60
+ });
61
+ };
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import { Portal } from '@ark-ui/react';
4
4
  import Image from 'next/image';
5
5
  import Link from 'next/link';
6
+ import { twMerge } from 'tailwind-merge';
6
7
  import { useShallow } from 'zustand/shallow';
7
8
  import { useAccountQuery, useGlobalStore, useLocaleInfo, useSignOutMutation, useUnreadMessagesCountQuery, useWalletQuery, } from '../../client/hooks/index.js';
8
9
  import { AlertCircleIcon, ChevronRightIcon, CoinsStacked02Icon, CoinsSwap02Icon, Gift01Icon, Logout01Icon, Settings02Icon, XIcon, } from '../../icons/index.js';
@@ -20,10 +21,14 @@ export function Account(props) {
20
21
  const betRecordsUrl = props.betRecordsUrl ?? '/bet-records';
21
22
  const transactionsUrl = props.transactionsUrl ?? '/transactions';
22
23
  const accountSettingsUrl = props.accountSettingsUrl ?? '/account';
24
+ const [mobileOffsetTop, desktopOffsetTop] = Array.isArray(props.offsetTop)
25
+ ? props.offsetTop
26
+ : [props.offsetTop ?? '0px', props.offsetTop ?? '0px'];
23
27
  return (_jsxs(_Fragment, { children: [_jsxs(Drawer.Root, { open: globalStore.account__mobile.open, onOpenChange: (details) => {
24
28
  globalStore.account__mobile.setOpen(details.open);
25
- }, lazyMount: true, unmountOnExit: true, children: [_jsx(Drawer.Trigger, { asChild: true, className: "lg:hidden", children: props.children ?? (_jsx(IconButton, { size: "sm", colorScheme: "gray", children: globalStore.account__mobile.open ? (_jsx(XIcon, {})) : (_jsx(Image, { src: avatarPlaceholder, alt: "", width: 100, height: 100, className: "size-10" })) })) }), _jsx(Portal, { children: _jsx(Drawer.Positioner, { children: _jsxs(Drawer.Content, { className: "relative top-[var(--top,0px)] flex h-[calc(100%-var(--top,0px))] w-full flex-col px-xl py-6", style: {
26
- ['--top']: props.offsetTop ?? '0px',
29
+ }, lazyMount: true, unmountOnExit: true, children: [_jsx(Drawer.Trigger, { asChild: true, className: "lg:hidden", children: props.children ?? (_jsx(IconButton, { size: "sm", colorScheme: "gray", children: globalStore.account__mobile.open ? (_jsx(XIcon, {})) : (_jsx(Image, { src: avatarPlaceholder, alt: "", width: 100, height: 100, className: "size-10" })) })) }), _jsx(Portal, { children: _jsx(Drawer.Positioner, { children: _jsxs(Drawer.Content, { className: twMerge('relative', 'flex', 'flex-col', 'top-[var(--offset-top-mobile)]', 'h-[calc(100%-var(--offset-top-mobile))]', 'w-full', 'px-xl', 'py-6', 'lg:top-[var(--offset-top-desktop)]', 'lg:h-[calc(100%-var(--offset-top-desktop))]'), style: {
30
+ ['--offset-top-mobile']: mobileOffsetTop,
31
+ ['--offset-top-desktop']: desktopOffsetTop,
27
32
  }, children: [_jsx(Profile, {}), _jsx(Wallet, {}), _jsx(Links, { rewardsUrl: rewardsUrl, betRecordsUrl: betRecordsUrl, transactionsUrl: transactionsUrl, accountSettingsUrl: accountSettingsUrl })] }) }) })] }), _jsxs(Popover.Root, { open: globalStore.account.open, onOpenChange: (details) => {
28
33
  globalStore.account.setOpen(details.open);
29
34
  }, lazyMount: true, unmountOnExit: true, positioning: {
@@ -1,10 +1,14 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { format } from 'date-fns';
4
- import { noop } from 'lodash-es';
3
+ import { zodResolver } from '@hookform/resolvers/zod';
4
+ import { differenceInYears, format } from 'date-fns';
5
5
  import Image from 'next/image';
6
+ import { useEffect } from 'react';
7
+ import { useForm } from 'react-hook-form';
6
8
  import { twMerge } from 'tailwind-merge';
7
- import { useAccountQuery, useLocaleInfo, useMobileNumberParser, } from '../../client/hooks/index.js';
9
+ import { z } from 'zod';
10
+ import { useAccountQuery, useLocaleInfo, useMobileNumberParser, useUpdateAccountMutation, } from '../../client/hooks/index.js';
11
+ import { toaster } from '../../client/utils/index.js';
8
12
  import { FacebookIcon, GoogleIcon } from '../../icons/index.js';
9
13
  import avatar from '../../images/placeholder-avatar.png';
10
14
  import { Button, Field, IconButton } from '../../ui/index.js';
@@ -19,16 +23,120 @@ function ProfileInfo() {
19
23
  function PersonalInfo() {
20
24
  const accountQuery = useAccountQuery();
21
25
  const account = accountQuery.data;
22
- return (_jsxs("div", { children: [_jsx("h2", { className: "text-text-secondary-700 text-sm font-semibold", children: "Personal Data" }), _jsxs("form", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border", children: [_jsxs("div", { className: "px-4 py-5 lg:px-3xl lg:py-5", children: [_jsxs(Field.Root, { children: [_jsx(Field.Label, { children: "Real name" }), _jsx(Field.Input, { value: account?.realName ?? '', onChange: noop, readOnly: true })] }), _jsxs(Field.Root, { className: "mt-6", children: [_jsx(Field.Label, { children: "Date of birth" }), _jsx(Field.Input, { type: "date", value: account?.birthDay ? format(account.birthDay, 'yyyy-MM-dd') : '', readOnly: true })] })] }), _jsxs("div", { className: "border-border-secondary flex justify-end gap-lg border-t px-xl py-lg lg:px-3xl lg:py-xl", children: [_jsx(Button, { size: "sm", variant: "outline", fullWidth: false, children: "Cancel" }), _jsx(Button, { size: "sm", fullWidth: false, children: "Save Changes" })] })] })] }));
26
+ const updateAccountMutation = useUpdateAccountMutation({
27
+ onSuccess() {
28
+ toaster.success({
29
+ description: 'Changes saved!',
30
+ });
31
+ },
32
+ onError(error) {
33
+ toaster.error({
34
+ description: error.message,
35
+ });
36
+ },
37
+ });
38
+ const schema = z.object({
39
+ realName: z.string().min(4).max(50).optional().or(z.literal('')),
40
+ birthDay: z
41
+ .string()
42
+ .optional()
43
+ .or(z.literal(''))
44
+ .superRefine((val, ctx) => {
45
+ if (!val)
46
+ return;
47
+ const date = new Date(val);
48
+ const age = differenceInYears(new Date(), date);
49
+ if (age < 21) {
50
+ ctx.addIssue({
51
+ code: z.ZodIssueCode.custom,
52
+ message: 'You must be at least 21 years old',
53
+ });
54
+ }
55
+ }),
56
+ });
57
+ const form = useForm({
58
+ mode: 'all',
59
+ resolver: zodResolver(schema),
60
+ defaultValues: {
61
+ birthDay: '',
62
+ realName: '',
63
+ },
64
+ });
65
+ useEffect(() => {
66
+ if (account) {
67
+ form.reset({
68
+ realName: account.realName ?? '',
69
+ birthDay: account.birthDay
70
+ ? format(account.birthDay, 'yyyy-MM-dd')
71
+ : '',
72
+ });
73
+ }
74
+ }, [account, form]);
75
+ return (_jsxs("div", { children: [_jsx("h2", { className: "text-text-secondary-700 text-sm font-semibold", children: "Personal Data" }), _jsxs("form", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border", onSubmit: form.handleSubmit((data) => {
76
+ updateAccountMutation.mutate({
77
+ realName: data.realName && account?.realName !== data.realName
78
+ ? data.realName
79
+ : undefined,
80
+ birthDay: data.birthDay && account?.birthDay !== data.birthDay
81
+ ? data.birthDay
82
+ : undefined,
83
+ });
84
+ }), children: [_jsxs("div", { className: "px-4 py-5 lg:px-3xl lg:py-5", children: [_jsxs(Field.Root, { invalid: !!form.formState.errors.realName, children: [_jsx(Field.Label, { children: "Real name" }), _jsx(Field.Input, { ...form.register('realName') }), _jsx(Field.ErrorText, { children: form.formState.errors.realName?.message })] }), _jsxs(Field.Root, { className: "mt-6", invalid: !!form.formState.errors.birthDay, children: [_jsx(Field.Label, { children: "Date of birth" }), _jsx(Field.Input, { type: "date", ...form.register('birthDay') }), _jsx(Field.ErrorText, { children: form.formState.errors.birthDay?.message })] })] }), form.formState.isDirty && (_jsxs("div", { className: "border-border-secondary flex justify-end gap-lg 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: !form.formState.isValid || updateAccountMutation.isPending, children: "Save Changes" })] }))] })] }));
23
85
  }
24
86
  function ContactInfo() {
25
87
  const localeInfo = useLocaleInfo();
26
88
  const accountQuery = useAccountQuery();
27
89
  const account = accountQuery.data;
28
- const mobileNumberParser = useMobileNumberParser();
29
- return (_jsxs("div", { children: [_jsx("h2", { className: "text-text-secondary-700 text-sm font-semibold", children: "Contact Info" }), _jsxs("form", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border", children: [_jsxs("div", { className: "px-xl py-5 lg:px-3xl lg:py-5", children: [_jsxs(Field.Root, { children: [_jsx(Field.Label, { children: "Mobile Number" }), _jsxs("div", { className: "relative", children: [_jsx(localeInfo.country.flag, { className: "pointer-events-none absolute left-3.5 top-1/2 size-5 -translate-y-1/2" }), _jsx(Field.Input, { className: "pl-10.5", value: account?.mobileNumber
30
- ? mobileNumberParser.format(account?.mobileNumber)
31
- : '', readOnly: true, onChange: noop })] })] }), _jsxs(Field.Root, { className: "mt-6", children: [_jsx(Field.Label, { children: "Email address" }), _jsx(Field.Input, { defaultValue: account?.emailAddress ?? '' })] })] }), _jsxs("div", { className: "border-border-secondary flex justify-end gap-lg border-t px-xl py-lg lg:px-3xl lg:py-xl", children: [_jsx(Button, { size: "sm", variant: "outline", fullWidth: false, children: "Cancel" }), _jsx(Button, { size: "sm", fullWidth: false, children: "Save Changes" })] })] })] }));
90
+ const { parse, format, equals } = useMobileNumberParser();
91
+ const updateAccountMutation = useUpdateAccountMutation({
92
+ onSuccess() {
93
+ toaster.success({
94
+ description: 'Changes saved!',
95
+ });
96
+ },
97
+ onError(error) {
98
+ toaster.error({
99
+ description: error.message,
100
+ });
101
+ },
102
+ });
103
+ const schema = z.object({
104
+ emailAddress: z.string().email().optional().or(z.literal('')),
105
+ mobileNumber: z
106
+ .string()
107
+ .regex(localeInfo.mobileNumber.pattern, 'Invalid mobile number')
108
+ .optional()
109
+ .or(z.literal('')),
110
+ });
111
+ const form = useForm({
112
+ mode: 'all',
113
+ resolver: zodResolver(schema),
114
+ defaultValues: {
115
+ mobileNumber: '',
116
+ emailAddress: '',
117
+ },
118
+ });
119
+ useEffect(() => {
120
+ if (account) {
121
+ form.reset({
122
+ emailAddress: account.emailAddress ?? '',
123
+ mobileNumber: account.mobileNumber
124
+ ? parse(account.mobileNumber).mobileNumber
125
+ : '',
126
+ });
127
+ }
128
+ }, [account, form, parse]);
129
+ return (_jsxs("div", { children: [_jsx("h2", { className: "text-text-secondary-700 text-sm font-semibold", children: "Contact Info" }), _jsxs("form", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border", onSubmit: form.handleSubmit((data) => {
130
+ updateAccountMutation.mutate({
131
+ emailAddress: data.emailAddress && account?.emailAddress !== data.emailAddress
132
+ ? data.emailAddress
133
+ : undefined,
134
+ mobileNumber: data.mobileNumber &&
135
+ !equals(account?.mobileNumber, data.mobileNumber)
136
+ ? format(data.mobileNumber)
137
+ : undefined,
138
+ });
139
+ }), 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: "pointer-events-none absolute left-3.5 top-1/2 size-5 -translate-y-1/2" }), _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: "border-border-secondary flex justify-end gap-lg 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" })] }))] })] }));
32
140
  }
33
141
  function SSO() {
34
142
  return (_jsxs("div", { children: [_jsx("h2", { className: "text-text-secondary-700 text-sm font-semibold", children: "Account Connections" }), _jsxs("div", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border px-4 py-5", children: [_jsxs("div", { className: "flex items-center", children: [_jsxs("div", { className: "flex grow items-center gap-sm", children: [_jsx(IconButton, { variant: "outline", colorScheme: "gray", children: _jsx(GoogleIcon, { className: "size-6" }) }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium leading-tight", children: "Google" }), _jsx("p", { className: "text-text-secondary-700 mt-xs text-xs leading-tight", children: "Not Connected" })] })] }), _jsx(Button, { fullWidth: false, children: "Connect" })] }), _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: "text-sm font-medium leading-tight", children: "Facebook" }), _jsx("p", { className: "text-text-success-primary-600 mt-xs text-xs leading-tight", children: "Connected" })] })] }), _jsx("button", { className: "text-button-tertiary-error-fg text-sm font-semibold", children: "Disconnect" })] })] })] }));
@@ -1,8 +1,12 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { ark, createListCollection, Portal } from '@ark-ui/react';
4
+ import { zodResolver } from '@hookform/resolvers/zod';
5
+ import { useForm } from 'react-hook-form';
4
6
  import { twMerge } from 'tailwind-merge';
5
- import { useProfileCompletionQuery } from '../../client/hooks/index.js';
7
+ import { z } from 'zod';
8
+ import { useProfileCompletionQuery, useUpdateAccountMutation, } from '../../client/hooks/index.js';
9
+ import { toaster } from '../../client/utils/index.js';
6
10
  import { AlertCircleIcon, CheckIcon, CheckVerified02Icon, ChevronDownIcon, EyeIcon, EyeOffIcon, } from '../../icons/index.js';
7
11
  import { Button, Field, PasswordInput, Select } from '../../ui/index.js';
8
12
  export function AccountSecurity(props) {
@@ -11,18 +15,130 @@ export function AccountSecurity(props) {
11
15
  function LoginPassword() {
12
16
  const profileCompletionQuery = useProfileCompletionQuery();
13
17
  const profileCompletion = profileCompletionQuery.data;
18
+ const updateAccountMutation = useUpdateAccountMutation({
19
+ onSuccess() {
20
+ form.reset();
21
+ toaster.success({
22
+ description: 'Changes saved!',
23
+ });
24
+ },
25
+ onError(error) {
26
+ toaster.error({
27
+ description: error.message,
28
+ });
29
+ },
30
+ });
31
+ const schema = z
32
+ .object({
33
+ password: z.string().min(8).max(150).optional().or(z.literal('')),
34
+ confirmPassword: z.string().optional(),
35
+ secretQuestion: z.enum(SECRET_QUESTIONS).nullable().optional(),
36
+ secretAnswer: z
37
+ .string()
38
+ .min(2, 'Answer is too short')
39
+ .optional()
40
+ .or(z.literal('')),
41
+ })
42
+ .superRefine((data, ctx) => {
43
+ if (data.password && data.password !== data.confirmPassword) {
44
+ ctx.addIssue({
45
+ path: ['confirmPassword'],
46
+ code: z.ZodIssueCode.custom,
47
+ message: 'Passwords do not match',
48
+ });
49
+ }
50
+ if (data.secretAnswer && !data.secretQuestion) {
51
+ ctx.addIssue({
52
+ path: ['secretQuestion'],
53
+ code: z.ZodIssueCode.custom,
54
+ message: 'Please select a security question',
55
+ });
56
+ }
57
+ if (data.secretQuestion && !data.secretAnswer) {
58
+ ctx.addIssue({
59
+ path: ['secretAnswer'],
60
+ code: z.ZodIssueCode.custom,
61
+ message: 'Please provide an answer to the security question',
62
+ });
63
+ }
64
+ });
65
+ const form = useForm({
66
+ mode: 'all',
67
+ resolver: zodResolver(schema),
68
+ defaultValues: {
69
+ password: '',
70
+ confirmPassword: '',
71
+ secretAnswer: '',
72
+ secretQuestion: null,
73
+ },
74
+ });
75
+ const secretQuestion = form.watch('secretQuestion');
14
76
  return (_jsxs("div", { children: [_jsxs("div", { className: "flex items-start gap-8", children: [_jsxs("div", { className: "grow", children: [_jsx("h2", { className: "text-text-secondary-700 text-sm font-semibold", children: "Log in password" }), _jsx("p", { className: "text-text-tertiary-600 text-sm", children: "Access your account by logging in with your name and password." })] }), _jsx(ark.svg, { asChild: true, className: twMerge('size-6', profileCompletion?.accountPassword
15
77
  ? 'text-text-success-primary'
16
- : 'text-text-warning-primary'), children: profileCompletion?.accountPassword ? (_jsx(CheckVerified02Icon, {})) : (_jsx(AlertCircleIcon, {})) })] }), _jsxs("form", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border", children: [_jsxs("div", { className: "px-xl py-5 lg:px-3xl lg:py-5", children: [_jsx(Field.Root, { children: _jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { children: "Password" }), _jsxs(PasswordInput.Control, { children: [_jsx(PasswordInput.Input, {}), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, {}), asChild: true, children: _jsx(EyeIcon, {}) }) })] })] }) }), _jsx(Field.Root, { className: "mt-6", children: _jsxs(Select.Root, { collection: secretQuestionCollection, lazyMount: true, positioning: {
17
- sameWidth: true,
18
- }, children: [_jsx(Select.Label, { children: "Security Question" }), _jsxs(Select.Trigger, { children: [_jsx(Select.ValueText, { placeholder: "Game Vendor" }), _jsx(Select.Indicator, { asChild: true, children: _jsx(ChevronDownIcon, {}) })] }), _jsx(Portal, { children: _jsx(Select.Positioner, { children: _jsx(Select.Content, { children: _jsx(Select.ItemGroup, { children: secretQuestionCollection.items.map((provider) => (_jsxs(Select.Item, { item: provider, children: [_jsx(Select.ItemText, { children: secretQuestionCollection.stringifyItem(provider) }), _jsx(Select.ItemIndicator, { asChild: true, children: _jsx(CheckIcon, {}) })] }, provider))) }) }) }) })] }) }), _jsxs(Field.Root, { className: "mt-6", children: [_jsx(Field.Label, { children: "Answer" }), _jsx(Field.Input, {})] })] }), _jsxs("div", { className: "border-border-secondary flex justify-end gap-lg border-t px-xl py-lg lg:px-3xl lg:py-xl", children: [_jsx(Button, { size: "sm", variant: "outline", fullWidth: false, children: "Cancel" }), _jsx(Button, { size: "sm", fullWidth: false, children: "Save Changes" })] })] })] }));
78
+ : 'text-text-warning-primary'), children: profileCompletion?.accountPassword ? (_jsx(CheckVerified02Icon, {})) : (_jsx(AlertCircleIcon, {})) })] }), _jsxs("form", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border", onSubmit: form.handleSubmit((data) => {
79
+ updateAccountMutation.mutate({
80
+ password: data.password ? data.password : undefined,
81
+ secretAnswer: data.secretAnswer ? data.secretAnswer : undefined,
82
+ secretQuestion: data.secretQuestion
83
+ ? data.secretQuestion
84
+ : undefined,
85
+ });
86
+ }), children: [_jsxs("div", { className: "px-xl py-5 lg:px-3xl lg:py-5", children: [_jsxs(Field.Root, { invalid: !!form.formState.errors.password, children: [_jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { children: "Password" }), _jsxs(PasswordInput.Control, { children: [_jsx(PasswordInput.Input, { ...form.register('password') }), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, {}), asChild: true, children: _jsx(EyeIcon, {}) }) })] })] }), _jsx(Field.ErrorText, { children: form.formState.errors.password?.message })] }), _jsxs(Field.Root, { className: "mt-6", invalid: !!form.formState.errors.confirmPassword, children: [_jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { children: "Confirm Password" }), _jsxs(PasswordInput.Control, { children: [_jsx(PasswordInput.Input, { ...form.register('confirmPassword') }), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, {}), asChild: true, children: _jsx(EyeIcon, {}) }) })] })] }), _jsx(Field.ErrorText, { children: form.formState.errors.confirmPassword?.message })] }), _jsxs(Field.Root, { className: "mt-6", invalid: !!form.formState.errors.secretQuestion, children: [_jsxs(Select.Root, { deselectable: true, collection: secretQuestionCollection, lazyMount: true, positioning: {
87
+ sameWidth: true,
88
+ }, value: secretQuestion ? [secretQuestion] : [], onValueChange: (details) => {
89
+ form.setValue('secretQuestion', z.enum(SECRET_QUESTIONS).safeParse(details.value.at(0))
90
+ .data ?? null, {
91
+ shouldDirty: true,
92
+ shouldTouch: true,
93
+ shouldValidate: true,
94
+ });
95
+ }, children: [_jsx(Select.Label, { children: "Security Question" }), _jsxs(Select.Trigger, { children: [_jsx(Select.ValueText, {}), _jsx(Select.Indicator, { asChild: true, children: _jsx(ChevronDownIcon, {}) })] }), _jsx(Portal, { children: _jsx(Select.Positioner, { children: _jsx(Select.Content, { children: _jsx(Select.ItemGroup, { children: secretQuestionCollection.items.map((provider) => (_jsxs(Select.Item, { item: provider, children: [_jsx(Select.ItemText, { children: secretQuestionCollection.stringifyItem(provider) }), _jsx(Select.ItemIndicator, { asChild: true, children: _jsx(CheckIcon, {}) })] }, provider))) }) }) }) })] }), _jsx(Field.ErrorText, { children: form.formState.errors.secretQuestion?.message })] }), _jsxs(Field.Root, { className: "mt-6", invalid: !!form.formState.errors.secretAnswer, children: [_jsx(Field.Label, { children: "Answer" }), _jsx(Field.Input, { ...form.register('secretAnswer') }), _jsx(Field.ErrorText, { children: form.formState.errors.secretAnswer?.message })] })] }), form.formState.isDirty && (_jsxs("div", { className: "border-border-secondary flex justify-end gap-lg 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" })] }))] })] }));
19
96
  }
20
97
  function TransactionPassword() {
21
98
  const profileCompletionQuery = useProfileCompletionQuery();
22
99
  const profileCompletion = profileCompletionQuery.data;
100
+ const updateAccountMutation = useUpdateAccountMutation({
101
+ onSuccess() {
102
+ form.reset();
103
+ toaster.success({
104
+ description: 'Changes saved!',
105
+ });
106
+ },
107
+ onError(error) {
108
+ toaster.error({
109
+ description: error.message,
110
+ });
111
+ },
112
+ });
113
+ const schema = z
114
+ .object({
115
+ password: z.string().min(8).max(150).optional().or(z.literal('')),
116
+ confirmPassword: z.string().optional(),
117
+ })
118
+ .superRefine((data, ctx) => {
119
+ if (data.password && data.password !== data.confirmPassword) {
120
+ ctx.addIssue({
121
+ path: ['confirmPassword'],
122
+ code: z.ZodIssueCode.custom,
123
+ message: 'Passwords do not match',
124
+ });
125
+ }
126
+ });
127
+ const form = useForm({
128
+ mode: 'all',
129
+ resolver: zodResolver(schema),
130
+ defaultValues: {
131
+ password: '',
132
+ confirmPassword: '',
133
+ },
134
+ });
23
135
  return (_jsxs("div", { children: [_jsxs("div", { className: "flex items-start gap-8", children: [_jsxs("div", { className: "grow", children: [_jsx("h2", { className: "text-text-secondary-700 text-sm font-semibold", children: "Transaction password" }), _jsx("p", { className: "text-text-tertiary-600 text-sm", children: "The transaction password secures and confirms your wallet withdrawals." })] }), _jsx(ark.svg, { asChild: true, className: twMerge('size-6', profileCompletion?.accountPassword
24
136
  ? 'text-text-success-primary'
25
- : 'text-text-warning-primary'), children: profileCompletion?.accountPassword ? (_jsx(CheckVerified02Icon, {})) : (_jsx(AlertCircleIcon, {})) })] }), _jsxs("form", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border", children: [_jsxs("div", { className: "px-xl py-5 lg:px-3xl lg:py-5", children: [_jsx(Field.Root, { children: _jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { children: "Password" }), _jsxs(PasswordInput.Control, { children: [_jsx(PasswordInput.Input, {}), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, {}), asChild: true, children: _jsx(EyeIcon, {}) }) })] })] }) }), _jsx(Field.Root, { className: "mt-6", children: _jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { children: "Confirm Password" }), _jsxs(PasswordInput.Control, { children: [_jsx(PasswordInput.Input, {}), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, {}), asChild: true, children: _jsx(EyeIcon, {}) }) })] })] }) })] }), _jsxs("div", { className: "border-border-secondary flex justify-end gap-lg border-t px-xl py-lg lg:px-3xl lg:py-xl", children: [_jsx(Button, { size: "sm", variant: "outline", fullWidth: false, children: "Cancel" }), _jsx(Button, { size: "sm", fullWidth: false, children: "Save Changes" })] })] })] }));
137
+ : 'text-text-warning-primary'), children: profileCompletion?.accountPassword ? (_jsx(CheckVerified02Icon, {})) : (_jsx(AlertCircleIcon, {})) })] }), _jsxs("form", { className: "shadow-xs bg-bg-primary-alt border-border-secondary mt-5 rounded-xl border", onSubmit: form.handleSubmit((data) => {
138
+ updateAccountMutation.mutate({
139
+ password: data.password ? data.password : undefined,
140
+ });
141
+ }), children: [_jsxs("div", { className: "px-xl py-5 lg:px-3xl lg:py-5", children: [_jsxs(Field.Root, { invalid: !!form.formState.errors.password, children: [_jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { children: "Password" }), _jsxs(PasswordInput.Control, { children: [_jsx(PasswordInput.Input, { ...form.register('password') }), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, {}), asChild: true, children: _jsx(EyeIcon, {}) }) })] })] }), _jsx(Field.ErrorText, { children: form.formState.errors.password?.message })] }), _jsxs(Field.Root, { className: "mt-6", invalid: !!form.formState.errors.confirmPassword, children: [_jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { children: "Confirm Password" }), _jsxs(PasswordInput.Control, { children: [_jsx(PasswordInput.Input, { ...form.register('confirmPassword') }), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, {}), asChild: true, children: _jsx(EyeIcon, {}) }) })] })] }), _jsx(Field.ErrorText, { children: form.formState.errors.confirmPassword?.message })] })] }), form.formState.isDirty && (_jsxs("div", { className: "border-border-secondary flex justify-end gap-lg 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: !form.formState.isValid || updateAccountMutation.isPending, children: "Save Changes" })] }))] })] }));
26
142
  }
27
143
  const SECRET_QUESTIONS = [
28
144
  'BEST_CHILDHOOD_FRIEND',