123 lines
3.1 KiB
JavaScript
123 lines
3.1 KiB
JavaScript
import {
|
|
collection,
|
|
query,
|
|
orderBy,
|
|
onSnapshot,
|
|
addDoc,
|
|
getDocs,
|
|
doc,
|
|
updateDoc,
|
|
deleteDoc,
|
|
writeBatch,
|
|
serverTimestamp,
|
|
Timestamp,
|
|
} from 'firebase/firestore';
|
|
import { db } from './firebase.js';
|
|
|
|
const donorsRef = collection(db, 'donors');
|
|
let unsubscribe = null;
|
|
|
|
export function subscribeToDonors(callback) {
|
|
const q = query(donorsRef, orderBy('date', 'desc'));
|
|
unsubscribe = onSnapshot(
|
|
q,
|
|
(snapshot) => {
|
|
const donors = [];
|
|
snapshot.forEach((doc) => {
|
|
donors.push({ id: doc.id, ...doc.data() });
|
|
});
|
|
callback(donors);
|
|
},
|
|
(error) => {
|
|
console.error('Error fetching donors:', error);
|
|
callback([]);
|
|
}
|
|
);
|
|
return unsubscribe;
|
|
}
|
|
|
|
export async function addDonor({ name, amount, classYear, message, anonymous }) {
|
|
return addDoc(donorsRef, {
|
|
name: anonymous ? 'Anonymous' : name,
|
|
amount: Number(amount),
|
|
classYear: classYear || '',
|
|
message: message || '',
|
|
anonymous: !!anonymous,
|
|
date: serverTimestamp(),
|
|
});
|
|
}
|
|
|
|
export function calculateTotal(donors) {
|
|
return donors.reduce((sum, d) => sum + (d.amount || 0), 0);
|
|
}
|
|
|
|
// ===== Admin Operations =====
|
|
|
|
export async function getDonors() {
|
|
const q = query(donorsRef, orderBy('date', 'desc'));
|
|
const snapshot = await getDocs(q);
|
|
const donors = [];
|
|
snapshot.forEach((d) => donors.push({ id: d.id, ...d.data() }));
|
|
return donors;
|
|
}
|
|
|
|
export async function addDonorWithDate({ name, amount, classYear, message, anonymous, date }) {
|
|
const dateValue = date ? Timestamp.fromDate(new Date(date)) : serverTimestamp();
|
|
return addDoc(donorsRef, {
|
|
name: anonymous ? 'Anonymous' : name,
|
|
amount: Number(amount),
|
|
classYear: classYear || '',
|
|
message: message || '',
|
|
anonymous: !!anonymous,
|
|
date: dateValue,
|
|
});
|
|
}
|
|
|
|
export async function updateDonor(id, fields) {
|
|
return updateDoc(doc(db, 'donors', id), fields);
|
|
}
|
|
|
|
export async function deleteDonor(id) {
|
|
return deleteDoc(doc(db, 'donors', id));
|
|
}
|
|
|
|
export async function addDonorsBatch(donorsArray) {
|
|
const chunks = [];
|
|
for (let i = 0; i < donorsArray.length; i += 500) {
|
|
chunks.push(donorsArray.slice(i, i + 500));
|
|
}
|
|
let imported = 0;
|
|
for (const chunk of chunks) {
|
|
const batch = writeBatch(db);
|
|
for (const d of chunk) {
|
|
const ref = doc(collection(db, 'donors'));
|
|
const dateValue = d.date ? Timestamp.fromDate(new Date(d.date)) : serverTimestamp();
|
|
batch.set(ref, {
|
|
name: d.anonymous ? 'Anonymous' : (d.name || 'Anonymous'),
|
|
amount: Number(d.amount) || 0,
|
|
classYear: d.classYear || '',
|
|
message: d.message || '',
|
|
anonymous: !!d.anonymous,
|
|
date: dateValue,
|
|
});
|
|
}
|
|
await batch.commit();
|
|
imported += chunk.length;
|
|
}
|
|
return imported;
|
|
}
|
|
|
|
export function sortDonors(donors, sortBy) {
|
|
const sorted = [...donors];
|
|
if (sortBy === 'amount') {
|
|
sorted.sort((a, b) => (b.amount || 0) - (a.amount || 0));
|
|
} else {
|
|
sorted.sort((a, b) => {
|
|
const dateA = a.date?.toMillis?.() || 0;
|
|
const dateB = b.date?.toMillis?.() || 0;
|
|
return dateB - dateA;
|
|
});
|
|
}
|
|
return sorted;
|
|
}
|