Skip to content

Commit ae99124

Browse files
authored
Merge pull request #418 from OperaCode/feature/implement-issues-362-377-360-366
fixed issues : #362, #377, #360, #366
2 parents 715a0ab + 3fd3a82 commit ae99124

540 files changed

Lines changed: 11286 additions & 3099 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dex_with_fiat_frontend/playwright-report/index.html

Lines changed: 85 additions & 0 deletions
Large diffs are not rendered by default.

dex_with_fiat_frontend/src/components/ChatHistorySidebar.tsx

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,32 @@ export default function ChatHistorySidebar({
190190
};
191191

192192
return (
193-
<div className={`theme-surface h-full flex flex-col transition-all duration-300 border-r ${isCollapsed ? 'w-20' : 'w-full'} transition-colors duration-300`}>
194-
<div className={`theme-border border-b transition-colors duration-300 ${isCollapsed ? 'p-4 flex flex-col items-center' : 'p-4'}`}>
195-
<div className={`flex items-center justify-between mb-4 w-full ${isCollapsed ? 'flex-col gap-4' : ''}`}>
196-
{!isCollapsed && <h2 className="theme-text-primary text-lg font-semibold">Activity</h2>}
197-
<div className={`flex items-center gap-1 ${isCollapsed ? 'flex-col' : ''}`}>
193+
<div
194+
className={`theme-surface h-full flex flex-col transition-all duration-300 border-r ${
195+
isCollapsed ? 'w-20' : 'w-full'
196+
} transition-colors duration-300`}
197+
>
198+
<div
199+
className={`theme-border border-b transition-colors duration-300 ${
200+
isCollapsed ? 'p-4 flex flex-col items-center' : 'p-4'
201+
}`}
202+
>
203+
<div
204+
className={`flex items-center justify-between mb-4 w-full ${
205+
isCollapsed ? 'flex-col gap-4' : ''
206+
}`}
207+
>
208+
209+
{!isCollapsed && (
210+
<h2 className="theme-text-primary text-lg font-semibold">
211+
Activity
212+
</h2>
213+
)}
214+
<div
215+
className={`flex items-center gap-1 ${
216+
isCollapsed ? 'flex-col' : ''
217+
}`}
218+
>
198219
<button
199220
onClick={clearAllHistory}
200221
className="theme-text-muted hover:bg-[var(--color-danger-soft)] p-2 rounded-lg transition-all duration-200 hover:scale-110"
@@ -301,9 +322,8 @@ export default function ChatHistorySidebar({
301322
<div className="theme-border border-t p-4 space-y-4">
302323
<PriceTicker symbols={['XLM', 'ETH', 'BTC']} currency="usd" />
303324

304-
<div className="flex items-center justify-between mb-3">
305-
<div className={`theme-border border-t p-4 ${isCollapsed ? 'flex flex-col items-center' : ''}`}>
306-
<div className={`flex items-center justify-between mb-3 w-full ${isCollapsed ? 'flex-col gap-3' : ''}`}>
325+
<div className={`theme-border border-t p-4 ${isCollapsed ? 'flex flex-col items-center' : ''}`}>
326+
<div className={`flex items-center justify-between mb-3 w-full ${isCollapsed ? 'flex-col gap-3' : ''}`}>
307327
<div className="flex items-center gap-2">
308328
<Coins className="w-4 h-4 text-[var(--color-primary)]" />
309329
{!isCollapsed && (
@@ -458,5 +478,6 @@ export default function ChatHistorySidebar({
458478
</div>
459479
)}
460480
</div>
481+
</div>
461482
);
462483
}

dex_with_fiat_frontend/src/components/LandingPage.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
} from 'lucide-react';
3030
import { useRouter } from 'next/navigation';
3131
import { useTheme } from '../contexts/ThemeContext';
32+
import OfflineStatusBanner from '@/components/OfflineStatusBanner';
3233

3334
interface FeatureCardProps {
3435
icon: React.ElementType;
@@ -215,6 +216,9 @@ export default function LandingPage() {
215216

216217
return (
217218
<div className="min-h-screen bg-[var(--background)] text-[var(--foreground)] transition-colors duration-200">
219+
{/* Offline Status Banner */}
220+
<OfflineStatusBanner />
221+
218222
{/* Theme Toggle Button */}
219223
<div className="fixed top-6 right-6 z-50">
220224
<button

dex_with_fiat_frontend/src/components/Message.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useStellarWallet } from '@/contexts/StellarWalletContext';
44
import { useTheme } from '@/contexts/ThemeContext';
55
import { useUserPreferences } from '@/contexts/UserPreferencesContext';
66
import { useMasking } from '@/hooks/useMasking';
7+
import { useCurrencyConversion } from '@/hooks/useCurrencyConversion';
78
import { ChatMessage } from '@/types';
89
import { AlertTriangle, Bot, Clock, Coins, Copy, Check, Link, RotateCcw, User, Loader2, RefreshCcw, XCircle } from 'lucide-react';
910
import React, { useState, useCallback } from 'react';
@@ -40,6 +41,16 @@ export default function Message({ message, onActionClick, onRetry, shouldAnimate
4041
const isFailed = message.metadata?.status === 'failed';
4142
const [receiptCopied, setReceiptCopied] = useState(false);
4243

44+
// Currency conversion hook for transaction amounts
45+
const amountForConversion = message.metadata?.transactionData?.amountIn
46+
? parseFloat(String(message.metadata.transactionData.amountIn))
47+
: undefined;
48+
const tokenForConversion = message.metadata?.transactionData?.tokenIn || 'XLM';
49+
const { displayText: conversionDisplayText } = useCurrencyConversion(
50+
amountForConversion,
51+
tokenForConversion,
52+
);
53+
4354
const handleCopyReceiptId = useCallback((receiptId: string) => {
4455
navigator.clipboard?.writeText(receiptId).then(() => {
4556
setReceiptCopied(true);
@@ -325,7 +336,7 @@ export default function Message({ message, onActionClick, onRetry, shouldAnimate
325336
<div className="flex justify-between">
326337
<span>Amount:</span>
327338
<span className="theme-text-primary font-medium">
328-
{message.metadata.transactionData.amountIn}
339+
{conversionDisplayText || message.metadata.transactionData.amountIn}
329340
</span>
330341
</div>
331342
)}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use client';
2+
3+
import { useEffect, useState } from 'react';
4+
import { AlertTriangle, WifiOff } from 'lucide-react';
5+
import { useOnlineStatus } from '@/hooks/useOnlineStatus';
6+
import { useToast } from '@/hooks/useToast';
7+
8+
/**
9+
* Offline Status Banner Component
10+
* Shows when the user loses internet connection
11+
* Displays accessibility-compliant live region
12+
*/
13+
export default function OfflineStatusBanner() {
14+
const { isOnline, wasOffline, resetWasOffline } = useOnlineStatus();
15+
const { addToast } = useToast();
16+
const [showBanner, setShowBanner] = useState(false);
17+
18+
useEffect(() => {
19+
if (!isOnline) {
20+
setShowBanner(true);
21+
} else if (wasOffline && isOnline) {
22+
// Show toast when coming back online
23+
addToast({
24+
message: 'Your connection has been restored. Queued messages will be sent.',
25+
severity: 'success',
26+
durationMs: 3000,
27+
});
28+
setShowBanner(false);
29+
resetWasOffline();
30+
}
31+
}, [isOnline, wasOffline, addToast, resetWasOffline]);
32+
33+
if (!showBanner) return null;
34+
35+
return (
36+
<div
37+
role="status"
38+
aria-live="polite"
39+
aria-atomic="true"
40+
className="fixed top-0 left-0 right-0 z-50 bg-red-50 dark:bg-red-900/20 border-b-2 border-red-500 shadow-md"
41+
>
42+
<div className="max-w-7xl mx-auto px-4 py-3 flex items-center gap-3">
43+
<div className="shrink-0">
44+
<WifiOff className="w-5 h-5 text-red-600 dark:text-red-400 animate-pulse" />
45+
</div>
46+
<div className="flex-1">
47+
<p className="text-sm font-medium text-red-800 dark:text-red-200">
48+
You are offline. Messages will be sent when you reconnect.
49+
</p>
50+
</div>
51+
<div className="shrink-0 text-red-600 dark:text-red-400">
52+
<AlertTriangle className="w-5 h-5" />
53+
</div>
54+
</div>
55+
</div>
56+
);
57+
}

dex_with_fiat_frontend/src/components/ReceiptDrawer.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
'use client';
2-
31
import React from 'react';
42
import { X, Receipt, ExternalLink, Clock, CheckCircle2, AlertCircle, Trash2 } from 'lucide-react';
53
import { TransactionHistoryEntry } from '@/types';
64
import { useTranslation } from '@/contexts/TranslationContext';
75
import { useTheme } from '@/contexts/ThemeContext';
86
import { useTransactionFilters } from '@/hooks/useTransactionFilters';
7+
import { TransactionAmountDisplay } from './TransactionAmountDisplay';
98
import { FilterChipBar } from './filters/FilterChipBar';
109

1110
interface ReceiptDrawerProps {
@@ -146,9 +145,12 @@ export default function ReceiptDrawer({
146145
<div className="space-y-2 text-sm">
147146
<div className="flex justify-between">
148147
<span className="text-gray-500">{t('receipt.amount')}</span>
149-
<span className="font-medium dark:text-gray-300">
150-
{tx.amount} {tx.asset}
151-
</span>
148+
<TransactionAmountDisplay
149+
amount={tx.amount}
150+
asset={tx.asset}
151+
fiatAmount={tx.fiatAmount}
152+
fiatCurrency={tx.fiatCurrency}
153+
/>
152154
</div>
153155
{tx.fiatAmount && (
154156
<div className="flex justify-between">
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use client';
2+
3+
import { useCurrencyConversion } from '@/hooks/useCurrencyConversion';
4+
5+
interface TransactionAmountDisplayProps {
6+
amount?: number | string;
7+
asset?: string;
8+
fiatAmount?: string | number;
9+
fiatCurrency?: string;
10+
}
11+
12+
/**
13+
* Component to display transaction amounts with live currency conversion
14+
* Shows format: "100 XLM ≈ $12.40 USD"
15+
* Falls back to just amount if price is unavailable
16+
*/
17+
export function TransactionAmountDisplay({
18+
amount,
19+
asset,
20+
fiatAmount,
21+
fiatCurrency,
22+
}: TransactionAmountDisplayProps) {
23+
const numericAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
24+
const normalizedAsset = asset || 'XLM';
25+
const { displayText } = useCurrencyConversion(numericAmount, normalizedAsset);
26+
27+
return (
28+
<div className="flex flex-col gap-1">
29+
<span className="font-medium dark:text-gray-300">
30+
{displayText}
31+
</span>
32+
{fiatAmount && fiatCurrency && (
33+
<span className="text-xs text-gray-500 dark:text-gray-400">
34+
Stored fiat: {fiatAmount} {fiatCurrency}
35+
</span>
36+
)}
37+
</div>
38+
);
39+
}

dex_with_fiat_frontend/src/components/TransferTimeline.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,22 @@ export default function TransferTimeline({
124124
);
125125
}
126126

127+
const currentEvent = events[events.length - 1];
128+
const currentMeta = STATUS_META[currentEvent.status];
129+
const currentStatusAnnouncement = `${currentMeta.label}. ${currentEvent.label ?? currentMeta.defaultLabel}`;
130+
127131
return (
128132
<div className="relative" aria-label="Transfer status timeline">
133+
{/* Accessibility: Live region to announce status changes */}
134+
<div
135+
aria-live="polite"
136+
aria-atomic="true"
137+
className="sr-only"
138+
role="status"
139+
>
140+
{currentStatusAnnouncement}
141+
</div>
142+
129143
{/* Vertical connector line */}
130144
<span
131145
className="absolute left-[19px] top-5 bottom-5 w-px bg-[var(--color-border)]"

0 commit comments

Comments
 (0)