Calgary Community of Christ
  • Welcome
  • About
    • Give
    • History
    • What to Expect
  • Calendar
  • Contact
    • Get Involved
import React, { useState, useEffect } from 'react'; import { Calendar, User, CheckCircle2, Utensils, Plus, X, ChevronRight, Info, Loader2 } from 'lucide-react'; import { initializeApp } from 'firebase/app'; import { getAuth, signInWithCustomToken, signInAnonymously, onAuthStateChanged } from 'firebase/auth'; import { getFirestore, doc, setDoc, onSnapshot } from 'firebase/firestore'; const initialEvents = [ { id: 'may', date: 'May 3rd', theme: 'Taco Bar', details: { main: 'Ground beef in crockpot', sides: '12 hard shells, 12 flour tortillas, shredded cheese, lettuce, tomatoes, red onion, salsa, tortilla chips', dessert: 'Frozen ice cream bars' }, slots: [ { id: 'may-1', category: 'Main: Ground Beef', needed: true, volunteer: '', details: '' }, { id: 'may-2', category: 'Shells: 12 Hard & 12 Flour', needed: true, volunteer: '', details: '' }, { id: 'may-3', category: 'Toppings: Cheese & Lettuce', needed: true, volunteer: '', details: '' }, { id: 'may-4', category: 'Toppings: Tomatoes, Onion, Salsa', needed: true, volunteer: '', details: '' }, { id: 'may-5', category: 'Sides: Tortilla Chips', needed: true, volunteer: '', details: '' }, { id: 'may-6', category: 'Dessert: Frozen Ice Cream Bars', needed: true, volunteer: '', details: '' }, { id: 'may-7', category: 'Drinks & Paper Goods', needed: true, volunteer: '', details: '' }, ] }, { id: 'june', date: 'June 7th', theme: 'Build-a-Sandwich', details: { main: 'Build-a-Sandwich', sides: 'Tuna salad, ham, cheese, mayo, mustard, lettuce, tomatoes, 6 white buns, 12 wheat buns', dessert: 'Sundae Bar: Vanilla ice cream, chocolate/caramel sauce, strawberries, bananas, sprinkles' }, slots: [ { id: 'june-1', category: 'Protein: Tuna Salad & Ham', needed: true, volunteer: '', details: '' }, { id: 'june-2', category: 'Cheese, Mayo & Mustard', needed: true, volunteer: '', details: '' }, { id: 'june-3', category: 'Veggies: Lettuce & Tomatoes', needed: true, volunteer: '', details: '' }, { id: 'june-4', category: 'Buns: 6 White, 12 Wheat', needed: true, volunteer: '', details: '' }, { id: 'june-5', category: 'Sundae Bar: Ice Cream', needed: true, volunteer: '', details: '' }, { id: 'june-6', category: 'Sundae Bar: Toppings & Sauces', needed: true, volunteer: '', details: '' }, ] }, { id: 'july', date: 'July 5th', theme: 'Summer BBQ Style', details: { main: 'Summer BBQ Style', sides: 'Potato salad, pasta salad, baked beans, 18 quality hot dogs, buns, relish, mustard, onions, pickles, chips', dessert: 'Watermelon' }, slots: [ { id: 'july-1', category: 'Main: 18 Hot Dogs & Buns', needed: true, volunteer: '', details: '' }, { id: 'july-2', category: 'Side: Potato Salad', needed: true, volunteer: '', details: '' }, { id: 'july-3', category: 'Side: Pasta Salad', needed: true, volunteer: '', details: '' }, { id: 'july-4', category: 'Side: Baked Beans', needed: true, volunteer: '', details: '' }, { id: 'july-5', category: 'Toppings: Relish, Mustard, Onions, Pickles', needed: true, volunteer: '', details: '' }, { id: 'july-6', category: 'Side: Chips', needed: true, volunteer: '', details: '' }, { id: 'july-7', category: 'Dessert: Watermelon', needed: true, volunteer: '', details: '' }, ] }, { id: 'aug', date: 'August 2nd', theme: 'NO POTLUCK', details: { main: 'Long Weekend Break', sides: 'N/A', dessert: 'N/A' }, slots: [] }, { id: 'sept', date: 'September 6th', theme: 'Traditional Potluck', details: { main: 'Bring whatever you want!', sides: 'General Categories', dessert: 'General Categories' }, slots: [ { id: 'sept-1', category: 'Main Dish (Protein)', needed: true, volunteer: '', details: '' }, { id: 'sept-2', category: 'Main Dish (Vegetarian)', needed: true, volunteer: '', details: '' }, { id: 'sept-3', category: 'Salad / Greens', needed: true, volunteer: '', details: '' }, { id: 'sept-4', category: 'Side Dish / Carbs', needed: true, volunteer: '', details: '' }, { id: 'sept-5', category: 'Appetizer / Snacks', needed: true, volunteer: '', details: '' }, { id: 'sept-6', category: 'Dessert', needed: true, volunteer: '', details: '' }, { id: 'sept-7', category: 'Drinks', needed: true, volunteer: '', details: '' }, ] }, { id: 'oct', date: 'October 4th', theme: 'Pizza', details: { main: 'Pizza', sides: 'Small veggie platter, small fruit platter', dessert: 'Ice cream with chocolate or caramel sauce (leftover from June)' }, slots: [ { id: 'oct-1', category: 'Main: Pizza 1', needed: true, volunteer: '', details: '' }, { id: 'oct-2', category: 'Main: Pizza 2', needed: true, volunteer: '', details: '' }, { id: 'oct-3', category: 'Main: Pizza 3', needed: true, volunteer: '', details: '' }, { id: 'oct-4', category: 'Side: Small Veggie Platter', needed: true, volunteer: '', details: '' }, { id: 'oct-5', category: 'Side: Small Fruit Platter', needed: true, volunteer: '', details: '' }, { id: 'oct-6', category: 'Dessert: Ice Cream (From June)', needed: true, volunteer: 'Church Kitchen', details: 'Using leftovers' }, ] }, { id: 'nov', date: 'November 1st', theme: 'Chili', details: { main: 'Chili', sides: 'Assorted rolls, shredded cheddar', dessert: 'Apple-themed dessert (crisp, pie, or cake) with ice cream' }, slots: [ { id: 'nov-1', category: 'Main: Chili (Pot 1)', needed: true, volunteer: '', details: '' }, { id: 'nov-2', category: 'Main: Chili (Pot 2)', needed: true, volunteer: '', details: '' }, { id: 'nov-3', category: 'Side: Assorted Rolls', needed: true, volunteer: '', details: '' }, { id: 'nov-4', category: 'Topping: Shredded Cheddar', needed: true, volunteer: '', details: '' }, { id: 'nov-5', category: 'Dessert: Apple Dessert', needed: true, volunteer: '', details: '' }, { id: 'nov-6', category: 'Dessert: Ice Cream', needed: true, volunteer: '', details: '' }, ] }, { id: 'dec', date: 'December 6th', theme: 'Casseroles & Lasagna', details: { main: 'Casseroles & Lasagna', sides: 'Tossed or Caesar salad, garlic bread', dessert: 'Christmas-themed dessert' }, slots: [ { id: 'dec-1', category: 'Main: Casserole', needed: true, volunteer: '', details: '' }, { id: 'dec-2', category: 'Main: Lasagna', needed: true, volunteer: '', details: '' }, { id: 'dec-3', category: 'Side: Tossed or Caesar Salad', needed: true, volunteer: '', details: '' }, { id: 'dec-4', category: 'Side: Garlic Bread', needed: true, volunteer: '', details: '' }, { id: 'dec-5', category: 'Dessert: Christmas Themed', needed: true, volunteer: '', details: '' }, ] } ]; const firebaseConfig = typeof __firebase_config !== 'undefined' ? JSON.parse(__firebase_config) : {}; const app = initializeApp(firebaseConfig); const auth = getAuth(app); const db = getFirestore(app); const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id'; export default function App() { const [events, setEvents] = useState(initialEvents); const [activeModal, setActiveModal] = useState(null); // { eventId, slotId } const [formData, setFormData] = useState({ name: '', details: '' }); const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); useEffect(() => { const initAuth = async () => { try { if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) { await signInWithCustomToken(auth, __initial_auth_token); } else { await signInAnonymously(auth); } } catch (err) { console.error('Auth error:', err); setError('Failed to authenticate.'); setLoading(false); } }; initAuth(); const unsubscribe = onAuthStateChanged(auth, setUser); return () => unsubscribe(); }, []); useEffect(() => { if (!user) return; const eventsDocRef = doc(db, 'artifacts', appId, 'public', 'data', 'potlucks', 'schedule'); const unsubscribe = onSnapshot( eventsDocRef, (docSnap) => { if (docSnap.exists()) { setEvents(docSnap.data().events); } else { // Initialize document if it doesn't exist yet setDoc(eventsDocRef, { events: initialEvents }).catch(console.error); } setLoading(false); }, (err) => { console.error('Firestore error:', err); setError('Failed to load data. Please refresh.'); setLoading(false); } ); return () => unsubscribe(); }, [user]); const handleOpenModal = (eventId, slotId) => { setActiveModal({ eventId, slotId }); setFormData({ name: '', details: '' }); setError(null); }; const handleCloseModal = () => { setActiveModal(null); setError(null); }; const handleSubmit = async (e) => { e.preventDefault(); if (!formData.name.trim() || !user) return; setSaving(true); setError(null); const updatedEvents = events.map(event => { if (event.id === activeModal.eventId) { return { ...event, slots: event.slots.map(slot => { if (slot.id === activeModal.slotId) { return { ...slot, needed: false, volunteer: formData.name, details: formData.details }; } return slot; }) }; } return event; }); try { const eventsDocRef = doc(db, 'artifacts', appId, 'public', 'data', 'potlucks', 'schedule'); await setDoc(eventsDocRef, { events: updatedEvents }, { merge: true }); handleCloseModal(); } catch (err) { console.error("Save error:", err); setError("Failed to save your sign-up. Please try again."); } finally { setSaving(false); } }; const getSlotToEdit = () => { if (!activeModal) return null; const event = events.find(e => e.id === activeModal.eventId); return event.slots.find(s => s.id === activeModal.slotId); }; return (
{/* Header */}

Church Potluck Sign-Up

Pick a date, claim an item, and let us know what you're bringing!

{error && !activeModal && (
{error}
)}
{/* Main Content */}
{loading ? (

Loading potluck schedule...

) : (
{events.map((event) => (
{/* Event Header */}
{event.date}

{event.theme}

{event.id !== 'aug' && (

Main: {event.details.main}

Sides: {event.details.sides}

Dessert: {event.details.dessert}

)}
{/* Event Slots */} {event.slots.length > 0 ? (
{event.slots.map((slot) => (

{slot.category}

{!slot.needed && slot.details && (

Bringing: {slot.details}

)}
{slot.needed ? ( ) : (
Claimed by {slot.volunteer}
)}
))}
) : (
Enjoy your long weekend! No potluck this month.
)}
))}
{/* Sign Up Modal */} {activeModal && (

Claim Item

You are claiming: {getSlotToEdit()?.category}
{error && (
{error}
)}
setFormData({...formData, name: e.target.value})} />
setFormData({...formData, details: e.target.value})} />

Helpful if you have a specific twist or if there are allergies to note.

)}
); }
Home
About
Contact

Canada West Mission Centre
World Church
Picture
© 2017-2024 Calgary Community of Christ
Special thanks to Wayne Rowe for his beautiful photography.
  • Welcome
  • About
    • Give
    • History
    • What to Expect
  • Calendar
  • Contact
    • Get Involved