From 97aa7860a940c2552c2969a39337ec342caf0051 Mon Sep 17 00:00:00 2001 From: kayela Date: Tue, 27 Jan 2026 14:33:36 -0600 Subject: [PATCH] feat: integrate TransactionHistory component into Dashboard and update styles for better UI consistency --- src/components/TransactionHistory.js | 4 +- src/pages/Dashboard.js | 260 ++++++++----------------- src/pages/admin/AdminFinancials.js | 7 +- src/pages/admin/AdminNewsletters.js | 7 +- src/pages/members/NewsletterArchive.js | 6 +- 5 files changed, 92 insertions(+), 192 deletions(-) diff --git a/src/components/TransactionHistory.js b/src/components/TransactionHistory.js index 9843a53..e375a27 100644 --- a/src/components/TransactionHistory.js +++ b/src/components/TransactionHistory.js @@ -70,9 +70,9 @@ const TransactionHistory = ({
{isSubscription ? ( - + ) : ( - + )}
diff --git a/src/pages/Dashboard.js b/src/pages/Dashboard.js index ee8ad38..6b74a27 100644 --- a/src/pages/Dashboard.js +++ b/src/pages/Dashboard.js @@ -9,6 +9,8 @@ import Navbar from '../components/Navbar'; import MemberFooter from '../components/MemberFooter'; import { Calendar, User, CheckCircle, Clock, AlertCircle, Mail, Users, Image, FileText, DollarSign, Scale, Receipt, Heart, CreditCard } from 'lucide-react'; import { toast } from 'sonner'; +import TransactionHistory from '../components/TransactionHistory'; + const Dashboard = () => { const { user, resendVerificationEmail, refreshUser } = useAuth(); @@ -17,12 +19,15 @@ const Dashboard = () => { const [resendLoading, setResendLoading] = useState(false); const [eventActivity, setEventActivity] = useState(null); const [activityLoading, setActivityLoading] = useState(true); + const [transactionsLoading, setTransactionsLoading] = useState(true); + const [transactions, setTransactions] = useState({ subscriptions: [], donations: [] }); const [activeTransactionTab, setActiveTransactionTab] = useState('all'); const joinedDate = user?.member_since || user?.created_at; useEffect(() => { fetchUpcomingEvents(); fetchEventActivity(); + fetchTransactions(); }, []); const fetchUpcomingEvents = async () => { @@ -48,6 +53,19 @@ const Dashboard = () => { } }; + const fetchTransactions = async () => { + try { + setTransactionsLoading(true); + const response = await api.get('/members/transactions'); + setTransactions(response.data); + } catch (error) { + console.error('Failed to load transactions:', error); + // Don't show error toast - transactions are optional + } finally { + setTransactionsLoading(false); + } + }; + const handleResendVerification = async () => { setResendLoading(true); try { @@ -72,6 +90,7 @@ const Dashboard = () => { } }; + const getStatusBadge = (status) => { const statusConfig = { pending_email: { icon: Clock, label: 'Pending Email', className: 'bg-orange-100 text-orange-700' }, @@ -183,67 +202,57 @@ const Dashboard = () => { {/* Grid Layout */}
{/* Quick Stats */} - -

- Quick Info -

-
-
-

Email

-

{user?.email}

-
-
-

Role

-

{user?.role}

-
-
-

Member Since

-

- {joinedDate ? new Date(joinedDate).toLocaleDateString() : 'N/A'} -

-
- {user?.subscription_start_date && user?.subscription_end_date && ( - <> -
-

Membership Period

-

- {new Date(user.subscription_start_date).toLocaleDateString()} - {new Date(user.subscription_end_date).toLocaleDateString()} -

-
-
-

Days Remaining

-

- {Math.max(0, Math.ceil((new Date(user.subscription_end_date) - new Date()) / (1000 * 60 * 60 * 24)))} days -

-
- - )} -
-
- -

- Membership Info -

-
+
- {user?.subscription_start_date && user?.subscription_end_date && ( - <> -
-

Membership Period

-

- {new Date(user.subscription_start_date).toLocaleDateString()} - {new Date(user.subscription_end_date).toLocaleDateString()} -

-
-
-

Days Remaining

-

- {Math.max(0, Math.ceil((new Date(user.subscription_end_date) - new Date()) / (1000 * 60 * 60 * 24)))} days -

-
- - )} -
- + +

+ Quick Info +

+
+
+

Email

+

{user?.email}

+
+
+

Role

+

{user?.role}

+
+
+

Member Since

+

+ {joinedDate ? new Date(joinedDate).toLocaleDateString() : 'N/A'} +

+
+ +
+
+ +

+ Membership Info +

+
+ {!user.subscription_end_date && !user.subscription_end_date && ( +
No subscriptions yet
+ )} + {user?.subscription_start_date && user?.subscription_end_date && ( + <> +
+

Membership Period

+

+ {new Date(user.subscription_start_date).toLocaleDateString()} - {new Date(user.subscription_end_date).toLocaleDateString()} +

+
+
+

Days Remaining

+

+ {Math.max(0, Math.ceil((new Date(user.subscription_end_date) - new Date()) / (1000 * 60 * 60 * 24)))} days +

+
+ + )} +
+
+
{/* Upcoming Events */} @@ -337,127 +346,16 @@ const Dashboard = () => { )} {/* Transaction History Section */} - - {/* Header */} -
-
- -
-

- Transaction History -

-
- - {/* Stats Row */} -
-
-
- - - Total Subscriptions - -
-

- $30.00 -

-

- 1 payment(s) -

-
-
-
- - - Total Donations - -
-

- $0.00 -

-

- 0 donation(s) -

-
-
- - {/* Filter Tabs */} -
- - - -
- - {/* Transaction List */} -
- {(activeTransactionTab === 'all' || activeTransactionTab === 'subscriptions') && ( -
-
-
-
-
- - Annual Membership - - - active - -
-
- - Dec 16, 2025 - - Custom -
- - Manual Payment - -
-
- - $30.00 - -
- )} - {activeTransactionTab === 'donations' && ( -
- -

- No donations yet -

-
- )} -
-
+
+ +
diff --git a/src/pages/admin/AdminFinancials.js b/src/pages/admin/AdminFinancials.js index d29bc67..7838efd 100644 --- a/src/pages/admin/AdminFinancials.js +++ b/src/pages/admin/AdminFinancials.js @@ -191,10 +191,9 @@ const AdminFinancials = () => {
{reports.map(report => ( -
-
- -
{report.year}
+
+
+

diff --git a/src/pages/admin/AdminNewsletters.js b/src/pages/admin/AdminNewsletters.js index 479a6fb..bb4a565 100644 --- a/src/pages/admin/AdminNewsletters.js +++ b/src/pages/admin/AdminNewsletters.js @@ -223,10 +223,13 @@ const AdminNewsletters = () => { {year}

-
+
{groupedNewsletters[year].map(newsletter => ( -
+
+
+ +

{newsletter.title} diff --git a/src/pages/members/NewsletterArchive.js b/src/pages/members/NewsletterArchive.js index 9febb0a..48513bc 100644 --- a/src/pages/members/NewsletterArchive.js +++ b/src/pages/members/NewsletterArchive.js @@ -167,9 +167,9 @@ export default function NewsletterArchive() { {groupedNewsletters[year].map(newsletter => (
-
- -
+
+ +

{newsletter.title}