diff --git a/src/components/Skeletons/WorkspaceRowSkeleton.tsx b/src/components/Skeletons/WorkspaceRowSkeleton.tsx new file mode 100644 index 000000000000..5c9f18ef4ef3 --- /dev/null +++ b/src/components/Skeletons/WorkspaceRowSkeleton.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import {Rect} from 'react-native-svg'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import variables from '@styles/variables'; +import ItemListSkeletonView from './ItemListSkeletonView'; + +const barHeight = 7; +const longBarWidth = 120; +const shortBarWidth = 60; +const leftPaneWidth = variables.navigationTabBarSize; +const gapWidth = 12; + +type WorkspaceRowSkeletonProps = { + shouldAnimate?: boolean; + fixedNumItems?: number; + gradientOpacityEnabled?: boolean; +}; + +function WorkspaceRowSkeleton({shouldAnimate = true, fixedNumItems, gradientOpacityEnabled = false}: WorkspaceRowSkeletonProps) { + const styles = useThemeStyles(); + const {windowWidth} = useWindowDimensions(); + const {shouldUseNarrowLayout} = useResponsiveLayout(); + // We calculate the width of the sections on the skeleton by first calculating the skeleton view width + // Then we subtract the width by 66, which is the x position of the first part. + const partWidth = Math.floor((windowWidth - leftPaneWidth - gapWidth * 2 - 66) / 3); + return ( + ( + <> + + + + {!shouldUseNarrowLayout && ( + <> + + + + + + )} + + )} + /> + ); +} +WorkspaceRowSkeleton.displayName = 'WorkspaceRowSkeleton'; +export default WorkspaceRowSkeleton; diff --git a/src/languages/de.ts b/src/languages/de.ts index 24075db4e304..39cb3a3e4a28 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -4882,9 +4882,8 @@ const translations = { updateTaxCodeFailureMessage: 'Beim Aktualisieren des Steuercodes ist ein Fehler aufgetreten, bitte versuchen Sie es erneut.', }, emptyWorkspace: { - title: 'Erstellen Sie einen Arbeitsbereich', - subtitle: - 'Erstellen Sie einen Arbeitsbereich, um Belege zu verfolgen, Ausgaben zu erstatten, Reisen zu verwalten, Rechnungen zu senden und mehr – alles in der Geschwindigkeit eines Chats.', + title: 'Sie haben keine Arbeitsbereiche', + subtitle: 'Verfolgen Sie Belege, erstatten Sie Ausgaben, verwalten Sie Reisen, senden Sie Rechnungen und mehr.', createAWorkspaceCTA: 'Loslegen', features: { trackAndCollect: 'Belege verfolgen und sammeln', diff --git a/src/languages/en.ts b/src/languages/en.ts index 6b3aa34a76f3..aa671054e64a 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -4865,8 +4865,8 @@ const translations = { updateTaxCodeFailureMessage: 'An error occurred while updating the tax code, please try again', }, emptyWorkspace: { - title: 'Create a workspace', - subtitle: 'Create a workspace to track receipts, reimburse expenses, manage travel, send invoices, and more — all at the speed of chat.', + title: 'You have no workspaces', + subtitle: 'Track receipts, reimburse expenses, manage travel, send invoices, and more.', createAWorkspaceCTA: 'Get Started', features: { trackAndCollect: 'Track and collect receipts', diff --git a/src/languages/es.ts b/src/languages/es.ts index 2d5402374455..b95461460981 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -4875,8 +4875,8 @@ const translations = { updateTaxCodeFailureMessage: 'Se produjo un error al actualizar el código tributario, inténtelo nuevamente', }, emptyWorkspace: { - title: 'Crea un espacio de trabajo', - subtitle: 'Crea un espacio de trabajo para organizar recibos, reembolsar gastos, gestionar viajes, enviar facturas y mucho más, todo a la velocidad del chat.', + title: 'No tienes espacios de trabajo', + subtitle: 'Organiza recibos, reembolsa gastos, gestiona viajes, envía facturas y mucho más.', createAWorkspaceCTA: 'Comenzar', features: { trackAndCollect: 'Organiza recibos', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 44204f4c8b12..1149d0fe5d70 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -4898,8 +4898,8 @@ const translations = { updateTaxCodeFailureMessage: "Une erreur s'est produite lors de la mise à jour du code fiscal, veuillez réessayer.", }, emptyWorkspace: { - title: 'Créer un espace de travail', - subtitle: 'Créez un espace de travail pour suivre les reçus, rembourser les dépenses, gérer les voyages, envoyer des factures, et plus encore — le tout à la vitesse du chat.', + title: "Vous n'avez aucun espace de travail", + subtitle: 'Suivez les reçus, remboursez les dépenses, gérez les déplacements, envoyez des factures, et plus encore.', createAWorkspaceCTA: 'Commencer', features: { trackAndCollect: 'Suivre et collecter les reçus', diff --git a/src/languages/it.ts b/src/languages/it.ts index da0c3fd5da1a..e4b32c0d6098 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -4897,8 +4897,8 @@ const translations = { updateTaxCodeFailureMessage: "Si è verificato un errore durante l'aggiornamento del codice fiscale, riprova.", }, emptyWorkspace: { - title: "Crea un'area di lavoro", - subtitle: 'Crea uno spazio di lavoro per tracciare le ricevute, rimborsare le spese, gestire i viaggi, inviare fatture e altro ancora, tutto alla velocità della chat.', + title: 'Non hai spazi di lavoro', + subtitle: 'Traccia ricevute, rimborsa spese, gestisci viaggi, invia fatture e altro ancora.', createAWorkspaceCTA: 'Inizia', features: { trackAndCollect: 'Traccia e raccogli ricevute', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 3a839d07010c..7ec2b552ae3c 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -4876,8 +4876,8 @@ const translations = { updateTaxCodeFailureMessage: '税コードの更新中にエラーが発生しました。もう一度お試しください。', }, emptyWorkspace: { - title: 'ワークスペースを作成', - subtitle: '領収書を追跡し、経費を払い戻し、旅行を管理し、請求書を送信するためのワークスペースを作成し、チャットの速度でこれらすべてを行いましょう。', + title: 'ワークスペースがありません', + subtitle: '領収書の管理、経費精算、出張管理、請求書の送信などができます。', createAWorkspaceCTA: '開始する', features: { trackAndCollect: '領収書を追跡して収集する', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 9f9dc1f9b1ac..9be49d351d84 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -4899,8 +4899,8 @@ const translations = { updateTaxCodeFailureMessage: 'Er is een fout opgetreden bij het bijwerken van de belastingcode, probeer het opnieuw.', }, emptyWorkspace: { - title: 'Maak een werkruimte aan', - subtitle: 'Maak een werkruimte om bonnetjes bij te houden, uitgaven te vergoeden, reizen te beheren, facturen te versturen en meer — allemaal op de snelheid van chat.', + title: 'Je hebt geen werkruimtes', + subtitle: 'Beheer bonnetjes, vergoed uitgaven, regel reizen, verstuur facturen en meer.', createAWorkspaceCTA: 'Aan de slag', features: { trackAndCollect: 'Volg en verzamel bonnetjes', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 7bbd38eb0e91..264fd0246054 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -4888,8 +4888,8 @@ const translations = { updateTaxCodeFailureMessage: 'Wystąpił błąd podczas aktualizacji kodu podatkowego, spróbuj ponownie.', }, emptyWorkspace: { - title: 'Utwórz przestrzeń roboczą', - subtitle: 'Utwórz przestrzeń roboczą do śledzenia paragonów, zwracania wydatków, zarządzania podróżami, wysyłania faktur i nie tylko — wszystko z prędkością czatu.', + title: 'Nie masz żadnych przestrzeni roboczych', + subtitle: 'Śledź paragony, zwracaj wydatki, zarządzaj podróżami, wysyłaj faktury i nie tylko.', createAWorkspaceCTA: 'Rozpocznij', features: { trackAndCollect: 'Śledź i zbieraj paragony', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 344b3bd485f2..c0579fe178f3 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -4894,8 +4894,8 @@ const translations = { updateTaxCodeFailureMessage: 'Ocorreu um erro ao atualizar o código de imposto, por favor, tente novamente.', }, emptyWorkspace: { - title: 'Criar um espaço de trabalho', - subtitle: 'Crie um espaço de trabalho para rastrear recibos, reembolsar despesas, gerenciar viagens, enviar faturas e muito mais — tudo na velocidade do chat.', + title: 'Você não tem espaços de trabalho', + subtitle: 'Acompanhe recibos, reembolse despesas, gerencie viagens, envie faturas e muito mais.', createAWorkspaceCTA: 'Começar', features: { trackAndCollect: 'Acompanhe e colete recibos', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 5e0f238759f2..0a1a124d0203 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -4811,8 +4811,8 @@ const translations = { updateTaxCodeFailureMessage: '更新税码时发生错误,请重试', }, emptyWorkspace: { - title: '创建一个工作区', - subtitle: '创建一个工作区来跟踪收据、报销费用、管理差旅、发送发票等——一切都在聊天的速度下完成。', + title: '您没有任何工作区', + subtitle: '跟踪收据、报销费用、管理差旅、发送发票等。', createAWorkspaceCTA: '开始使用', features: { trackAndCollect: '跟踪并收集收据', diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index f901338592df..30ba4462c6f4 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -4,11 +4,9 @@ import {FlatList, View} from 'react-native'; import type {ValueOf} from 'type-fest'; import Button from '@components/Button'; import ConfirmModal from '@components/ConfirmModal'; -import type {FeatureListItem} from '@components/FeatureList'; -import FeatureList from '@components/FeatureList'; +import EmptyStateComponent from '@components/EmptyStateComponent'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as Illustrations from '@components/Icon/Illustrations'; import LottieAnimations from '@components/LottieAnimations'; import type {MenuItemProps} from '@components/MenuItem'; import NavigationTabBar from '@components/Navigation/NavigationTabBar'; @@ -22,6 +20,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import SearchBar from '@components/SearchBar'; import type {ListItem} from '@components/SelectionList/types'; +import WorkspaceRowSkeleton from '@components/Skeletons/WorkspaceRowSkeleton'; import SupportalActionRestrictedModal from '@components/SupportalActionRestrictedModal'; import Text from '@components/Text'; import useCardFeeds from '@hooks/useCardFeeds'; @@ -32,6 +31,7 @@ import useOnyx from '@hooks/useOnyx'; import usePayAndDowngrade from '@hooks/usePayAndDowngrade'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useSearchResults from '@hooks/useSearchResults'; +import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import {isConnectionInProgress} from '@libs/actions/connections'; @@ -46,6 +46,8 @@ import {getDefaultApprover, getPolicy, getPolicyBrickRoadIndicatorStatus, isPoli import {getDefaultWorkspaceAvatar} from '@libs/ReportUtils'; import {shouldCalculateBillNewDot as shouldCalculateBillNewDotFn} from '@libs/SubscriptionUtils'; import type {AvatarSource} from '@libs/UserUtils'; +import colors from '@styles/theme/colors'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -72,21 +74,6 @@ type WorkspaceItem = ListItem & // eslint-disable-next-line react/no-unused-prop-types type GetMenuItem = {item: WorkspaceItem; index: number}; -const workspaceFeatures: FeatureListItem[] = [ - { - icon: Illustrations.MoneyReceipts, - translationKey: 'workspace.emptyWorkspace.features.trackAndCollect', - }, - { - icon: Illustrations.CreditCardsNew, - translationKey: 'workspace.emptyWorkspace.features.companyCards', - }, - { - icon: Illustrations.MoneyWings, - translationKey: 'workspace.emptyWorkspace.features.reimbursements', - }, -]; - /** * Dismisses the errors on one item */ @@ -107,6 +94,7 @@ function dismissWorkspaceError(policyID: string, pendingAction: OnyxCommon.Pendi function WorkspacesListPage() { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {translate, localeCompare} = useLocalize(); const {isOffline} = useNetwork(); const {shouldUseNarrowLayout, isMediumScreenWidth} = useResponsiveLayout(); @@ -448,23 +436,27 @@ function WorkspacesListPage() { ) : ( - - interceptAnonymousUser(() => Navigation.navigate(ROUTES.WORKSPACE_CONFIRMATION.getRoute(ROUTES.WORKSPACES_LIST.route)))} - illustration={LottieAnimations.WorkspacePlanet} - // We use this style to vertically center the illustration, as the original illustration is not centered - illustrationStyle={styles.emptyWorkspaceIllustrationStyle} - titleStyles={styles.textHeadlineH1} - /> - + interceptAnonymousUser(() => Navigation.navigate(ROUTES.WORKSPACE_CONFIRMATION.getRoute(ROUTES.WORKSPACES_LIST.route))), + buttonText: translate('workspace.new.newWorkspace'), + }, + ]} + /> )} {shouldDisplayLHB && } diff --git a/src/styles/index.ts b/src/styles/index.ts index b9f6e70eb1e6..8f3f5f4b0ee2 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -2018,6 +2018,12 @@ const styles = (theme: ThemeColors) => marginBottom: -20, }, + emptyWorkspaceListIllustrationStyle: { + marginTop: 12, + marginBottom: -20, + height: '100%', + }, + overlayStyles: (current: OverlayStylesParams, isModalOnTheLeft: boolean) => ({ ...positioning.pFixed,