diff --git a/src/components/FrozenCardHeader.tsx b/src/components/FrozenCardHeader.tsx
index 5b7f1cb752e0..74f4e3306518 100644
--- a/src/components/FrozenCardHeader.tsx
+++ b/src/components/FrozenCardHeader.tsx
@@ -1,5 +1,4 @@
-import {cardByIdSelector} from '@selectors/Card';
-import React, {useMemo} from 'react';
+import React from 'react';
import {View} from 'react-native';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
@@ -9,19 +8,26 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import DateUtils from '@libs/DateUtils';
import {getDisplayNameOrDefault} from '@libs/PersonalDetailsUtils';
+import Navigation from '@navigation/Navigation';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
import Button from './Button';
import Icon from './Icon';
import Text from './Text';
+import TextLink from './TextLink';
type FrozenCardHeaderProps = {
- cardID: string;
cardPreview: React.ReactNode;
onUnfreezePress: () => void;
+ onAskToUnfreezePress: () => void;
+ canUnfreezeCard: boolean;
+ isWorkspaceAdmin: boolean;
+ frozenByAccountID?: number;
+ frozenDate?: string;
};
-function FrozenCardHeader({cardID, cardPreview, onUnfreezePress}: FrozenCardHeaderProps) {
+function FrozenCardHeader({cardPreview, onUnfreezePress, onAskToUnfreezePress, canUnfreezeCard, isWorkspaceAdmin, frozenByAccountID, frozenDate}: FrozenCardHeaderProps) {
const styles = useThemeStyles();
const theme = useTheme();
const {translate} = useLocalize();
@@ -29,21 +35,50 @@ function FrozenCardHeader({cardID, cardPreview, onUnfreezePress}: FrozenCardHead
const icons = useMemoizedLazyExpensifyIcons(['FreezeCard'] as const);
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST);
const [session] = useOnyx(ONYXKEYS.SESSION);
- const [card] = useOnyx(ONYXKEYS.CARD_LIST, {selector: cardByIdSelector(cardID)});
-
- const frozenByAccountID = card?.nameValuePairs?.frozen?.byAccountID;
- const frozenDate = card?.nameValuePairs?.frozen?.date;
const isCurrentUser = frozenByAccountID === session?.accountID;
const frozenByName = frozenByAccountID ? getDisplayNameOrDefault(personalDetails?.[frozenByAccountID]) : '';
const formattedDate = frozenDate ? DateUtils.formatWithUTCTimeZone(frozenDate, CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT) : '';
+ const adminFrozenTextPrefix = translate('cardPage.frozenByAdminPrefix', {date: formattedDate});
+ const frozenNeedsUnfreezePrefix = translate('cardPage.frozenByAdminNeedsUnfreezePrefix');
+ const frozenNeedsUnfreezeSuffix = translate('cardPage.frozenByAdminNeedsUnfreezeSuffix');
+
+ let statusText: React.ReactNode;
- const statusText = useMemo(() => {
- if (isCurrentUser) {
- return translate('cardPage.youFroze', {date: formattedDate});
+ if (isCurrentUser) {
+ statusText = translate('cardPage.youFroze', {date: formattedDate});
+ } else if (isWorkspaceAdmin) {
+ if (!frozenByAccountID || !frozenByName) {
+ statusText = `${adminFrozenTextPrefix}${translate('common.someone')}`;
+ } else {
+ statusText = (
+ <>
+ {adminFrozenTextPrefix}
+ Navigation.navigate(ROUTES.PROFILE.getRoute(Number(frozenByAccountID), Navigation.getActiveRoute()))}
+ style={styles.link}
+ >
+ {frozenByName}
+
+ >
+ );
}
- return translate('cardPage.frozenBy', {date: formattedDate, person: frozenByName});
- }, [formattedDate, frozenByName, isCurrentUser, translate]);
+ } else if (!frozenByAccountID || !frozenByName) {
+ statusText = translate('cardPage.frozenByAdminNeedsUnfreeze', {person: frozenByName || translate('common.someone')});
+ } else {
+ statusText = (
+ <>
+ {frozenNeedsUnfreezePrefix}
+ Navigation.navigate(ROUTES.PROFILE.getRoute(Number(frozenByAccountID), Navigation.getActiveRoute()))}
+ style={styles.link}
+ >
+ {frozenByName}
+
+ {frozenNeedsUnfreezeSuffix}
+ >
+ );
+ }
return (
@@ -58,9 +93,9 @@ function FrozenCardHeader({cardID, cardPreview, onUnfreezePress}: FrozenCardHead
diff --git a/src/languages/de.ts b/src/languages/de.ts
index 82ee108404b3..ea19dd64ceab 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -2367,12 +2367,17 @@ ${amount} für ${merchant} – ${date}`,
freezeCard: 'Karte sperren',
unfreeze: 'Entsperren',
unfreezeCard: 'Karte entsperren',
+ askToUnfreeze: 'Entsperrung anfragen',
freezeDescription: 'Eine gesperrte Karte kann nicht für Käufe und Transaktionen verwendet werden. Du kannst sie jederzeit entsperren.',
unfreezeDescription:
'Durch das Entsperren dieser Karte werden Käufe und Transaktionen wieder zugelassen. Fahre nur fort, wenn du sicher bist, dass die Karte sicher verwendet werden kann.',
frozen: 'Gesperrt',
youFroze: ({date}: {date: string}) => `Du hast diese Karte am ${date} gesperrt.`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person} hat diese Karte am ${date} gesperrt.`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `Diese Karte wurde am ${date} gesperrt von `,
+ frozenByAdminNeedsUnfreezePrefix: 'Diese Karte wurde von ',
+ frozenByAdminNeedsUnfreezeSuffix: ' gesperrt. Bitte kontaktiere einen Admin, um sie zu entsperren.',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `Diese Karte wurde von ${person} gesperrt. Bitte kontaktiere einen Admin, um sie zu entsperren.`,
},
workflowsPage: {
workflowTitle: 'Ausgaben',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 4b6645274b68..21857cb60132 100644
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -2419,11 +2419,16 @@ const translations = {
freezeCard: 'Freeze card',
unfreeze: 'Unfreeze',
unfreezeCard: 'Unfreeze card',
+ askToUnfreeze: 'Ask to unfreeze',
freezeDescription: 'A frozen card cannot be used for purchases and transactions. You can unfreeze it at any time.',
unfreezeDescription: "Unfreezing this card will start allowing purchases and transactions again. Only proceed if you're sure the card is safe to use.",
frozen: 'Frozen',
youFroze: ({date}: {date: string}) => `You froze this card on ${date}.`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person} froze this card on ${date}.`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `This card was frozen on ${date} by `,
+ frozenByAdminNeedsUnfreezePrefix: 'This card was frozen by ',
+ frozenByAdminNeedsUnfreezeSuffix: '. Please contact an admin to unfreeze it.',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `This card was frozen by ${person}. Please contact an admin to unfreeze it.`,
},
workflowsPage: {
workflowTitle: 'Spend',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index ed025e937e2f..43430530095d 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2277,11 +2277,16 @@ ${amount} para ${merchant} - ${date}`,
freezeCard: 'Congelar tarjeta',
unfreeze: 'Descongelar',
unfreezeCard: 'Descongelar tarjeta',
+ askToUnfreeze: 'Solicitar descongelación',
freezeDescription: 'Una tarjeta congelada no se puede usar para compras ni transacciones. Puedes descongelarla en cualquier momento.',
unfreezeDescription: 'Al descongelar esta tarjeta se volverán a permitir compras y transacciones. Continúa solo si estás seguro de que la tarjeta es segura para usar.',
frozen: 'Congelada',
youFroze: ({date}: {date: string}) => `Congelaste esta tarjeta el ${date}.`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person} congeló esta tarjeta el ${date}.`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `Esta tarjeta fue congelada el ${date} por `,
+ frozenByAdminNeedsUnfreezePrefix: 'Esta tarjeta fue congelada por ',
+ frozenByAdminNeedsUnfreezeSuffix: '. Ponte en contacto con un administrador para descongelarla.',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `Esta tarjeta fue congelada por ${person}. Ponte en contacto con un administrador para descongelarla.`,
},
workflowsPage: {
workflowTitle: 'Gasto',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 5ee4f9359a1a..e80a48b5be1a 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -2374,12 +2374,17 @@ ${amount} pour ${merchant} - ${date}`,
freezeCard: 'Geler la carte',
unfreeze: 'Dégeler',
unfreezeCard: 'Dégeler la carte',
+ askToUnfreeze: 'Demander le dégel',
freezeDescription: 'Une carte gelée ne peut pas être utilisée pour des achats ni des transactions. Vous pouvez la dégeler à tout moment.',
unfreezeDescription:
'Dégeler cette carte permettra à nouveau les achats et les transactions. Continuez uniquement si vous êtes sûr(e) que la carte peut être utilisée en toute sécurité.',
frozen: 'Gelée',
youFroze: ({date}: {date: string}) => `Vous avez gelé cette carte le ${date}.`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person} a gelé cette carte le ${date}.`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `Cette carte a été gelée le ${date} par `,
+ frozenByAdminNeedsUnfreezePrefix: 'Cette carte a été gelée par ',
+ frozenByAdminNeedsUnfreezeSuffix: '. Veuillez contacter un administrateur pour la dégeler.',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `Cette carte a été gelée par ${person}. Veuillez contacter un administrateur pour la dégeler.`,
},
workflowsPage: {
workflowTitle: 'Dépense',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 1728e4defd4f..63108f7a4c1d 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -2364,11 +2364,16 @@ ${amount} per ${merchant} - ${date}`,
freezeCard: 'Blocca carta',
unfreeze: 'Sblocca',
unfreezeCard: 'Sblocca carta',
+ askToUnfreeze: 'Richiedi sblocco',
freezeDescription: 'Una carta bloccata non può essere usata per acquisti e transazioni. Puoi sbloccarla in qualsiasi momento.',
unfreezeDescription: 'Sbloccando questa carta torneranno ad essere consentiti acquisti e transazioni. Procedi solo se sei sicuro che la carta sia sicura da usare.',
frozen: 'Bloccata',
youFroze: ({date}: {date: string}) => `Hai bloccato questa carta il ${date}.`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person} ha bloccato questa carta il ${date}.`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `Questa carta è stata bloccata il ${date} da `,
+ frozenByAdminNeedsUnfreezePrefix: 'Questa carta è stata bloccata da ',
+ frozenByAdminNeedsUnfreezeSuffix: '. Contatta un amministratore per sbloccarla.',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `Questa carta è stata bloccata da ${person}. Contatta un amministratore per sbloccarla.`,
},
workflowsPage: {
workflowTitle: 'Spesa',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 102e4941579a..91c422b0a11c 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -2339,11 +2339,16 @@ ${date} の ${merchant} への ${amount}`,
freezeCard: 'カードを一時停止',
unfreeze: '再開',
unfreezeCard: 'カードの一時停止を解除',
+ askToUnfreeze: '一時停止解除を依頼',
freezeDescription: '一時停止したカードは購入や取引に使用できません。いつでも再開できます。',
unfreezeDescription: 'このカードの一時停止を解除すると、購入と取引が再び可能になります。カードが安全に使用できると確信できる場合にのみ続行してください。',
frozen: '凍結中',
youFroze: ({date}: {date: string}) => `${date}にこのカードを一時停止しました。`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person}が${date}にこのカードを一時停止しました。`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `${date}にこのカードを一時停止したのは`,
+ frozenByAdminNeedsUnfreezePrefix: 'このカードは',
+ frozenByAdminNeedsUnfreezeSuffix: 'によって一時停止されました。解除するには管理者に連絡してください。',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `このカードは${person}によって一時停止されました。解除するには管理者に連絡してください。`,
},
workflowsPage: {
workflowTitle: '支出',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 1df2b00e2b98..8d45c0f8bace 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -2362,11 +2362,16 @@ ${amount} voor ${merchant} - ${date}`,
freezeCard: 'Kaart blokkeren',
unfreeze: 'Deblokkeren',
unfreezeCard: 'Kaart deblokkeren',
+ askToUnfreeze: 'Vraag om deblokkering',
freezeDescription: 'Een geblokkeerde kaart kan niet worden gebruikt voor aankopen en transacties. Je kunt deze op elk moment deblokkeren.',
unfreezeDescription: 'Door deze kaart te deblokkeren worden aankopen en transacties weer toegestaan. Ga alleen verder als je zeker weet dat de kaart veilig is om te gebruiken.',
frozen: 'Geblokkeerd',
youFroze: ({date}: {date: string}) => `Je hebt deze kaart op ${date} geblokkeerd.`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person} heeft deze kaart op ${date} geblokkeerd.`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `Deze kaart is op ${date} bevroren door `,
+ frozenByAdminNeedsUnfreezePrefix: 'Deze kaart is bevroren door ',
+ frozenByAdminNeedsUnfreezeSuffix: '. Neem contact op met een beheerder om deze te deblokkeren.',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `Deze kaart is bevroren door ${person}. Neem contact op met een beheerder om deze te deblokkeren.`,
},
workflowsPage: {
workflowTitle: 'Uitgaven',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 1f2940d6f12d..5daba78b9f37 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -2358,11 +2358,16 @@ ${amount} dla ${merchant} - ${date}`,
freezeCard: 'Zamroź kartę',
unfreeze: 'Odmroź',
unfreezeCard: 'Odmroź kartę',
+ askToUnfreeze: 'Poproś o odmrożenie',
freezeDescription: 'Zamrożonej karty nie można używać do zakupów i transakcji. Możesz ją odmrozić w dowolnym momencie.',
unfreezeDescription: 'Odmrożenie tej karty ponownie umożliwi zakupy i transakcje. Kontynuuj tylko wtedy, gdy masz pewność, że korzystanie z karty jest bezpieczne.',
frozen: 'Zamrożona',
youFroze: ({date}: {date: string}) => `Zamroziłeś tę kartę ${date}.`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person} zamroził(a) tę kartę ${date}.`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `Ta karta została zamrożona ${date} przez `,
+ frozenByAdminNeedsUnfreezePrefix: 'Ta karta została zamrożona przez ',
+ frozenByAdminNeedsUnfreezeSuffix: '. Skontaktuj się z administratorem, aby ją odmrozić.',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `Ta karta została zamrożona przez ${person}. Skontaktuj się z administratorem, aby ją odmrozić.`,
},
workflowsPage: {
workflowTitle: 'Wydatki',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 772e6e1373dc..3ca121ab940d 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -2355,11 +2355,16 @@ ${amount} para ${merchant} - ${date}`,
freezeCard: 'Bloquear cartão',
unfreeze: 'Desbloquear',
unfreezeCard: 'Desbloquear cartão',
+ askToUnfreeze: 'Pedir desbloqueio',
freezeDescription: 'Um cartão bloqueado não pode ser usado para compras e transações. Você pode desbloqueá-lo a qualquer momento.',
unfreezeDescription: 'Ao desbloquear este cartão, compras e transações voltarão a ser permitidas. Continue apenas se tiver certeza de que o cartão é seguro para uso.',
frozen: 'Congelado',
youFroze: ({date}: {date: string}) => `Você bloqueou este cartão em ${date}.`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person} bloqueou este cartão em ${date}.`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `Este cartão foi bloqueado em ${date} por `,
+ frozenByAdminNeedsUnfreezePrefix: 'Este cartão foi bloqueado por ',
+ frozenByAdminNeedsUnfreezeSuffix: '. Entre em contato com um administrador para desbloqueá-lo.',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `Este cartão foi bloqueado por ${person}. Entre em contato com um administrador para desbloqueá-lo.`,
},
workflowsPage: {
workflowTitle: 'Gastos',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 7e5fe1dbaa54..8fa9b73cb67a 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -2299,11 +2299,16 @@ ${amount},商户:${merchant} - 日期:${date}`,
freezeCard: '冻结卡片',
unfreeze: '解冻',
unfreezeCard: '解冻卡片',
+ askToUnfreeze: '申请解冻',
freezeDescription: '冻结的卡片无法用于购买和交易。你可以随时解冻。',
unfreezeDescription: '解冻此卡后,将重新允许购买和交易。仅当你确定该卡可以安全使用时再继续。',
frozen: '已冻结',
youFroze: ({date}: {date: string}) => `你于${date}冻结了此卡。`,
frozenBy: ({person, date}: {person: string; date: string}) => `${person}于${date}冻结了此卡。`,
+ frozenByAdminPrefix: ({date}: {date: string}) => `此卡于${date}被冻结,操作人是`,
+ frozenByAdminNeedsUnfreezePrefix: '此卡已被',
+ frozenByAdminNeedsUnfreezeSuffix: '冻结。请联系管理员解冻。',
+ frozenByAdminNeedsUnfreeze: ({person}: {person: string}) => `此卡已被${person}冻结。请联系管理员解冻。`,
},
workflowsPage: {
workflowTitle: '支出',
diff --git a/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx b/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx
index 65e1724a282d..63983280e91c 100644
--- a/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx
+++ b/src/pages/settings/Wallet/ExpensifyCardPage/index.tsx
@@ -2,6 +2,7 @@ import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useMemo, useState} from 'react';
import type {ViewStyle} from 'react-native';
import {View} from 'react-native';
+import type {OnyxCollection} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import cardScarf from '@assets/images/card-scarf.svg';
import AddToWalletButton from '@components/AddToWalletButton/index';
@@ -46,6 +47,8 @@ import {convertToDisplayString} from '@libs/CurrencyUtils';
import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import type {DomainCardNavigatorParamList, SettingsNavigatorParamList} from '@libs/Navigation/types';
+import {isPolicyAdmin} from '@libs/PolicyUtils';
+import {getPolicyExpenseChat} from '@libs/ReportUtils';
import {buildCannedSearchQuery} from '@libs/SearchQueryUtils';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
import RedDotCardSection from '@pages/settings/Wallet/RedDotCardSection';
@@ -57,6 +60,7 @@ import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';
+import type {Policy} from '@src/types/onyx';
import {useExpensifyCardActions, useExpensifyCardState} from './ExpensifyCardContextProvider';
type ExpensifyCardPageProps =
@@ -150,9 +154,27 @@ function ExpensifyCardPage({route}: ExpensifyCardPageProps) {
const session = useSession();
const isCardHolder = currentCard?.accountID === session?.accountID;
+ const frozenByAccountID = currentCard?.nameValuePairs?.frozen?.byAccountID;
const {isBetaEnabled} = usePermissions();
const canManageCardFreeze = isBetaEnabled(CONST.BETAS.FREEZE_CARD) && isCardHolder && !!currentCard && !isAccountLocked;
+
+ const policySelector = useCallback(
+ (allPolicies: OnyxCollection): Policy | undefined => {
+ const workspaceAccountID = Number(currentCard?.fundID);
+ if (!workspaceAccountID || Number.isNaN(workspaceAccountID)) {
+ return undefined;
+ }
+
+ return Object.values(allPolicies ?? {}).find((policy) => policy?.workspaceAccountID === workspaceAccountID);
+ },
+ [currentCard?.fundID],
+ );
+ const [policyForCurrentCard] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {selector: policySelector}, [policySelector]);
+ const policyIDForCurrentCard = policyForCurrentCard?.id;
+ const isWorkspaceAdmin = isPolicyAdmin(policyForCurrentCard, session?.email);
+ const canUnfreezeCard = canManageCardFreeze && (frozenByAccountID === session?.accountID || isWorkspaceAdmin);
+
const scarfOverlayStyle = useMemo(
() => ({
top: 0,
@@ -187,6 +209,14 @@ function ExpensifyCardPage({route}: ExpensifyCardPageProps) {
setIsUnfreezeModalVisible(true);
}, []);
+ const handleAskToUnfreezePress = useCallback(() => {
+ const cardHolderWorkspaceChatReportID = getPolicyExpenseChat(currentCard?.accountID, policyIDForCurrentCard)?.reportID;
+ if (!cardHolderWorkspaceChatReportID) {
+ return;
+ }
+ Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(cardHolderWorkspaceChatReportID));
+ }, [currentCard?.accountID, policyIDForCurrentCard]);
+
const handleDismissUnfreezeModal = useCallback(() => {
setIsUnfreezeModalVisible(false);
}, []);
@@ -212,7 +242,11 @@ function ExpensifyCardPage({route}: ExpensifyCardPageProps) {
{canManageCardFreeze && isCardFrozen(currentCard) ? (
getDisplayNameOrDefault(cardholder), [cardholder]);
const cardType = isVirtual ? translate('workspace.expensifyCard.virtual') : translate('workspace.expensifyCard.physical');
+ const formattedFrozenDate = frozenDate ? DateUtils.formatWithUTCTimeZone(frozenDate, CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT) : '';
+ const frozenByAdminPrefix = translate('cardPage.frozenByAdminPrefix', {date: formattedFrozenDate});
+ const frozenByText = useMemo(() => {
+ if (!formattedFrozenDate) {
+ return undefined;
+ }
+
+ if (frozenByAccountID === session?.accountID) {
+ return translate('cardPage.youFroze', {date: formattedFrozenDate});
+ }
+
+ return `${frozenByAdminPrefix}${frozenByDisplayName ?? translate('common.someone')}`;
+ }, [formattedFrozenDate, frozenByAccountID, frozenByAdminPrefix, frozenByDisplayName, session?.accountID, translate]);
+
return (
-
-
-
-
-
- {cardholderName}
-
-
- {name}
-
+
+
+
+
+
+
+ {cardholderName}
+
+
+ {name}
+
+
-
- {!shouldUseNarrowLayout && (
-
+ {!shouldUseNarrowLayout && (
+
+
+ {cardType}
+
+
+ )}
+ {!shouldUseNarrowLayout && (
+
+
+ {translate(getTranslationKeyForLimitType(limitType))}
+
+
+ )}
+
- {cardType}
+ {lastFourPAN}
- )}
- {!shouldUseNarrowLayout && (
-
+
- {translate(getTranslationKeyForLimitType(limitType))}
+ {convertToShortDisplayString(limit, currency)}
+ {shouldUseNarrowLayout && (
+
+ {cardType}
+
+ )}
+
+
+
- )}
-
-
- {lastFourPAN}
-
-
-
-
- {convertToShortDisplayString(limit, currency)}
-
- {shouldUseNarrowLayout && (
-
- {cardType}
-
- )}
-
-
-
+ {!!frozenByText && (
+
+
+ {frozenByText}
+
+ )}
);
}
diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardDetailsPage.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardDetailsPage.tsx
index 1c07aa648948..7646a3b5f7a9 100644
--- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardDetailsPage.tsx
+++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardDetailsPage.tsx
@@ -180,7 +180,9 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
{canManageCardFreeze && isCardFrozen(card) ? (
@@ -198,6 +200,8 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
}
+ canUnfreezeCard={canManageCardFreeze}
+ onAskToUnfreezePress={() => {}}
/>
) : (
{workspaceCardImage}
diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardListPage.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardListPage.tsx
index f75b7e9eafa2..a53eeba31bc3 100644
--- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardListPage.tsx
+++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardListPage.tsx
@@ -33,6 +33,7 @@ import {clearIssueNewCardFormData, setIssueNewCardStepAndData} from '@libs/actio
import {clearDeletePaymentMethodError} from '@libs/actions/PaymentMethods';
import {filterCardsByPersonalDetails, getCardsByCardholderName, getCardSettings, sortCardsByCardholderName} from '@libs/CardUtils';
import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types';
+import {getDisplayNameOrDefault} from '@libs/PersonalDetailsUtils';
import {getDescriptionForPolicyDomainCard, getMemberAccountIDsForWorkspace} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import type {WorkspaceSplitNavigatorParamList} from '@navigation/types';
@@ -155,37 +156,46 @@ function WorkspaceExpensifyCardListPage({route, cardsList, fundID}: WorkspaceExp
);
const renderItem = useCallback(
- ({item, index}: ListRenderItemInfo) => (
- clearDeletePaymentMethodError(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${defaultFundID}_${CONST.EXPENSIFY_CARD.BANK}`, item.cardID)}
- >
- Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_DETAILS.getRoute(policyID, item.cardID.toString()))}
+ ({item, index}: ListRenderItemInfo) => {
+ const frozenByDisplayName = item.nameValuePairs?.frozen?.byAccountID
+ ? getDisplayNameOrDefault(personalDetails?.[item.nameValuePairs.frozen.byAccountID], '', false) || undefined
+ : undefined;
+
+ return (
+ clearDeletePaymentMethodError(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${defaultFundID}_${CONST.EXPENSIFY_CARD.BANK}`, item.cardID)}
>
- {({hovered}) => (
-
- )}
-
-
- ),
+ Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_DETAILS.getRoute(policyID, item.cardID.toString()))}
+ >
+ {({hovered}) => (
+
+ )}
+
+
+ );
+ },
[personalDetails, settlementCurrency, policyID, defaultFundID, styles],
);