Skip to content

Commit 0e08ae8

Browse files
authored
Merge pull request #27 from fuzziecoder/codex/fix-multiple-issues-26,-20,-and-17
Codex-generated pull request
2 parents d96253c + ec82696 commit 0e08ae8

8 files changed

Lines changed: 106 additions & 84 deletions

File tree

DATABASE_SCHEMA.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ CREATE POLICY "Users can delete own moments" ON moments
242242
FOR DELETE USING (auth.uid() = user_id);
243243
```
244244

245-
<<<<<<< HEAD
246245
### 7. `transactions` table
247246

248247
Stores transaction history for payment tracking.
@@ -302,19 +301,14 @@ CREATE POLICY "Admins can update transactions" ON transactions
302301
);
303302
```
304303

305-
=======
306-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b
307304
## Real-time Subscriptions
308305

309306
Enable real-time for the following tables in Supabase Dashboard:
310307
- `spots` - for spot updates
311308
- `invitations` - for RSVP updates
312309
- `payments` - for payment status updates
313310
- `chat_messages` - for chat updates
314-
<<<<<<< HEAD
315311
- `transactions` - for transaction history updates
316-
=======
317-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b
318312

319313
## Initial Data
320314

components/common/TransactionHistory.tsx

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useMemo, useState } from "react";
22
import { Transaction, PaymentStatus } from "../../types";
33
import Card from "./Card";
44

@@ -7,10 +7,16 @@ interface TransactionHistoryProps {
77
loading?: boolean;
88
}
99

