diff --git a/.github/workflows/mobile.apps.android.yml b/.github/workflows/mobile.apps.android.yml index 2e6fb6897..22c0a24e1 100644 --- a/.github/workflows/mobile.apps.android.yml +++ b/.github/workflows/mobile.apps.android.yml @@ -62,6 +62,15 @@ jobs: run: | yarn build:mobile + - name: Generate app.json and replace placeholders + run: | + cd apps/mobile && yarn config:mobile + env: + EXPO_PROJECT_SLUG: ${{ secrets.EXPO_PROJECT_SLUG }} + EXPO_PROJECT_NAME: ${{ secrets.EXPO_PROJECT_NAME }} + EXPO_PROJECT_OWNER: ${{ secrets.EXPO_PROJECT_OWNER }} + EXPO_PROJECT_ID: ${{ secrets.EXPO_PROJECT_ID }} + - name: Build on EAS run: cd apps/mobile && eas build --platform android --non-interactive diff --git a/.github/workflows/mobile.apps.ios.yml b/.github/workflows/mobile.apps.ios.yml index 0fa5752f1..1b120fb4f 100644 --- a/.github/workflows/mobile.apps.ios.yml +++ b/.github/workflows/mobile.apps.ios.yml @@ -68,6 +68,15 @@ jobs: run: | yarn build:mobile + - name: Generate app.json and replace placeholders + run: | + cd apps/mobile && yarn config:mobile + env: + EXPO_PROJECT_SLUG: ${{ secrets.EXPO_PROJECT_SLUG }} + EXPO_PROJECT_NAME: ${{ secrets.EXPO_PROJECT_NAME }} + EXPO_PROJECT_OWNER: ${{ secrets.EXPO_PROJECT_OWNER }} + EXPO_PROJECT_ID: ${{ secrets.EXPO_PROJECT_ID }} + - name: Build on EAS run: cd apps/mobile && eas build --platform ios --non-interactive diff --git a/.scripts/configure.mobile.ts b/.scripts/configure.mobile.ts new file mode 100644 index 000000000..66e05c3a3 --- /dev/null +++ b/.scripts/configure.mobile.ts @@ -0,0 +1,37 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as dotenv from 'dotenv'; + +dotenv.config(); // Load environment variables from .env file + +const templatePath = path.join(__dirname, '../apps/mobile/app.template.json'); +const appJsonPath = path.join(__dirname, '../apps/mobile/app.json'); + +fs.copyFile(templatePath, appJsonPath, (err) => { + if (err) { + console.error('Error copying template file:', err); + return; + } + + fs.readFile(appJsonPath, 'utf8', (err, appData) => { + if (err) { + console.error('Error reading app.json file:', err); + return; + } + + const updatedData = appData + .replace(/\$EXPO_PROJECT_SLUG/g, process.env.EXPO_PROJECT_SLUG) + .replace(/\$EXPO_PROJECT_NAME/g, process.env.EXPO_PROJECT_NAME) + .replace(/\$EXPO_PROJECT_OWNER/g, process.env.EXPO_PROJECT_OWNER) + .replace(/\$EXPO_PROJECT_ID/g, process.env.EXPO_PROJECT_ID); + + fs.writeFile(appJsonPath, updatedData, (err) => { + if (err) { + console.error('Error writing app.json file:', err); + return; + } + + console.log('app.json generated successfully!'); + }); + }); +}); diff --git a/apps/mobile/.env b/apps/mobile/.env index f3df1a804..f07c6ee3f 100644 --- a/apps/mobile/.env +++ b/apps/mobile/.env @@ -6,3 +6,7 @@ INVITE_CALLBACK_URL=https://app.ever.team/auth/passcode EXPO_PUBLIC_SENTRY_DSN= SENTRY_ORG=ever-co SENTRY_PROJECT=ever-teams-mobile +EXPO_PROJECT_SLUG=ever-teams-mobile +EXPO_PROJECT_NAME=Ever Teams Mobile +EXPO_PROJECT_OWNER=everco +EXPO_PROJECT_ID=2ff924e4-7a91-4b23-9db9-7453a8063bb0 diff --git a/apps/mobile/.env.template b/apps/mobile/.env.template index f3df1a804..f07c6ee3f 100644 --- a/apps/mobile/.env.template +++ b/apps/mobile/.env.template @@ -6,3 +6,7 @@ INVITE_CALLBACK_URL=https://app.ever.team/auth/passcode EXPO_PUBLIC_SENTRY_DSN= SENTRY_ORG=ever-co SENTRY_PROJECT=ever-teams-mobile +EXPO_PROJECT_SLUG=ever-teams-mobile +EXPO_PROJECT_NAME=Ever Teams Mobile +EXPO_PROJECT_OWNER=everco +EXPO_PROJECT_ID=2ff924e4-7a91-4b23-9db9-7453a8063bb0 diff --git a/apps/mobile/.gitignore b/apps/mobile/.gitignore index 7efd359d0..3e8c41db6 100644 --- a/apps/mobile/.gitignore +++ b/apps/mobile/.gitignore @@ -148,5 +148,5 @@ yarn-error.log .expo/ web-build/ dist/ - -# @end expo-cli \ No newline at end of file +/app.json +# @end expo-cli diff --git a/apps/mobile/app.json b/apps/mobile/app.json deleted file mode 100644 index 99d8e7859..000000000 --- a/apps/mobile/app.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "name": "ever-teams", - "displayName": "Ever Teams", - "expo": { - "name": "Ever Teams", - "slug": "ever-teams-mobile", - "version": "0.1.0", - "orientation": "portrait", - "icon": "./assets/images/ever-teams-logo.png", - "splash": { - "image": "./assets/images/splash-ever-teams.png", - "resizeMode": "cover", - "backgroundColor": "#ffffff" - }, - "owner": "everco", - "updates": { - "fallbackToCacheTimeout": 0, - "url": "https://u.expo.dev/2ff924e4-7a91-4b23-9db9-7453a8063bb0" - }, - "jsEngine": "hermes", - "assetBundlePatterns": ["**/*"], - "plugins": [ - [ - "expo-media-library", - { - "photosPermission": "Allow $(PRODUCT_NAME) to access your photos.", - "savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.", - "isAccessMediaLocationEnabled": true - } - ], - "sentry-expo", - [ - "expo-build-properties", - { - "android": { - "enableProguardInReleaseBuilds": true, - "extraProguardRules": "-keep public class com.horcrux.svg.** {*;}", - "allowBackup": false - } - } - ] - ], - "android": { - "icon": "./assets/images/app-icon-android-legacy-ever-teams.png", - "package": "ever.team", - "adaptiveIcon": { - "foregroundImage": "./assets/images/app-icon-android-adaptive-foreground-ever.png", - "backgroundImage": "./assets/images/app-icon-android-adaptive-background.png" - }, - "splash": { - "image": "./assets/images/splash-ever-teams.png", - "resizeMode": "cover", - "backgroundColor": "#ffffff" - }, - "permissions": [ - "android.permission.READ_EXTERNAL_STORAGE", - "android.permission.WRITE_EXTERNAL_STORAGE", - "android.permission.ACCESS_MEDIA_LOCATION" - ] - }, - "ios": { - "icon": "./assets/images/app-icon-ios-ever-teams.png", - "supportsTablet": true, - "bundleIdentifier": "co.ever.teams", - "splash": { - "image": "./assets/images/splash-ever-teams.png", - "tabletImage": "./assets/images/splash-logo-ever-teams-ios-tablet.png", - "resizeMode": "cover", - "backgroundColor": "#ffffff" - }, - "infoPlist": { - "NSCameraUsageDescription": "This app uses the camera to scan barcodes on event tickets.", - "NSPhotoLibraryUsageDescription": "Allow $(PRODUCT_NAME) to access your photos.", - "NSPhotoLibraryAddUsageDescription": "Allow $(PRODUCT_NAME) to save photos." - } - }, - "web": { - "favicon": "./assets/images/app-icon-web-favicon.png", - "splash": { - "image": "./assets/images/splash-logo-web-ever-teams.png", - "resizeMode": "contain", - "backgroundColor": "#ffffff" - } - }, - "extra": { - "eas": { - "projectId": "2ff924e4-7a91-4b23-9db9-7453a8063bb0" - } - }, - "runtimeVersion": "exposdk:48.0.0" - } -} diff --git a/apps/mobile/app.template.json b/apps/mobile/app.template.json new file mode 100644 index 000000000..a69f6c58c --- /dev/null +++ b/apps/mobile/app.template.json @@ -0,0 +1,91 @@ +{"name": "$EXPO_PROJECT_SLUG", +"displayName": "$EXPO_PROJECT_NAME", +"expo": { + "name": "$EXPO_PROJECT_NAME", + "slug": "$EXPO_PROJECT_SLUG", + "version": "0.1.0", + "orientation": "portrait", + "icon": "./assets/images/ever-teams-logo.png", + "splash": { + "image": "./assets/images/splash-ever-teams.png", + "resizeMode": "cover", + "backgroundColor": "#ffffff" + }, + "owner": "$EXPO_PROJECT_OWNER", + "updates": { + "fallbackToCacheTimeout": 0, + "url": "https://u.expo.dev/$EXPO_PROJECT_ID" + }, + "jsEngine": "hermes", + "assetBundlePatterns": ["**/*"], + "plugins": [ + [ + "expo-media-library", + { + "photosPermission": "Allow $(PRODUCT_NAME) to access your photos.", + "savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.", + "isAccessMediaLocationEnabled": true + } + ], + "sentry-expo", + [ + "expo-build-properties", + { + "android": { + "enableProguardInReleaseBuilds": true, + "extraProguardRules": "-keep public class com.horcrux.svg.** {*;}", + "allowBackup": false + } + } + ] + ], + "android": { + "icon": "./assets/images/app-icon-android-legacy-ever-teams.png", + "package": "ever.team", + "adaptiveIcon": { + "foregroundImage": "./assets/images/app-icon-android-adaptive-foreground-ever.png", + "backgroundImage": "./assets/images/app-icon-android-adaptive-background.png" + }, + "splash": { + "image": "./assets/images/splash-ever-teams.png", + "resizeMode": "cover", + "backgroundColor": "#ffffff" + }, + "permissions": [ + "android.permission.READ_EXTERNAL_STORAGE", + "android.permission.WRITE_EXTERNAL_STORAGE", + "android.permission.ACCESS_MEDIA_LOCATION" + ] + }, + "ios": { + "icon": "./assets/images/app-icon-ios-ever-teams.png", + "supportsTablet": true, + "bundleIdentifier": "co.ever.teams", + "splash": { + "image": "./assets/images/splash-ever-teams.png", + "tabletImage": "./assets/images/splash-logo-ever-teams-ios-tablet.png", + "resizeMode": "cover", + "backgroundColor": "#ffffff" + }, + "infoPlist": { + "NSCameraUsageDescription": "This app uses the camera to scan barcodes on event tickets.", + "NSPhotoLibraryUsageDescription": "Allow $(PRODUCT_NAME) to access your photos.", + "NSPhotoLibraryAddUsageDescription": "Allow $(PRODUCT_NAME) to save photos." + } + }, + "web": { + "favicon": "./assets/images/app-icon-web-favicon.png", + "splash": { + "image": "./assets/images/splash-logo-web-ever-teams.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + } + }, + "extra": { + "eas": { + "projectId": "$EXPO_PROJECT_ID" + } + }, + "runtimeVersion": "exposdk:48.0.0" +} +} diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 4093b91a0..3da62b796 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -9,13 +9,13 @@ }, "private": true, "scripts": { - "start": "expo start --dev-client", - "ios": "yarn react-native run-ios", - "android": "yarn react-native run-android --active-arch-only", - "test:detox": "yarn detox test -c ios.sim.debug", - "build:detox": "yarn detox build -c ios.sim.debug", - "ci:test:detox": "yarn detox test -c ios.sim.release -l verbose --cleanup", - "ci:build:detox": "yarn detox build -c ios.sim.release", + "start": "yarn config:mobile && expo start --dev-client", + "ios": "yarn config:mobile && yarn react-native run-ios", + "android": "yarn config:mobile && yarn react-native run-android --active-arch-only", + "test:detox": "yarn config:mobile && yarn detox test -c ios.sim.debug", + "build:detox": "yarn config:mobile && yarn detox build -c ios.sim.debug", + "ci:test:detox": "yarn config:mobile && yarn detox test -c ios.sim.release -l verbose --cleanup", + "ci:build:detox": "yarn config:mobile && yarn detox build -c ios.sim.release", "build": "yarn compile", "compile": "yarn tsc --noEmit -p . --pretty", "format": "yarn prettier --write \"app/**/*.{js,jsx,json,md,ts,tsx}\"", @@ -25,18 +25,20 @@ "test:watch": "yarn jest --watch", "adb": "yarn adb reverse tcp:9090 tcp:9090 && adb reverse tcp:3000 tcp:3000 && adb reverse tcp:9001 tcp:9001 && adb reverse tcp:8081 tcp:8081", "postinstall": "node ./bin/postInstall", - "bundle:ios": "yarn react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios", - "bundle:android": "yarn react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res", + "bundle:ios": "yarn config:mobile && yarn react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios", + "bundle:android": "yarn config:mobile && yarn react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res", "release:ios": "echo 'Not implemented yet: release:ios. Use Xcode. More info: https://reactnative.dev/docs/next/publishing-to-app-store'", - "release:android": "cd android && rm -rf app/src/main/res/drawable-* && ./gradlew assembleRelease && cd - && echo 'APK generated in ./android/app/build/outputs/apk/release/app-release.apk'", + "release:android": "yarn config:mobile && cd android && rm -rf app/src/main/res/drawable-* && ./gradlew assembleRelease && cd - && echo 'APK generated in ./android/app/build/outputs/apk/release/app-release.apk'", "clean": "yarn npx react-native-clean-project", "clean-all": "yarn npx react-native clean-project-auto", - "expo:start": "yarn expo start", - "expo:android": "yarn expo start --android", - "expo:ios": "yarn expo start --ios", - "expo:web": "yarn expo start --web", - "expo:build:detox": "yarn detox build -c ios.sim.expo", - "expo:test:detox": "./bin/downloadExpoApp.sh && yarn detox test --configuration ios.sim.expo" + "expo:start": "yarn config:mobile && yarn expo start", + "expo:android": "yarn config:mobile && yarn expo start --android", + "expo:ios": "yarn config:mobile && yarn expo start --ios", + "expo:web": "yarn config:mobile && yarn expo start --web", + "expo:build:detox": "yarn config:mobile && yarn detox build -c ios.sim.expo", + "expo:test:detox": "yarn config:mobile && ./bin/downloadExpoApp.sh && yarn detox test --configuration ios.sim.expo", + "eas:build": "yarn yarn config:mobile && eas build", + "config:mobile": "yarn ts-node ../../.scripts/configure.mobile.ts" }, "overrides": { "react-error-overlay": "6.0.9" diff --git a/apps/web/app/api/email-reset/request-change-email/route.ts b/apps/web/app/api/email-reset/request-change-email/route.ts index 4c929a74f..35c03719b 100644 --- a/apps/web/app/api/email-reset/request-change-email/route.ts +++ b/apps/web/app/api/email-reset/request-change-email/route.ts @@ -10,11 +10,11 @@ export async function POST(req: Request) { const { email } = (await req.json()) as IEmail; - return $res( - await emailResetRequest({ - email, - tenantId, - bearer_token: access_token - }) - ); + const response = await emailResetRequest({ + email, + tenantId, + bearer_token: access_token + }); + + return $res(response.data); } diff --git a/apps/web/app/api/email-reset/verify-change-email/route.ts b/apps/web/app/api/email-reset/verify-change-email/route.ts index 382970eb3..9960b18b3 100644 --- a/apps/web/app/api/email-reset/verify-change-email/route.ts +++ b/apps/web/app/api/email-reset/verify-change-email/route.ts @@ -10,11 +10,11 @@ export async function POST(req: Request) { const { code } = (await req.json()) as ICode; - return $res( - await verifyChangemailRequest({ - code, - tenantId, - bearer_token: access_token - }) - ); + const response = await verifyChangemailRequest({ + code, + tenantId, + bearer_token: access_token + }); + + return $res(response.data); } diff --git a/apps/web/app/hooks/features/useTimer.ts b/apps/web/app/hooks/features/useTimer.ts index b7a6bfc5a..479f5c803 100644 --- a/apps/web/app/hooks/features/useTimer.ts +++ b/apps/web/app/hooks/features/useTimer.ts @@ -153,7 +153,7 @@ function useLocalTimeCounter(timerStatus: ITimerStatus | null, activeTeamTask: I export function useTimer() { const { updateTask, activeTeamId, activeTeam, activeTeamTask } = useTeamTasks(); const { updateOrganizationTeamEmployeeActiveTask } = useOrganizationEmployeeTeams(); - const { user } = useAuthenticateUser(); + const { user, $user } = useAuthenticateUser(); const [timerStatus, setTimerStatus] = useRecoilState(timerStatusState); @@ -229,10 +229,10 @@ export function useTimer() { if (syncTimerLoading || syncTimerLoadingRef.current) { return; } - return syncTimerQueryCall(timerStatus?.lastLog?.source || TimerSource.TEAMS).then((res) => { + return syncTimerQueryCall(timerStatus?.lastLog?.source || TimerSource.TEAMS, $user.current).then((res) => { return res; }); - }, [syncTimerQueryCall, timerStatus, syncTimerLoading, syncTimerLoadingRef]); + }, [syncTimerQueryCall, timerStatus, syncTimerLoading, syncTimerLoadingRef, $user]); // Loading states useEffect(() => { diff --git a/apps/web/app/services/client/api/auth.ts b/apps/web/app/services/client/api/auth.ts index 3c9f7e0b8..6576e4bf7 100644 --- a/apps/web/app/services/client/api/auth.ts +++ b/apps/web/app/services/client/api/auth.ts @@ -1,7 +1,14 @@ import { getRefreshTokenCookie } from '@app/helpers/cookies'; import { ISuccessResponse, IUser } from '@app/interfaces'; import { ILoginResponse, IRegisterDataAPI, ISigninEmailConfirmResponse } from '@app/interfaces/IAuthentication'; -import api, { get } from '../axios'; +import api, { get, post } from '../axios'; +import { + APP_LOGO_URL, + APP_NAME, + APP_SIGNATURE, + VERIFY_EMAIL_CALLBACK_PATH, + VERIFY_EMAIL_CALLBACK_URL +} from '@app/constants'; export const signInWithEmailAndCodeAPI = (email: string, code: string) => { return api.post(`/auth/login`, { @@ -66,6 +73,20 @@ export const verifyUserEmailByTokenAPI = (email: string, token: string) => { return api.post(`/auth/verify/token`, { email, token }); }; -export const resentVerifyUserLinkAPI = () => { - return api.post(`/auth/verify/resend-link`); +export const resentVerifyUserLinkAPI = (user: IUser) => { + const appEmailConfirmationUrl = `${location.origin}${VERIFY_EMAIL_CALLBACK_PATH}`; + const registerDefaultValue = { + appName: APP_NAME, + appSignature: APP_SIGNATURE, + appLogo: APP_LOGO_URL + }; + + const body = { + email: user.email, + tenantId: user.tenantId, + ...registerDefaultValue, + appEmailConfirmationUrl: VERIFY_EMAIL_CALLBACK_URL || appEmailConfirmationUrl + }; + + return post(`/auth/verify/resend-link`, body); }; diff --git a/apps/web/app/services/client/api/email-reset.ts b/apps/web/app/services/client/api/email-reset.ts index 94e53c0cb..f53e9ee4a 100644 --- a/apps/web/app/services/client/api/email-reset.ts +++ b/apps/web/app/services/client/api/email-reset.ts @@ -1,11 +1,11 @@ -import { CreateResponse, ISuccessResponse } from '@app/interfaces'; -import api from '../axios'; +import { ISuccessResponse } from '@app/interfaces'; +import { post } from '../axios'; export function emailResetRequestAPI(email: string) { - return api.post>(`/email-reset/request-change-email`, { + return post(`/email-reset/request-change-email`, { email }); } export function verifyChangeEmailRequestAPI(code: string) { - return api.post>(`/email-reset/verify-change-email`, { code }); + return post(`/email-reset/verify-change-email`, { code }); } diff --git a/apps/web/app/services/client/api/timer.ts b/apps/web/app/services/client/api/timer.ts index 1172d7ae2..405720e1f 100644 --- a/apps/web/app/services/client/api/timer.ts +++ b/apps/web/app/services/client/api/timer.ts @@ -1,6 +1,8 @@ import { ITimerStatus, IToggleTimerParams, TimerSource } from '@app/interfaces/ITimer'; -import api, { get } from '../axios'; +import api, { get, post } from '../axios'; import { GAUZY_API_BASE_SERVER_URL } from '@app/constants'; +import { getActiveTaskIdCookie, getActiveTeamIdCookie, getOrganizationIdCookie, getTenantIdCookie } from '@app/helpers'; +import { IUser } from '@app/interfaces'; export async function getTimerStatusAPI(tenantId: string, organizationId: string) { const params = new URLSearchParams({ tenantId, organizationId }); @@ -9,21 +11,93 @@ export async function getTimerStatusAPI(tenantId: string, organizationId: string return get(endpoint); } -export function toggleTimerAPI(body: Pick) { +export async function toggleTimerAPI(body: Pick) { + const organizationId = getOrganizationIdCookie(); + const tenantId = getTenantIdCookie(); + + if (GAUZY_API_BASE_SERVER_URL.value) { + await post('/timesheet/timer/toggle', { + source: TimerSource.TEAMS, + logType: 'TRACKED', + taskId: body.taskId, + tenantId, + organizationId + }); + + await post('/timesheet/timer/stop', { + source: TimerSource.TEAMS, + logType: 'TRACKED', + taskId: body.taskId, + tenantId, + organizationId + }); + + return getTimerStatusAPI(tenantId, organizationId); + } + return api.post('/timer/toggle', body); } -export function startTimerAPI() { +export async function startTimerAPI() { + const organizationId = getOrganizationIdCookie(); + const tenantId = getTenantIdCookie(); + const teamId = getActiveTeamIdCookie(); + const taskId = getActiveTaskIdCookie(); + + if (GAUZY_API_BASE_SERVER_URL.value) { + await post('/timesheet/timer/start', { + tenantId, + organizationId, + taskId, + logType: 'TRACKED', + source: TimerSource.TEAMS, + tags: [], + organizationTeamId: teamId + }); + + return getTimerStatusAPI(tenantId, organizationId); + } + return api.post('/timer/start'); } -export function stopTimerAPI(source: TimerSource) { +export async function stopTimerAPI(source: TimerSource) { + const organizationId = getOrganizationIdCookie(); + const tenantId = getTenantIdCookie(); + const taskId = getActiveTaskIdCookie(); + + if (GAUZY_API_BASE_SERVER_URL.value) { + await post('/timesheet/timer/stop', { + source, + logType: 'TRACKED', + ...(taskId ? { taskId } : {}), + tenantId, + organizationId + }); + + return getTimerStatusAPI(tenantId, organizationId); + } + return api.post('/timer/stop', { source }); } -export function syncTimerAPI(source: TimerSource) { +export async function syncTimerAPI(source: TimerSource, user: IUser | undefined) { + const organizationId = getOrganizationIdCookie(); + const tenantId = getTenantIdCookie(); + + if (GAUZY_API_BASE_SERVER_URL.value) { + await post('/timesheet/timer/stop', { + tenantId, + organizationId, + logType: 'TRACKED', + source, + employeeId: user?.employee.id, + duration: 5 + }); + } + return api.post('/timer/sync', { source }); diff --git a/apps/web/lib/features/unverified-email.tsx b/apps/web/lib/features/unverified-email.tsx index 132454cd9..3abe9f9cc 100644 --- a/apps/web/lib/features/unverified-email.tsx +++ b/apps/web/lib/features/unverified-email.tsx @@ -2,6 +2,7 @@ import { getAccessTokenCookie } from '@app/helpers'; import { useAuthenticateUser, useModal, useQuery } from '@app/hooks'; +import { IUser } from '@app/interfaces'; import { resentVerifyUserLinkAPI, verifyUserEmailByCodeAPI } from '@app/services/client/api'; import { clsxm } from '@app/utils'; import { AuthCodeInputField, Button, Card, Modal, SpinnerLoader, Text } from 'lib/components'; @@ -57,7 +58,7 @@ export function UnverifiedEmail() { @@ -69,14 +70,14 @@ export function UnverifiedEmail() { */} - + ) : ( <> ); } -export function ConfirmUserModal({ open, closeModal }: { open: boolean; closeModal: () => void }) { +export function ConfirmUserModal({ open, user, closeModal }: { open: boolean; user?: IUser; closeModal: () => void }) { const { loading, queryCall } = useQuery(verifyUserEmailByCodeAPI); const { loading: resendLinkLoading, queryCall: resendLinkQueryCall } = useQuery(resentVerifyUserLinkAPI); @@ -128,7 +129,7 @@ export function ConfirmUserModal({ open, closeModal }: { open: boolean; closeMod