main
tsx 154 lines 5.95 KB
Raw
1 import { useEffect, useState } from "react";
2 import { useNavigate } from "react-router-dom";
3 import { Card } from "@/components/ui/card";
4 import { Badge } from "@/components/ui/badge";
5 import { ArrowUpRight, ArrowDownRight, Plus } from "lucide-react";
6 import { Button } from "@/components/ui/button";
7 import { transactionService } from "@/services/transactionService";
8 import { Transaction } from "@/types/transaction";
9 import { formatDistanceToNow } from "date-fns";
10 import { useLang } from "@/context/LanguageContext";
11 import { useAccount } from "@/context/AccountContext";
12
13 const Home = () => {
14 const navigate = useNavigate();
15 const { t, lang } = useLang();
16 const [transactions, setTransactions] = useState<Transaction[]>([]);
17 const [loading, setLoading] = useState(true);
18 const balance = transactionService.getBalance();
19 const isRTL = lang === "fa";
20 const { loggedIn, user } = useAccount();
21
22 useEffect(() => {
23 const loadTransactions = async () => {
24 const data = await transactionService.getTransactions();
25 setTransactions(data);
26 setLoading(false);
27 };
28 loadTransactions();
29 }, [user]);
30
31 return (
32 <div className="p-4 space-y-6" dir={isRTL ? "rtl" : "ltr"}>
33 {!loggedIn && (
34 <Card className="p-8 bg-card border-0 shadow-lg">
35 <div className="space-y-2">Login to see your account</div>
36 </Card>
37 )}
38 {/* LOGGED IN */}
39 {user && (
40 <>
41 {/* Balance Card */}
42 <Card className="p-8 bg-card border-0 shadow-lg">
43 <div className="space-y-2">
44 <p className="text-sm text-muted-foreground font-medium">
45 {t.availableBalance}
46 </p>
47 <h2 className="text-5xl font-bold tracking-tight">
48 ${balance.toFixed(2)}
49 </h2>
50 </div>
51 <div className="mt-8">
52 <Button
53 size="lg"
54 className="w-full"
55 onClick={() => navigate("/send")}
56 >
57 <Plus className={`h-5 w-5 ${isRTL ? "ml-2" : "mr-2"}`} />
58 {t.sendMoney}
59 </Button>
60 </div>
61 </Card>
62
63 {/* Stats */}
64 <div className="grid grid-cols-2 gap-4">
65 <Card className="p-6 border-0 shadow-md">
66 <div className="space-y-2">
67 <p className="text-sm text-muted-foreground font-medium">
68 {t.thisMonth}
69 </p>
70 <p className="text-3xl font-bold text-foreground">$985</p>
71 <div className="flex items-center gap-1 text-expense-negative text-sm font-medium">
72 <ArrowUpRight className="h-4 w-4" />
73 <span>{t.spent}</span>
74 </div>
75 </div>
76 </Card>
77 <Card className="p-6 border-0 shadow-md">
78 <div className="space-y-2">
79 <p className="text-sm text-muted-foreground font-medium">
80 {t.saved}
81 </p>
82 <p className="text-3xl font-bold text-foreground">$450</p>
83 <div className="flex items-center gap-1 text-expense-positive text-sm font-medium">
84 <ArrowDownRight className="h-4 w-4" />
85 <span>{t.thisMonth}</span>
86 </div>
87 </div>
88 </Card>
89 </div>
90
91 {/* Recent Transactions */}
92 <div className="space-y-4">
93 <h3 className="text-xl font-bold">{t.recentTransactions}</h3>
94 {loading ? (
95 <Card className="p-8 border-0 shadow-md text-center">
96 <p className="text-muted-foreground">{t.loadingTransactions}</p>
97 </Card>
98 ) : transactions.length === 0 ? (
99 <Card className="p-8 border-0 shadow-md text-center">
100 <p className="text-muted-foreground">{t.noTransactions}</p>
101 </Card>
102 ) : (
103 <div className="space-y-3">
104 {transactions.map((transaction) => (
105 <Card
106 key={transaction.id}
107 className="p-5 border-0 shadow-md hover:shadow-lg transition-all cursor-pointer"
108 >
109 <div className="flex items-center justify-between">
110 <div className="flex-1">
111 <div className="flex items-center gap-3 mb-1">
112 <p className="font-semibold text-base">
113 {transaction.recipientName}
114 </p>
115 {transaction.status === "processing" && (
116 <Badge
117 variant="outline"
118 className="text-xs font-medium border-2"
119 >
120 {t.processing}
121 </Badge>
122 )}
123 {transaction.status === "pending" && (
124 <Badge
125 variant="outline"
126 className="text-xs font-medium border-2 border-yellow-500"
127 >
128 {t.pending}
129 </Badge>
130 )}
131 </div>
132 <p className="text-sm text-muted-foreground font-medium">
133 {transaction.description || t.payment} ·{" "}
134 {formatDistanceToNow(transaction.timestamp, {
135 addSuffix: true,
136 })}
137 </p>
138 </div>
139 <p className="text-xl font-bold text-foreground">
140 -{transaction.currency} {transaction.amount.toFixed(2)}
141 </p>
142 </div>
143 </Card>
144 ))}
145 </div>
146 )}
147 </div>
148 </>
149 )}
150 </div>
151 );
152 };
153
154 export default Home;