10+
type DateFilter = "7d" | "30d" | "custom" | "all";
11+
1012
const TransactionHistory: React.FC<TransactionHistoryProps> = ({
1113
transactions,
1214
loading = false,
1315
}) => {
16+
const [dateFilter, setDateFilter] = useState<DateFilter>("all");
17+
const [customStart, setCustomStart] = useState("");
18+
const [customEnd, setCustomEnd] = useState("");
19+
1420
const formatDate = (dateString: string) => {
1521
const date = new Date(dateString);
1622
return date.toLocaleDateString("en-IN", {
@@ -34,6 +40,39 @@ const TransactionHistory: React.FC<TransactionHistoryProps> = ({
3440
);
3541
};
3642

43+
const filteredTransactions = useMemo(() => {
44+
if (dateFilter === "all") return transactions;
45+
46+
const now = new Date();
47+
const nowAtMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
48+
49+
return transactions.filter((transaction) => {
50+
const txDate = new Date(transaction.created_at);
51+
const txAtMidnight = new Date(txDate.getFullYear(), txDate.getMonth(), txDate.getDate()).getTime();
52+
53+
if (dateFilter === "7d") {
54+
const sevenDaysAgo = nowAtMidnight - 6 * 24 * 60 * 60 * 1000;
55+
return txAtMidnight >= sevenDaysAgo && txAtMidnight <= nowAtMidnight;
56+
}
57+
58+
if (dateFilter === "30d") {
59+
const thirtyDaysAgo = nowAtMidnight - 29 * 24 * 60 * 60 * 1000;
60+
return txAtMidnight >= thirtyDaysAgo && txAtMidnight <= nowAtMidnight;
61+
}
62+
63+
if (dateFilter === "custom") {
64+
if (!customStart || !customEnd) return true;
65+
const start = new Date(`${customStart}T00:00:00`).getTime();
66+
const end = new Date(`${customEnd}T23:59:59`).getTime();
67+
return txDate.getTime() >= start && txDate.getTime() <= end;
68+
}
69+
70+
return true;
71+
});
72+
}, [transactions, dateFilter, customStart, customEnd]);
73+
74+
const showEmptyFiltered = transactions.length > 0 && filteredTransactions.length === 0;
75+
3776
if (loading) {
3877
return (
3978
<Card className="p-4 md:p-6">
@@ -47,13 +86,40 @@ const TransactionHistory: React.FC<TransactionHistoryProps> = ({
4786

4887
return (
4988
<Card className="p-4 md:p-6">
50-
<h2 className="text-lg md:text-xl font-semibold mb-4">
51-
Transaction History
52-
</h2>
89+
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-3 mb-4">
90+
<h2 className="text-lg md:text-xl font-semibold">
91+
Transaction History
92+
</h2>
93+
<div className="flex flex-wrap items-center gap-2">
94+
<button onClick={() => setDateFilter("7d")} className={`px-3 py-1 text-xs rounded-md border ${dateFilter === "7d" ? "bg-zinc-700 border-zinc-600 text-white" : "border-zinc-700 text-zinc-300 hover:bg-zinc-800"}`}>Last 7 days</button>
95+
<button onClick={() => setDateFilter("30d")} className={`px-3 py-1 text-xs rounded-md border ${dateFilter === "30d" ? "bg-zinc-700 border-zinc-600 text-white" : "border-zinc-700 text-zinc-300 hover:bg-zinc-800"}`}>Last 30 days</button>
96+
<button onClick={() => setDateFilter("custom")} className={`px-3 py-1 text-xs rounded-md border ${dateFilter === "custom" ? "bg-zinc-700 border-zinc-600 text-white" : "border-zinc-700 text-zinc-300 hover:bg-zinc-800"}`}>Custom</button>
97+
<button onClick={() => setDateFilter("all")} className={`px-3 py-1 text-xs rounded-md border ${dateFilter === "all" ? "bg-zinc-700 border-zinc-600 text-white" : "border-zinc-700 text-zinc-300 hover:bg-zinc-800"}`}>All</button>
98+
</div>
99+
</div>
100+
101+
{dateFilter === "custom" && (
102+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 mb-4">
103+
<input
104+
type="date"
105+
value={customStart}
106+
onChange={(e) => setCustomStart(e.target.value)}
107+
className="w-full px-3 py-2 bg-zinc-800 border border-zinc-700 rounded-md text-white"
108+
aria-label="Custom start date"
109+
/>
110+
<input
111+
type="date"
112+
value={customEnd}
113+
onChange={(e) => setCustomEnd(e.target.value)}
114+
className="w-full px-3 py-2 bg-zinc-800 border border-zinc-700 rounded-md text-white"
115+
aria-label="Custom end date"
116+
/>
117+
</div>
118+
)}
53119

54-
{transactions.length === 0 ? (
120+
{filteredTransactions.length === 0 ? (
55121
<p className="text-sm text-gray-400 text-center py-8">
56-
No transactions found.
122+
{showEmptyFiltered ? "No transactions found for the selected date range." : "No transactions found."}
57123
</p>
58124
) : (
59125
<div className="overflow-x-auto">
@@ -75,7 +141,7 @@ const TransactionHistory: React.FC<TransactionHistoryProps> = ({
75141
</tr>
76142
</thead>
77143
<tbody>
78-
{transactions.map((transaction) => (
144+
{filteredTransactions.map((transaction) => (
79145
<tr
80146
key={transaction.id}
81147
className="border-b border-white/5 hover:bg-white/5 transition-colors"

package-lock.json

Lines changed: 0 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pages/NotificationsPage.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
22
import { Notification } from '../types';
33
import Card from '../components/common/Card';
44
import { motion, AnimatePresence } from 'framer-motion';
5+
import { BellOff, RefreshCw } from 'lucide-react';
56
import { useNotifications } from '../contexts/NotificationsContext';
67

78
const timeAgo = (dateString: string): string => {
@@ -110,8 +111,28 @@ const NotificationsPage: React.FC = () => {
110111
))}
111112
</AnimatePresence>
112113
{filteredNotifications.length === 0 && (
113-
<div className="p-6 text-center text-gray-400">
114-
{notifications.length === 0 ? "You're all caught up!" : "No notifications match your filters."}
114+
<div className="px-6 py-12 text-center">
115+
<div className="mx-auto mb-4 w-14 h-14 rounded-full bg-zinc-800 border border-zinc-700 flex items-center justify-center">
116+
<BellOff className="w-7 h-7 text-zinc-400" />
117+
</div>
118+
<h3 className="text-lg font-semibold text-zinc-200">
119+
{notifications.length === 0 ? "You're all caught up" : "No notifications found"}
120+
</h3>
121+
<p className="text-sm text-zinc-400 mt-2">
122+
{notifications.length === 0
123+
? "We'll let you know when there is a new update for your party crew."
124+
: "Try changing the status or type filters to see more results."}
125+
</p>
126+
<button
127+
onClick={() => {
128+
setStatusFilter('all');
129+
setTypeFilter('all');
130+
}}
131+
className="mt-5 inline-flex items-center gap-2 px-4 py-2 rounded-md bg-zinc-700 hover:bg-zinc-600 text-white text-sm font-medium transition-colors"
132+
>
133+
<RefreshCw className="w-4 h-4" />
134+
Reset Filters
135+
</button>
115136
</div>
116137
)}
117138
</div>

pages/PaymentPage.tsx

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useEffect, useState, useCallback } from "react";
22
import { useAuth } from "../hooks/useAuth";
3-
<<<<<<< HEAD
43
import { UserRole, Spot, Payment, PaymentStatus, Transaction } from "../types";
54
import Card from "../components/common/Card";
65
import Button from "../components/common/Button";
@@ -9,15 +8,6 @@ import { spotService, paymentService, invitationService, transactionService } fr
98
import { InvitationStatus } from "../types";
109
import { supabase } from "../services/supabase";
1110
import TransactionHistory from "../components/common/TransactionHistory";
12-
=======
13-
import { UserRole, Spot, Payment, PaymentStatus } from "../types";
14-
import Card from "../components/common/Card";
15-
import Button from "../components/common/Button";
16-
import { QRCodeCanvas } from "qrcode.react";
17-
import { spotService, paymentService, invitationService } from "../services/database";
18-
import { InvitationStatus } from "../types";
19-
import { supabase } from "../services/supabase";
20-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b
2111

2212
/* -------------------------------------------------------------------------- */
2313
/* Status Badge */
@@ -42,10 +32,7 @@ const PaymentPage: React.FC = () => {
4232
const { profile } = useAuth();
4333
const [spot, setSpot] = useState<Spot | null>(null);
4434
const [payments, setPayments] = useState<Payment[]>([]);
45-
<<<<<<< HEAD
4635
const [transactions, setTransactions] = useState<Transaction[]>([]);
47-
=======
48-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b
4936
const [loading, setLoading] = useState(true);
5037

5138
const fetchData = useCallback(async () => {
@@ -88,25 +75,17 @@ const PaymentPage: React.FC = () => {
8875
} else {
8976
setPayments([]);
9077
}
91-
<<<<<<< HEAD
92-
9378
// Fetch transaction history for current user
9479
if (profile?.id) {
9580
const transactionData = await transactionService.getUserTransactions(profile.id);
9681
setTransactions(transactionData);
9782
}
98-
=======
99-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b
10083
} catch (error) {
10184
console.error("Error loading payment data:", error);
10285
} finally {
10386
setLoading(false);
10487
}
105-
<<<<<<< HEAD
10688
}, [profile?.id]);
107-
=======
108-
}, []);
109-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b
11089

11190
useEffect(() => {
11291
fetchData();
@@ -159,7 +138,6 @@ const PaymentPage: React.FC = () => {
159138
if (!isAdmin) return;
160139
try {
161140
await paymentService.updatePaymentStatus(paymentId, PaymentStatus.PAID);
162-
<<<<<<< HEAD
163141

164142
// Create a transaction record when payment is marked as paid
165143
const payment = payments.find(p => p.id === paymentId);
@@ -172,9 +150,6 @@ const PaymentPage: React.FC = () => {
172150
status: PaymentStatus.PAID,
173151
});
174152
}
175-
176-
=======
177-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b
178153
await fetchData();
179154
} catch (error: any) {
180155
alert(`Failed to update payment: ${error.message || 'Please try again.'}`);
@@ -342,12 +317,8 @@ const PaymentPage: React.FC = () => {
342317
)}
343318
</Card>
344319
</div>
345-
<<<<<<< HEAD
346-
347320
{/* ---------------- TRANSACTION HISTORY ---------------- */}
348321
<TransactionHistory transactions={transactions} loading={loading} />
349-
=======
350-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b
351322
</div>
352323
);
353324
};

pages/ProfilePage.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,16 @@ const ProfileForm: React.FC<{ onSave: () => void }> = ({ onSave }) => {
178178
{errors.location && (
179179
<p className="text-red-400 text-xs -mt-4">{errors.location}</p>
180180
)}
181-
<Button type="submit" disabled={loading || checkingUsername} className="w-full py-4 font-black uppercase tracking-widest">Update Profile</Button>
181+
<Button type="submit" disabled={loading || checkingUsername} className="w-full py-4 font-black uppercase tracking-widest">
182+
{loading ? (
183+
<span className="inline-flex items-center justify-center gap-2">
184+
<span className="h-4 w-4 rounded-full border-2 border-white/40 border-t-white animate-spin" aria-hidden="true" />
185+
Saving...
186+
</span>
187+
) : (
188+
'Update Profile'
189+
)}
190+
</Button>
182191
</form>
183192
);
184193
};

services/database.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,7 +1613,6 @@ export const attendanceService = {
16131613
};
16141614
},
16151615
};
1616-
<<<<<<< HEAD
16171616

16181617
/* TRANSACTIONS */
16191618
/* -------------------------------------------------------------------------- */
@@ -1745,5 +1744,3 @@ export const transactionService = {
17451744
}
17461745
},
17471746
};
1748-
=======
1749-
>>>>>>> bedb01a0af53821680ce26a67bce5af226a10c8b

0 commit comments

Comments
 (0)