From 08847e3f550801426f47df7f9e0653de17fa7691 Mon Sep 17 00:00:00 2001 From: nghiacc Date: Wed, 4 Feb 2026 06:30:36 +0700 Subject: [PATCH 1/5] fix: Shopping tab improvements 1. Currency dropdown: Created ShoppingCurrencyModal showing fiat currencies + XEC in a single list, sorted alphabetically (simpler than the 3-tab modal) 2. Removed 'Goods & Services' heading: Changed to 'Offers' to match P2P Trading tab. Also hide payment method badges on Shopping tab since all items are goods/services 3. Fixed scrolling: Removed local scrollbar (overflow: auto, maxHeight) to use global page scrolling like P2P Trading tab --- .../src/app/shopping/page.tsx | 10 +- .../FilterList/ShoppingCurrencyModal.tsx | 191 ++++++++++++++++++ .../FilterOffer/ShoppingFilterComponent.tsx | 4 +- .../src/components/OfferItem/OfferItem.tsx | 5 +- 4 files changed, 199 insertions(+), 11 deletions(-) create mode 100644 apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx diff --git a/apps/telegram-ecash-escrow/src/app/shopping/page.tsx b/apps/telegram-ecash-escrow/src/app/shopping/page.tsx index cc364869..493fdfea 100644 --- a/apps/telegram-ecash-escrow/src/app/shopping/page.tsx +++ b/apps/telegram-ecash-escrow/src/app/shopping/page.tsx @@ -184,7 +184,7 @@ export default function Shopping() {
- Goods & Services + Offers {isShowSortIcon && ( )} -
+
{!isLoadingFilter ? ( {dataFilter.map(item => { - return ; + return ; })} ) : ( diff --git a/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx b/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx new file mode 100644 index 00000000..656c8f05 --- /dev/null +++ b/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx @@ -0,0 +1,191 @@ +'use client'; + +import { styled } from '@mui/material/styles'; +import { LIST_CURRENCIES_USED } from '@bcpros/lixi-models'; +import { ChevronLeft } from '@mui/icons-material'; +import { + Box, + Button, + Dialog, + DialogContent, + DialogTitle, + IconButton, + Slide, + TextField, + Typography, + useMediaQuery, + useTheme +} from '@mui/material'; +import { TransitionProps } from '@mui/material/transitions'; +import React, { useMemo, useState } from 'react'; +import { FilterCurrencyType } from '../../store/type/types'; + +interface ShoppingCurrencyModalProps { + isOpen: boolean; + onDismissModal?: (value: boolean) => void; + setSelectedItem?: (value: FilterCurrencyType) => void; +} + +const StyledDialog = styled(Dialog)(({ theme }) => ({ + '.MuiPaper-root': { + background: theme.palette.background.default, + backgroundRepeat: 'no-repeat', + backgroundSize: 'cover', + width: '500px', + height: '100vh', + maxHeight: '100%', + margin: 0, + [theme.breakpoints.down('sm')]: { + width: '100%' + } + }, + + '.MuiIconButton-root': { + width: 'fit-content', + svg: { + fontSize: '32px' + } + }, + + '.MuiDialogTitle-root': { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + + '.back-btn': { + position: 'absolute', + left: '10px' + }, + + '.btn-clear': { + color: '#FFF', + position: 'absolute', + right: '10px', + fontSize: '12px', + padding: '1px 5px' + } + }, + + '.MuiDialogContent-root': { + padding: '16px' + }, + + button: { + color: theme.palette.text.secondary + } +})); + +const Transition = React.forwardRef(function Transition( + props: TransitionProps & { + children: React.ReactElement; + }, + ref: React.Ref +) { + return ; +}); + +/** + * Simplified currency modal for Shopping tab + * Shows fiat currencies + XEC in a single list, sorted alphabetically + */ +const ShoppingCurrencyModal: React.FC = props => { + const { isOpen, onDismissModal, setSelectedItem } = props; + const theme = useTheme(); + const fullScreen = useMediaQuery(theme.breakpoints.down('md')); + + const [searchTerm, setSearchTerm] = useState(''); + + // Build combined list of fiat currencies + XEC, sorted alphabetically by code + const currencyList = useMemo(() => { + // Add XEC as a currency option + const xecOption = { code: 'XEC', name: 'eCash' }; + + // Combine fiat currencies with XEC + const allCurrencies = [...LIST_CURRENCIES_USED, xecOption]; + + // Sort alphabetically by code + return allCurrencies.sort((a, b) => a.code.localeCompare(b.code)); + }, []); + + // Filter currencies based on search term + const filteredCurrencies = useMemo(() => { + if (!searchTerm) return currencyList; + + const lowerSearch = searchTerm.toLowerCase(); + return currencyList.filter( + option => + option.code.toLowerCase().includes(lowerSearch) || option.name.toLowerCase().includes(lowerSearch) + ); + }, [currencyList, searchTerm]); + + const handleSelect = (currency: { code: string; name: string }) => { + const filterCurrency: FilterCurrencyType = { + paymentMethod: 5, // PAYMENT_METHOD.GOODS_SERVICES + value: currency.code + }; + setSelectedItem?.(filterCurrency); + onDismissModal?.(false); + setSearchTerm(''); + }; + + const handleClear = () => { + setSelectedItem?.({ paymentMethod: 5, value: '' }); + onDismissModal?.(false); + setSearchTerm(''); + }; + + const handleClose = () => { + onDismissModal?.(false); + setSearchTerm(''); + }; + + return ( + + + + + + Select currency + + + + setSearchTerm(e.target.value)} + value={searchTerm} + autoFocus + /> + + {filteredCurrencies.map(option => ( + + ))} + {filteredCurrencies.length === 0 && ( + + No currencies found + + )} + + + + ); +}; + +export default ShoppingCurrencyModal; diff --git a/apps/telegram-ecash-escrow/src/components/FilterOffer/ShoppingFilterComponent.tsx b/apps/telegram-ecash-escrow/src/components/FilterOffer/ShoppingFilterComponent.tsx index b3a21d1d..d7ff132e 100644 --- a/apps/telegram-ecash-escrow/src/components/FilterOffer/ShoppingFilterComponent.tsx +++ b/apps/telegram-ecash-escrow/src/components/FilterOffer/ShoppingFilterComponent.tsx @@ -18,7 +18,7 @@ import { styled } from '@mui/material/styles'; import { debounce } from 'lodash'; import React, { useCallback, useState } from 'react'; import { NumericFormat } from 'react-number-format'; -import FilterCurrencyModal from '../FilterList/FilterCurrencyModal'; +import ShoppingCurrencyModal from '../FilterList/ShoppingCurrencyModal'; const WrapFilter = styled('div')(({ theme }) => ({ marginBottom: '16px', @@ -228,7 +228,7 @@ const ShoppingFilterComponent: React.FC = ({ filte )}
- handleFilterCurrency(value)} onDismissModal={value => setOpenCurrencyList(value)} diff --git a/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx b/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx index 0ba05cec..163b865b 100644 --- a/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx +++ b/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx @@ -142,9 +142,10 @@ const OfferShowWrapItem = styled('div')(({ theme }) => ({ type OfferItemProps = { timelineItem?: TimelineQueryItem; + hidePaymentMethods?: boolean; }; -export default function OfferItem({ timelineItem }: OfferItemProps) { +export default function OfferItem({ timelineItem, hidePaymentMethods = false }: OfferItemProps) { const { status } = useSession(); const askAuthorization = useAuthorization(); const searchParams = useSearchParams(); @@ -337,7 +338,7 @@ export default function OfferItem({ timelineItem }: OfferItemProps) { )} - {OfferItemPaymentMethod} + {!hidePaymentMethods && {OfferItemPaymentMethod}} From 6c88ff164365a3455a2f550453c861ecfecf3ee3 Mon Sep 17 00:00:00 2001 From: nghiacc Date: Wed, 4 Feb 2026 06:40:04 +0700 Subject: [PATCH 2/5] feat: Add VND currency support for Goods & Services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added VND to LIST_TICKER_GOODS_SERVICES in constants.ts - VND can now be selected in Create Offer price dropdown for G&S offers - VND will appear in Shopping tab currency filter - Conversion uses direct VND/XEC rate from fiat API (1 VND ≈ 4.35 XEC) - Updated getCoinRate function with clearer comments for currency conversion --- .../FilterList/ShoppingCurrencyModal.tsx | 16 ++++------------ .../telegram-ecash-escrow/src/store/constants.ts | 4 ++++ apps/telegram-ecash-escrow/src/store/util.ts | 12 ++++++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx b/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx index 656c8f05..490305c2 100644 --- a/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx +++ b/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx @@ -1,6 +1,5 @@ 'use client'; -import { styled } from '@mui/material/styles'; import { LIST_CURRENCIES_USED } from '@bcpros/lixi-models'; import { ChevronLeft } from '@mui/icons-material'; import { @@ -16,6 +15,7 @@ import { useMediaQuery, useTheme } from '@mui/material'; +import { styled } from '@mui/material/styles'; import { TransitionProps } from '@mui/material/transitions'; import React, { useMemo, useState } from 'react'; import { FilterCurrencyType } from '../../store/type/types'; @@ -113,8 +113,7 @@ const ShoppingCurrencyModal: React.FC = props => { const lowerSearch = searchTerm.toLowerCase(); return currencyList.filter( - option => - option.code.toLowerCase().includes(lowerSearch) || option.name.toLowerCase().includes(lowerSearch) + option => option.code.toLowerCase().includes(lowerSearch) || option.name.toLowerCase().includes(lowerSearch) ); }, [currencyList, searchTerm]); @@ -140,12 +139,7 @@ const ShoppingCurrencyModal: React.FC = props => { }; return ( - + @@ -178,9 +172,7 @@ const ShoppingCurrencyModal: React.FC = props => { ))} {filteredCurrencies.length === 0 && ( - - No currencies found - + No currencies found )} diff --git a/apps/telegram-ecash-escrow/src/store/constants.ts b/apps/telegram-ecash-escrow/src/store/constants.ts index bed05609..dc6174f5 100644 --- a/apps/telegram-ecash-escrow/src/store/constants.ts +++ b/apps/telegram-ecash-escrow/src/store/constants.ts @@ -98,6 +98,10 @@ export const LIST_TICKER_GOODS_SERVICES = [ { id: 2, name: 'USD' + }, + { + id: 3, + name: 'VND' } ]; export const DEFAULT_TICKER_GOODS_SERVICES = 'XEC'; diff --git a/apps/telegram-ecash-escrow/src/store/util.ts b/apps/telegram-ecash-escrow/src/store/util.ts index 450f1894..ade4ea92 100644 --- a/apps/telegram-ecash-escrow/src/store/util.ts +++ b/apps/telegram-ecash-escrow/src/store/util.ts @@ -132,17 +132,21 @@ export const getCoinRate = ({ tickerPriceGoodsServices, rateData }: GetCoinRateOptions): any | null => { - // For Goods & Services: priceGoodsServices is the PRICE (e.g., 1 USD) - // We need to find the USD (or tickerPriceGoodsServices) rate from rateData + // For Goods & Services: priceGoodsServices is the PRICE (e.g., 1 USD or 25000 VND) + // We need to find the currency rate from rateData if (isGoodsServicesConversion && tickerPriceGoodsServices) { - // Find the rate for the ticker currency (e.g., USD rate) const tickerPriceGoodsServicesUpper = tickerPriceGoodsServices.toUpperCase(); + + // Find the direct rate for the ticker currency (USD, VND, etc.) + // rateData contains inverted rates: 1 USD = X XEC, 1 VND = X XEC const tickerRate = rateData.find( (item: { coin?: string; rate?: number }) => item.coin?.toUpperCase() === tickerPriceGoodsServicesUpper )?.rate; + if (tickerRate && priceGoodsServices && priceGoodsServices > 0) { // Return the fiat currency rate multiplied by the price - // E.g., if 1 USD = 68027 XEC and item costs 1 USD, return 68027 + // E.g., if 1 USD = 68027 XEC and item costs 1 USD, return 68027 XEC + // E.g., if 1 VND = 4.35 XEC and item costs 25000 VND, return 108750 XEC return tickerRate * priceGoodsServices; } } From f8cf61f65f99342db1d00f4fce82d834ea06448c Mon Sep 17 00:00:00 2001 From: nghiacc Date: Wed, 4 Feb 2026 06:49:00 +0700 Subject: [PATCH 3/5] fix: Format XEC and fiat prices with proper decimals - XEC prices: Limited to 2 decimal places (e.g., 43,542.01 XEC instead of 43,542.014) - Fiat prices (VND): No decimals with thousands separators (e.g., 10,000 VND instead of 10000) - Updated useOfferPrice hook to round XEC amounts to 2 decimals - Updated formatAmountForGoodsServices to round to 2 decimals - Added formatFiatPrice helper function in OfferDetailInfo components - Display: Price: 43,542.01 XEC / unit (10,000 VND) --- .../src/components/DetailInfo/OfferDetailInfo.tsx | 13 ++++++++++++- .../components/OfferDetailInfo/OfferDetailInfo.tsx | 13 ++++++++++++- .../src/components/OfferItem/OfferItem.tsx | 13 ++++++++++++- .../src/hooks/useOfferPrice.tsx | 9 +++++++-- apps/telegram-ecash-escrow/src/store/util.ts | 4 +++- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/apps/telegram-ecash-escrow/src/components/DetailInfo/OfferDetailInfo.tsx b/apps/telegram-ecash-escrow/src/components/DetailInfo/OfferDetailInfo.tsx index bf7cc435..37ab1362 100644 --- a/apps/telegram-ecash-escrow/src/components/DetailInfo/OfferDetailInfo.tsx +++ b/apps/telegram-ecash-escrow/src/components/DetailInfo/OfferDetailInfo.tsx @@ -96,6 +96,17 @@ const OfferDetailInfo = ({ timelineItem, post, isShowBuyButton = false, isItemTi const isOwner = (postData ?? post)?.accountId === selectedAccountId; + // Format fiat price without decimals and with thousands separators for display + const formatFiatPrice = (price: number | string | undefined): string => { + if (!price) return ''; + const num = typeof price === 'string' ? parseFloat(price) : price; + if (isNaN(num)) return String(price); + return new Intl.NumberFormat('en-GB', { + minimumFractionDigits: 0, + maximumFractionDigits: 0 + }).format(Math.round(num)); + }; + const handleClickAction = e => { e.stopPropagation(); dispatch(openActionSheet('OfferActionSheet', { post: postData })); @@ -184,7 +195,7 @@ const OfferDetailInfo = ({ timelineItem, post, isShowBuyButton = false, isItemTi (offerData?.tickerPriceGoodsServices ?? DEFAULT_TICKER_GOODS_SERVICES) !== DEFAULT_TICKER_GOODS_SERVICES ? ( - ({offerData.priceGoodsServices} {offerData.tickerPriceGoodsServices ?? 'USD'}) + ({formatFiatPrice(offerData.priceGoodsServices)} {offerData.tickerPriceGoodsServices ?? 'USD'}) ) : null} diff --git a/apps/telegram-ecash-escrow/src/components/OfferDetailInfo/OfferDetailInfo.tsx b/apps/telegram-ecash-escrow/src/components/OfferDetailInfo/OfferDetailInfo.tsx index c3c3a7d2..c95baaae 100644 --- a/apps/telegram-ecash-escrow/src/components/OfferDetailInfo/OfferDetailInfo.tsx +++ b/apps/telegram-ecash-escrow/src/components/OfferDetailInfo/OfferDetailInfo.tsx @@ -42,6 +42,17 @@ const OrderDetailInfo = ({ key, post }: { key: string; post: Post }) => { isGoodsServices: _isGoodsServices } = useOfferPrice({ paymentInfo: post?.offer, inputAmount: 1 }); + // Format fiat price without decimals and with thousands separators for display + const formatFiatPrice = (price: number | string | undefined): string => { + if (!price) return ''; + const num = typeof price === 'string' ? parseFloat(price) : price; + if (isNaN(num)) return String(price); + return new Intl.NumberFormat('en-GB', { + minimumFractionDigits: 0, + maximumFractionDigits: 0 + }).format(Math.round(num)); + }; + return ( @@ -60,7 +71,7 @@ const OrderDetailInfo = ({ key, post }: { key: string; post: Post }) => { (post.offer?.tickerPriceGoodsServices ?? DEFAULT_TICKER_GOODS_SERVICES) !== DEFAULT_TICKER_GOODS_SERVICES ? ( - ({post.offer.priceGoodsServices} {post.offer.tickerPriceGoodsServices ?? 'USD'}) + ({formatFiatPrice(post.offer.priceGoodsServices)} {post.offer.tickerPriceGoodsServices ?? 'USD'}) ) : null} diff --git a/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx b/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx index 163b865b..ed6a26be 100644 --- a/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx +++ b/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx @@ -165,6 +165,17 @@ export default function OfferItem({ timelineItem, hidePaymentMethods = false }: const settingContext = useContext(SettingContext); const seedBackupTime = settingContext?.setting?.lastSeedBackupTime ?? lastSeedBackupTimeOnDevice ?? ''; + // Format fiat price without decimals and with thousands separators for display + const formatFiatPrice = (price: number | string | undefined): string => { + if (!price) return ''; + const num = typeof price === 'string' ? parseFloat(price) : price; + if (isNaN(num)) return String(price); + return new Intl.NumberFormat('en-GB', { + minimumFractionDigits: 0, + maximumFractionDigits: 0 + }).format(Math.round(num)); + }; + const { useGetAccountByAddressQuery } = accountsApi; const { currentData: accountQueryData } = useGetAccountByAddressQuery( { address: selectedWalletPath?.xAddress }, @@ -351,7 +362,7 @@ export default function OfferItem({ timelineItem, hidePaymentMethods = false }: (offerData?.tickerPriceGoodsServices ?? DEFAULT_TICKER_GOODS_SERVICES) !== DEFAULT_TICKER_GOODS_SERVICES ? ( - ({offerData.priceGoodsServices} {offerData.tickerPriceGoodsServices ?? 'USD'}) + ({formatFiatPrice(offerData.priceGoodsServices)} {offerData.tickerPriceGoodsServices ?? 'USD'}) ) : null} diff --git a/apps/telegram-ecash-escrow/src/hooks/useOfferPrice.tsx b/apps/telegram-ecash-escrow/src/hooks/useOfferPrice.tsx index 954e8ef8..895fcd78 100644 --- a/apps/telegram-ecash-escrow/src/hooks/useOfferPrice.tsx +++ b/apps/telegram-ecash-escrow/src/hooks/useOfferPrice.tsx @@ -187,7 +187,9 @@ export default function useOfferPrice({ paymentInfo, inputAmount = 1 }: UseOffer const priceOf1XECInLocalCurrency = xecRateEntry.rate; const priceOf1MXECInLocalCurrency = priceOf1XECInLocalCurrency * 1000000; - setAmountXECGoodsServices(1); // 1 XEC + // Round to 2 decimal places for XEC display + const roundedXEC = Math.round(1 * 100) / 100; + setAmountXECGoodsServices(roundedXEC); setAmountPer1MXEC( formatAmountFor1MXEC(priceOf1MXECInLocalCurrency, paymentInfo?.marginPercentage, coinCurrency, isBuyOffer) ); @@ -212,7 +214,10 @@ export default function useOfferPrice({ paymentInfo, inputAmount = 1 }: UseOffer ? paymentInfo.priceGoodsServices : 1; // Default to 1 XEC for legacy offers without price - setAmountXECGoodsServices(displayPrice); + // Round XEC to maximum 2 decimal places + const roundedPrice = Math.round(displayPrice * 100) / 100; + + setAmountXECGoodsServices(roundedPrice); setAmountPer1MXEC( formatAmountFor1MXEC(amountCoinOrCurrency, paymentInfo?.marginPercentage, coinCurrency, isBuyOffer) ); diff --git a/apps/telegram-ecash-escrow/src/store/util.ts b/apps/telegram-ecash-escrow/src/store/util.ts index ade4ea92..6e61ada2 100644 --- a/apps/telegram-ecash-escrow/src/store/util.ts +++ b/apps/telegram-ecash-escrow/src/store/util.ts @@ -283,7 +283,9 @@ export function formatAmountFor1MXEC(amount, marginPercentage = 0, coinCurrency } export function formatAmountForGoodsServices(amount) { - return `${formatNumber(amount)} XEC / ${GOODS_SERVICES_UNIT}`; + // Limit XEC to 2 decimal places + const roundedAmount = Math.round(amount * 100) / 100; + return `${formatNumber(roundedAmount)} XEC / ${GOODS_SERVICES_UNIT}`; } /** From 836ceebe3a843a7d261a5dbcace89d571494cca0 Mon Sep 17 00:00:00 2001 From: nghiacc Date: Wed, 4 Feb 2026 07:02:47 +0700 Subject: [PATCH 4/5] fix: Address PR review comments - ShoppingCurrencyModal: Add aria-label to IconButton for accessibility - shopping/page.tsx: Remove invalid scrollableTarget reference (use window scrolling) --- apps/telegram-ecash-escrow/src/app/shopping/page.tsx | 1 - .../src/components/DetailInfo/OfferDetailInfo.tsx | 2 +- .../src/components/FilterList/ShoppingCurrencyModal.tsx | 2 +- .../src/components/OfferDetailInfo/OfferDetailInfo.tsx | 2 +- .../src/components/OfferItem/OfferItem.tsx | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/telegram-ecash-escrow/src/app/shopping/page.tsx b/apps/telegram-ecash-escrow/src/app/shopping/page.tsx index 493fdfea..33c9b1e3 100644 --- a/apps/telegram-ecash-escrow/src/app/shopping/page.tsx +++ b/apps/telegram-ecash-escrow/src/app/shopping/page.tsx @@ -213,7 +213,6 @@ export default function Shopping() { } - scrollableTarget="scrollableDiv" scrollThreshold={'100px'} > {dataFilter.map(item => { diff --git a/apps/telegram-ecash-escrow/src/components/DetailInfo/OfferDetailInfo.tsx b/apps/telegram-ecash-escrow/src/components/DetailInfo/OfferDetailInfo.tsx index 37ab1362..0871c0cd 100644 --- a/apps/telegram-ecash-escrow/src/components/DetailInfo/OfferDetailInfo.tsx +++ b/apps/telegram-ecash-escrow/src/components/DetailInfo/OfferDetailInfo.tsx @@ -98,7 +98,7 @@ const OfferDetailInfo = ({ timelineItem, post, isShowBuyButton = false, isItemTi // Format fiat price without decimals and with thousands separators for display const formatFiatPrice = (price: number | string | undefined): string => { - if (!price) return ''; + if (price == null || price === '') return ''; const num = typeof price === 'string' ? parseFloat(price) : price; if (isNaN(num)) return String(price); return new Intl.NumberFormat('en-GB', { diff --git a/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx b/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx index 490305c2..8bdb4de7 100644 --- a/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx +++ b/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx @@ -141,7 +141,7 @@ const ShoppingCurrencyModal: React.FC = props => { return ( - + Select currency diff --git a/apps/telegram-ecash-escrow/src/components/OfferDetailInfo/OfferDetailInfo.tsx b/apps/telegram-ecash-escrow/src/components/OfferDetailInfo/OfferDetailInfo.tsx index c95baaae..e07e398b 100644 --- a/apps/telegram-ecash-escrow/src/components/OfferDetailInfo/OfferDetailInfo.tsx +++ b/apps/telegram-ecash-escrow/src/components/OfferDetailInfo/OfferDetailInfo.tsx @@ -44,7 +44,7 @@ const OrderDetailInfo = ({ key, post }: { key: string; post: Post }) => { // Format fiat price without decimals and with thousands separators for display const formatFiatPrice = (price: number | string | undefined): string => { - if (!price) return ''; + if (price == null || price === '') return ''; const num = typeof price === 'string' ? parseFloat(price) : price; if (isNaN(num)) return String(price); return new Intl.NumberFormat('en-GB', { diff --git a/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx b/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx index ed6a26be..508d92ee 100644 --- a/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx +++ b/apps/telegram-ecash-escrow/src/components/OfferItem/OfferItem.tsx @@ -167,7 +167,7 @@ export default function OfferItem({ timelineItem, hidePaymentMethods = false }: // Format fiat price without decimals and with thousands separators for display const formatFiatPrice = (price: number | string | undefined): string => { - if (!price) return ''; + if (price == null || price === '') return ''; const num = typeof price === 'string' ? parseFloat(price) : price; if (isNaN(num)) return String(price); return new Intl.NumberFormat('en-GB', { From fb4ec6f42582b76dd016f7738d7173bacb65c30f Mon Sep 17 00:00:00 2001 From: nghiacc Date: Wed, 4 Feb 2026 07:11:33 +0700 Subject: [PATCH 5/5] fix: Add aria-labelledby to ShoppingCurrencyModal for accessibility - Use React's useId() hook to generate unique dialog title ID - Add aria-labelledby to StyledDialog referencing the title ID - Improves screen reader support by properly associating dialog with its title --- .../components/FilterList/ShoppingCurrencyModal.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx b/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx index 8bdb4de7..932a0d35 100644 --- a/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx +++ b/apps/telegram-ecash-escrow/src/components/FilterList/ShoppingCurrencyModal.tsx @@ -17,7 +17,7 @@ import { } from '@mui/material'; import { styled } from '@mui/material/styles'; import { TransitionProps } from '@mui/material/transitions'; -import React, { useMemo, useState } from 'react'; +import React, { useId, useMemo, useState } from 'react'; import { FilterCurrencyType } from '../../store/type/types'; interface ShoppingCurrencyModalProps { @@ -94,6 +94,7 @@ const ShoppingCurrencyModal: React.FC = props => { const fullScreen = useMediaQuery(theme.breakpoints.down('md')); const [searchTerm, setSearchTerm] = useState(''); + const titleId = useId(); // Build combined list of fiat currencies + XEC, sorted alphabetically by code const currencyList = useMemo(() => { @@ -139,8 +140,14 @@ const ShoppingCurrencyModal: React.FC = props => { }; return ( - - + +