diff --git a/assets/animations/Plane.lottie b/assets/animations/Plane.lottie
new file mode 100644
index 000000000000..5244cb7bea10
Binary files /dev/null and b/assets/animations/Plane.lottie differ
diff --git a/assets/images/simple-illustrations/simple-illustration__alert.svg b/assets/images/simple-illustrations/simple-illustration__alert.svg
new file mode 100644
index 000000000000..55429cf39b8f
--- /dev/null
+++ b/assets/images/simple-illustrations/simple-illustration__alert.svg
@@ -0,0 +1,15 @@
+
diff --git a/assets/images/suitcase.svg b/assets/images/suitcase.svg
new file mode 100644
index 000000000000..97036db6b5ac
--- /dev/null
+++ b/assets/images/suitcase.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 179cc751ef3f..a1b76414f800 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -754,8 +754,10 @@ const ROUTES = {
route: 'referral/:contentType',
getRoute: (contentType: string, backTo?: string) => getUrlWithBackToParam(`referral/${contentType}`, backTo),
},
- TRACK_TRAINING_MODAL: 'track-training',
PROCESS_MONEY_REQUEST_HOLD: 'hold-expense-educational',
+ TRAVEL_MY_TRIPS: 'travel',
+ TRAVEL_TCS: 'travel/terms',
+ TRACK_TRAINING_MODAL: 'track-training',
ONBOARDING_ROOT: 'onboarding',
ONBOARDING_PERSONAL_DETAILS: 'onboarding/personal-details',
ONBOARDING_WORK: 'onboarding/work',
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index 00933686004f..223e276e2e26 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -23,6 +23,10 @@ const SCREENS = {
CONNECTION_COMPLETE: 'ConnectionComplete',
UNLINK_LOGIN: 'UnlinkLogin',
SETTINGS_CENTRAL_PANE: 'SettingsCentralPane',
+ TRAVEL: {
+ MY_TRIPS: 'Travel_MyTrips',
+ TCS: 'Travel_TCS',
+ },
WORKSPACES_CENTRAL_PANE: 'WorkspacesCentralPane',
SEARCH: {
CENTRAL_PANE: 'Search_Central_Pane',
@@ -133,6 +137,7 @@ const SCREENS = {
ROOM_INVITE: 'RoomInvite',
REFERRAL: 'Referral',
PROCESS_MONEY_REQUEST_HOLD: 'ProcessMoneyRequestHold',
+ TRAVEL: 'Travel',
SEARCH_REPORT: 'SearchReport',
},
ONBOARDING_MODAL: {
diff --git a/src/components/FeatureList.tsx b/src/components/FeatureList.tsx
index 5f713d5f3aef..85f421731cfa 100644
--- a/src/components/FeatureList.tsx
+++ b/src/components/FeatureList.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import {View} from 'react-native';
-import type {StyleProp, ViewStyle} from 'react-native';
+import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import variables from '@styles/variables';
@@ -43,6 +43,12 @@ type FeatureListProps = {
/** The background color to apply in the upper half of the screen. */
illustrationBackgroundColor?: string;
+
+ /** The style used for the title */
+ titleStyles?: StyleProp;
+
+ /** Padding for content on large screens */
+ contentPaddingOnLargeScreens?: {padding: number};
};
function FeatureList({
@@ -55,6 +61,8 @@ function FeatureList({
illustration,
illustrationStyle,
illustrationBackgroundColor,
+ titleStyles,
+ contentPaddingOnLargeScreens,
}: FeatureListProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
@@ -68,6 +76,8 @@ function FeatureList({
illustration={illustration}
illustrationBackgroundColor={illustrationBackgroundColor}
illustrationStyle={illustrationStyle}
+ titleStyles={titleStyles}
+ contentPaddingOnLargeScreens={contentPaddingOnLargeScreens}
>
diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts
index 22117652c5f9..f564bcf48345 100644
--- a/src/components/Icon/Expensicons.ts
+++ b/src/components/Icon/Expensicons.ts
@@ -144,6 +144,7 @@ import Podcast from '@assets/images/social-podcast.svg';
import Twitter from '@assets/images/social-twitter.svg';
import Youtube from '@assets/images/social-youtube.svg';
import Stopwatch from '@assets/images/stopwatch.svg';
+import Suitcase from '@assets/images/suitcase.svg';
import Sync from '@assets/images/sync.svg';
import Tag from '@assets/images/tag.svg';
import Task from '@assets/images/task.svg';
@@ -302,6 +303,7 @@ export {
Send,
Shield,
Stopwatch,
+ Suitcase,
Sync,
Task,
ThumbsUp,
diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts
index b639b2efdd26..8d3f53be9396 100644
--- a/src/components/Icon/Illustrations.ts
+++ b/src/components/Icon/Illustrations.ts
@@ -31,6 +31,7 @@ import ThreeLeggedLaptopWoman from '@assets/images/product-illustrations/three_l
import ToddBehindCloud from '@assets/images/product-illustrations/todd-behind-cloud.svg';
import Abacus from '@assets/images/simple-illustrations/simple-illustration__abacus.svg';
import Accounting from '@assets/images/simple-illustrations/simple-illustration__accounting.svg';
+import Alert from '@assets/images/simple-illustrations/simple-illustration__alert.svg';
import Approval from '@assets/images/simple-illustrations/simple-illustration__approval.svg';
import BankArrow from '@assets/images/simple-illustrations/simple-illustration__bank-arrow.svg';
import BigRocket from '@assets/images/simple-illustrations/simple-illustration__bigrocket.svg';
@@ -160,6 +161,7 @@ export {
Workflows,
ThreeLeggedLaptopWoman,
House,
+ Alert,
TeachersUnite,
Abacus,
Binoculars,
diff --git a/src/components/LottieAnimations/index.tsx b/src/components/LottieAnimations/index.tsx
index 18cb9188d60c..598819e19361 100644
--- a/src/components/LottieAnimations/index.tsx
+++ b/src/components/LottieAnimations/index.tsx
@@ -67,6 +67,11 @@ const DotLottieAnimations = {
w: 200,
h: 120,
},
+ Plane: {
+ file: require('@assets/animations/Plane.lottie'),
+ w: 180,
+ h: 200,
+ },
} satisfies Record;
export default DotLottieAnimations;
diff --git a/src/components/Section/index.tsx b/src/components/Section/index.tsx
index 848761c9e982..7f7d759c72aa 100644
--- a/src/components/Section/index.tsx
+++ b/src/components/Section/index.tsx
@@ -68,6 +68,9 @@ type SectionProps = ChildrenProps & {
/** Styles to apply to illustration component */
illustrationStyle?: StyleProp;
+ /** Padding for content on large screens */
+ contentPaddingOnLargeScreens?: {padding: number};
+
/** Overlay content to display on top of animation */
overlayContent?: () => ReactNode;
@@ -92,6 +95,7 @@ function Section({
illustration,
illustrationBackgroundColor,
illustrationStyle,
+ contentPaddingOnLargeScreens,
overlayContent,
renderSubtitle,
}: SectionProps) {
@@ -124,7 +128,7 @@ function Section({
{overlayContent?.()}
)}
-
+
{cardLayout === CARD_LAYOUT.ICON_ON_LEFT && (
require('../../../../pages/settings/Profile/PersonalDetails/StateSelectionPage').default as React.ComponentType,
});
+const TravelModalStackNavigator = createModalStackNavigator({
+ [SCREENS.TRAVEL.MY_TRIPS]: () => require('../../../../pages/Travel/MyTripsPage').default as React.ComponentType,
+ [SCREENS.TRAVEL.TCS]: () => require('../../../../pages/Travel/TravelTerms').default as React.ComponentType,
+});
+
const SplitDetailsModalStackNavigator = createModalStackNavigator({
[SCREENS.SPLIT_DETAILS.ROOT]: () => require('../../../../pages/iou/SplitBillDetailsPage').default as React.ComponentType,
});
@@ -364,6 +370,7 @@ export {
PrivateNotesModalStackNavigator,
ProfileModalStackNavigator,
ReferralModalStackNavigator,
+ TravelModalStackNavigator,
WorkspaceSwitcherModalStackNavigator,
ReimbursementAccountModalStackNavigator,
ReportDetailsModalStackNavigator,
diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx
index c3cff62eefe2..1d595f05ee88 100644
--- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx
+++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx
@@ -133,6 +133,10 @@ function RightModalNavigator({navigation}: RightModalNavigatorProps) {
name="ProcessMoneyRequestHold"
component={ModalStackNavigators.ProcessMoneyRequestHoldStackNavigator}
/>
+
| undefined;
const routes = navigationState?.routes;
const currentRoute = routes?.[navigationState?.index ?? 0];
-
+ // When we are redirected to the Settings tab from the OldDot, we don't want to call the Welcome.show() method.
+ // To prevent this, the value of the bottomTabRoute?.name is checked here
if (Boolean(currentRoute && currentRoute.name !== NAVIGATORS.BOTTOM_TAB_NAVIGATOR && currentRoute.name !== NAVIGATORS.CENTRAL_PANE_NAVIGATOR) || Session.isAnonymousUser()) {
return;
}
diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts
index a34bac1fb9c5..00ae38136c3b 100644
--- a/src/libs/Navigation/linkingConfig/config.ts
+++ b/src/libs/Navigation/linkingConfig/config.ts
@@ -688,6 +688,12 @@ const config: LinkingOptions['config'] = {
[SCREENS.PROCESS_MONEY_REQUEST_HOLD_ROOT]: ROUTES.PROCESS_MONEY_REQUEST_HOLD,
},
},
+ [SCREENS.RIGHT_MODAL.TRAVEL]: {
+ screens: {
+ [SCREENS.TRAVEL.MY_TRIPS]: ROUTES.TRAVEL_MY_TRIPS,
+ [SCREENS.TRAVEL.TCS]: ROUTES.TRAVEL_TCS,
+ },
+ },
[SCREENS.RIGHT_MODAL.SEARCH_REPORT]: {
screens: {
[SCREENS.SEARCH.REPORT_RHP]: ROUTES.SEARCH_REPORT.route,
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index 68320f306f80..e210879f3795 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -707,6 +707,12 @@ type RightModalNavigatorParamList = {
[SCREENS.RIGHT_MODAL.PROCESS_MONEY_REQUEST_HOLD]: NavigatorScreenParams;
[SCREENS.RIGHT_MODAL.REFERRAL]: NavigatorScreenParams;
[SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: NavigatorScreenParams;
+ [SCREENS.RIGHT_MODAL.TRAVEL]: NavigatorScreenParams;
+ [SCREENS.RIGHT_MODAL.SEARCH_REPORT]: NavigatorScreenParams;
+};
+
+type TravelNavigatorParamList = {
+ [SCREENS.TRAVEL.MY_TRIPS]: undefined;
[SCREENS.RIGHT_MODAL.SEARCH_REPORT]: NavigatorScreenParams;
};
@@ -931,6 +937,7 @@ export type {
State,
StateOrRoute,
SwitchPolicyIDParams,
+ TravelNavigatorParamList,
TaskDetailsNavigatorParamList,
TeachersUniteNavigatorParamList,
WalletStatementNavigatorParamList,
diff --git a/src/libs/actions/Travel.ts b/src/libs/actions/Travel.ts
new file mode 100644
index 000000000000..02affae0fe67
--- /dev/null
+++ b/src/libs/actions/Travel.ts
@@ -0,0 +1,26 @@
+import type {OnyxUpdate} from 'react-native-onyx';
+import * as API from '@libs/API';
+import {WRITE_COMMANDS} from '@libs/API/types';
+import ONYXKEYS from '@src/ONYXKEYS';
+
+/**
+ * Accept Spotnana terms and conditions to receive a proper token used for authenticating further actions
+ */
+function acceptSpotnanaTerms() {
+ const successData: OnyxUpdate[] = [
+ {
+ onyxMethod: 'merge',
+ key: ONYXKEYS.ACCOUNT,
+ value: {
+ travelSettings: {
+ hasAcceptedTerms: true,
+ },
+ },
+ },
+ ];
+
+ API.write(WRITE_COMMANDS.ACCEPT_SPOTNANA_TERMS, {}, {successData});
+}
+
+// eslint-disable-next-line import/prefer-default-export
+export {acceptSpotnanaTerms};
diff --git a/src/pages/Travel/ManageTrips.tsx b/src/pages/Travel/ManageTrips.tsx
new file mode 100644
index 000000000000..401f06277b5e
--- /dev/null
+++ b/src/pages/Travel/ManageTrips.tsx
@@ -0,0 +1,58 @@
+import React from 'react';
+import {View} from 'react-native';
+import type {FeatureListItem} from '@components/FeatureList';
+import FeatureList from '@components/FeatureList';
+import * as Illustrations from '@components/Icon/Illustrations';
+import LottieAnimations from '@components/LottieAnimations';
+import ScrollView from '@components/ScrollView';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@hooks/useThemeStyles';
+import useWindowDimensions from '@hooks/useWindowDimensions';
+import Navigation from '@libs/Navigation/Navigation';
+import colors from '@styles/theme/colors';
+import ROUTES from '@src/ROUTES';
+import getTripIllustrationStyle from './getTripIllustrationStyle';
+
+const tripsFeatures: FeatureListItem[] = [
+ {
+ icon: Illustrations.PiggyBank,
+ translationKey: 'travel.features.saveMoney',
+ },
+ {
+ icon: Illustrations.Alert,
+ translationKey: 'travel.features.alerts',
+ },
+];
+
+function ManageTrips() {
+ const styles = useThemeStyles();
+ const {isSmallScreenWidth} = useWindowDimensions();
+ const {translate} = useLocalize();
+ const illustrationStyle = getTripIllustrationStyle();
+
+ return (
+
+
+ {
+ Navigation.navigate(ROUTES.TRAVEL_TCS);
+ }}
+ illustration={LottieAnimations.Plane}
+ illustrationStyle={illustrationStyle}
+ illustrationBackgroundColor={colors.blue600}
+ titleStyles={styles.textHeadlineH1}
+ contentPaddingOnLargeScreens={styles.p5}
+ />
+
+
+ );
+}
+
+ManageTrips.displayName = 'ManageTrips';
+
+export default ManageTrips;
diff --git a/src/pages/Travel/MyTripsPage.tsx b/src/pages/Travel/MyTripsPage.tsx
new file mode 100644
index 000000000000..be29e8dc8c12
--- /dev/null
+++ b/src/pages/Travel/MyTripsPage.tsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
+import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import ScreenWrapper from '@components/ScreenWrapper';
+import useLocalize from '@hooks/useLocalize';
+import usePermissions from '@hooks/usePermissions';
+import ManageTrips from './ManageTrips';
+
+function MyTripsPage() {
+ const {translate} = useLocalize();
+ const {canUseSpotnanaTravel} = usePermissions();
+
+ return (
+
+
+
+
+
+
+ );
+}
+
+MyTripsPage.displayName = 'MyTripsPage';
+
+export default MyTripsPage;
diff --git a/src/pages/Travel/TravelTerms.tsx b/src/pages/Travel/TravelTerms.tsx
new file mode 100644
index 000000000000..6852275dfe91
--- /dev/null
+++ b/src/pages/Travel/TravelTerms.tsx
@@ -0,0 +1,110 @@
+import React, {useCallback, useEffect, useState} from 'react';
+import {View} from 'react-native';
+import {ScrollView} from 'react-native-gesture-handler';
+import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
+import CheckboxWithLabel from '@components/CheckboxWithLabel';
+import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton';
+import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import SafeAreaConsumer from '@components/SafeAreaConsumer';
+import ScreenWrapper from '@components/ScreenWrapper';
+import Text from '@components/Text';
+import TextLink from '@components/TextLink';
+import useLocalize from '@hooks/useLocalize';
+import usePermissions from '@hooks/usePermissions';
+import useThemeStyles from '@hooks/useThemeStyles';
+import Navigation from '@libs/Navigation/Navigation';
+import * as Travel from '@userActions/Travel';
+
+function TravelTerms() {
+ const styles = useThemeStyles();
+ const {translate} = useLocalize();
+ const {canUseSpotnanaTravel} = usePermissions();
+ const [hasAcceptedTravelTerms, setHasAcceptedTravelTerms] = useState(false);
+ const [error, setError] = useState(false);
+
+ const errorMessage = error ? 'travel.termsAndConditions.error' : '';
+
+ const toggleTravelTerms = () => {
+ setHasAcceptedTravelTerms(!hasAcceptedTravelTerms);
+ };
+
+ useEffect(() => {
+ if (!hasAcceptedTravelTerms) {
+ return;
+ }
+
+ setError(false);
+ }, [hasAcceptedTravelTerms]);
+
+ const AgreeToTheLabel = useCallback(
+ () => (
+
+ {`${translate('travel.termsAndConditions.agree')}`}
+ {`${translate('travel.termsAndConditions.travelTermsAndConditions')}`}
+
+ ),
+ [translate],
+ );
+
+ // Add beta support for FullPageNotFound that is universal across travel pages
+ return (
+
+
+ Navigation.goBack()}
+ />
+
+ {({safeAreaPaddingBottomStyle}) => (
+
+
+ {`${translate('travel.termsAndConditions.title')}`}
+
+ {`${translate('travel.termsAndConditions.subtitle')}`}
+ {`${translate('travel.termsAndConditions.termsconditions')}.`}
+
+
+ {`${translate('travel.termsAndConditions.helpDocIntro')}`}
+ {`${translate('travel.termsAndConditions.helpDoc')} `}
+ {`${translate('travel.termsAndConditions.helpDocOutro')}`}
+
+
+
+
+ {
+ if (!hasAcceptedTravelTerms) {
+ setError(true);
+ return;
+ }
+
+ Travel.acceptSpotnanaTerms();
+ setError(false);
+ Navigation.resetToHome();
+ }}
+ message={errorMessage}
+ isAlertVisible={error || Boolean(errorMessage)}
+ containerStyles={[styles.mh0, styles.mt5]}
+ />
+
+ )}
+
+
+
+ );
+}
+
+TravelTerms.displayName = 'TravelMenu';
+
+export default TravelTerms;
diff --git a/src/pages/Travel/getTripIllustrationStyle/index.native.ts b/src/pages/Travel/getTripIllustrationStyle/index.native.ts
new file mode 100644
index 000000000000..e5b0a1381d7e
--- /dev/null
+++ b/src/pages/Travel/getTripIllustrationStyle/index.native.ts
@@ -0,0 +1,8 @@
+import type {ViewStyle} from 'react-native';
+
+// Styling lottie animations for the ManageTrips component requires different margin values depending on the platform.
+export default function getTripIllustrationStyle(): ViewStyle {
+ return {
+ marginVertical: 20,
+ };
+}
diff --git a/src/pages/Travel/getTripIllustrationStyle/index.ts b/src/pages/Travel/getTripIllustrationStyle/index.ts
new file mode 100644
index 000000000000..a2a141022d73
--- /dev/null
+++ b/src/pages/Travel/getTripIllustrationStyle/index.ts
@@ -0,0 +1,9 @@
+import type {ViewStyle} from 'react-native';
+
+// Styling lottie animations for the ManageTrips component requires different margin values depending on the platform.
+export default function getTripIllustrationStyle(): ViewStyle {
+ return {
+ marginTop: 20,
+ marginBottom: -20,
+ };
+}
diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx
index cc61e61aa1f8..9f492ad90a5b 100644
--- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx
+++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx
@@ -178,6 +178,7 @@ function FloatingActionButtonAndPopover(
const prevIsFocused = usePrevious(isFocused);
const {isOffline} = useNetwork();
+ const {canUseSpotnanaTravel} = usePermissions();
const canSendInvoice = useMemo(() => PolicyUtils.canSendInvoice(allPolicies as OnyxCollection), [allPolicies]);
const quickActionAvatars = useMemo(() => {
@@ -401,6 +402,15 @@ function FloatingActionButtonAndPopover(
text: translate('newTaskPage.assignTask'),
onSelected: () => interceptAnonymousUser(() => Task.clearOutTaskInfoAndNavigate()),
},
+ ...(canUseSpotnanaTravel
+ ? [
+ {
+ icon: Expensicons.Suitcase,
+ text: translate('travel.bookTravel'),
+ onSelected: () => interceptAnonymousUser(() => Navigation.navigate(ROUTES.TRAVEL_MY_TRIPS)),
+ },
+ ]
+ : []),
...(!isLoading && !Policy.hasActiveChatEnabledPolicies(allPolicies)
? [
{
diff --git a/src/styles/index.ts b/src/styles/index.ts
index 365c89ac4a18..1b1587d81bce 100644
--- a/src/styles/index.ts
+++ b/src/styles/index.ts
@@ -1868,6 +1868,11 @@ const styles = (theme: ThemeColors) =>
marginBottom: -20,
},
+ travelIllustrationStyle: {
+ marginTop: 16,
+ marginBottom: -16,
+ },
+
overlayStyles: (current: OverlayStylesParams, isModalOnTheLeft: boolean) =>
({
...positioning.pFixed,
diff --git a/src/types/onyx/Account.ts b/src/types/onyx/Account.ts
index 67ff12c74150..c53d7ea816f8 100644
--- a/src/types/onyx/Account.ts
+++ b/src/types/onyx/Account.ts
@@ -2,6 +2,7 @@ import type {ValueOf} from 'type-fest';
import type CONST from '@src/CONST';
import type DismissedReferralBanners from './DismissedReferralBanners';
import type * as OnyxCommon from './OnyxCommon';
+import type {TravelSettings} from './TravelSettings';
type TwoFactorAuthStep = ValueOf | '';
@@ -59,6 +60,9 @@ type Account = {
codesAreCopied?: boolean;
twoFactorAuthStep?: TwoFactorAuthStep;
dismissedReferralBanners?: DismissedReferralBanners;
+
+ /** Object containing all account information necessary to connect with Spontana */
+ travelSettings?: TravelSettings;
};
export default Account;
diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts
index d64de6196985..b2ec43c4f55e 100644
--- a/src/types/onyx/Policy.ts
+++ b/src/types/onyx/Policy.ts
@@ -3,6 +3,7 @@ import type CONST from '@src/CONST';
import type {Country} from '@src/CONST';
import type * as OnyxTypes from '.';
import type * as OnyxCommon from './OnyxCommon';
+import type {WorkspaceTravelSettings} from './TravelSettings';
type Unit = 'mi' | 'km';
@@ -523,6 +524,9 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback<
/** Indicates if the Policy ownership change is failed */
isChangeOwnerFailed?: boolean;
+
+ /** Object containing all policy information necessary to connect with Spontana */
+ travelSettings?: WorkspaceTravelSettings;
} & Partial,
'generalSettings' | 'addWorkspaceRoom' | keyof ACHAccount
>;
diff --git a/src/types/onyx/TravelSettings.ts b/src/types/onyx/TravelSettings.ts
new file mode 100644
index 000000000000..e653c3378572
--- /dev/null
+++ b/src/types/onyx/TravelSettings.ts
@@ -0,0 +1,17 @@
+type TravelSettings = {
+ /** UUIDs that spotnana provides us with when we provision users in their system, and the spotnanaCompanyIDs as the values */
+ accountIDs: Record;
+
+ /** Whether the user has completed the travel terms and conditions checkbox */
+ hasAcceptedTerms: boolean;
+};
+
+type WorkspaceTravelSettings = {
+ /** The UUID that spotnana provides us when we create a “company” in their system */
+ spotnanaCompanyID: string;
+
+ /** The UUID that spotnana provides us when we provision the workspace as an “entity” in their system */
+ spotnanaEntityID: boolean;
+};
+
+export type {TravelSettings, WorkspaceTravelSettings};
diff --git a/tests/utils/collections/userAccount.ts b/tests/utils/collections/userAccount.ts
index 9e7c33a228d5..ebaa0a132169 100644
--- a/tests/utils/collections/userAccount.ts
+++ b/tests/utils/collections/userAccount.ts
@@ -7,6 +7,10 @@ function getValidAccount(credentialLogin = ''): Account {
primaryLogin: credentialLogin,
isLoading: false,
requiresTwoFactorAuth: false,
+ travelSettings: {
+ accountIDs: {},
+ hasAcceptedTerms: false,
+ },
};
}