AppContext.jsx 5.41 KB
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';

const AppContext = createContext();

export const AppProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState(null);
  const [activities, setActivities] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [registrations, setRegistrations] = useState([]);
  const [userMessages, setUserMessages] = useState([]);

  // Initialize app data
  useEffect(() => {
    const fetchInitialData = async () => {
      try {
        setLoading(true);
        
        // Fetch users data - In a real app, this would be a real API call
        const usersResponse = await fetch('/data/users.json');
        const usersData = await usersResponse.json();
        
        // For demo purposes, set the first user as current user
        setCurrentUser(usersData[0]);
        
        // Fetch activities
        const activitiesResponse = await fetch('/data/activities.json');
        const activitiesData = await activitiesResponse.json();
        setActivities(activitiesData);

        // Fetch registrations
        const registrationsResponse = await fetch('/data/registrations.json');
        const registrationsData = await registrationsResponse.json();
        setRegistrations(registrationsData);

        // Fetch messages
        const messagesResponse = await fetch('/data/messages.json');
        const messagesData = await messagesResponse.json();
        setUserMessages(messagesData);

        setLoading(false);
      } catch (err) {
        console.error('Failed to fetch initial data:', err);
        setError('Failed to load application data. Please try again later.');
        setLoading(false);
      }
    };

    fetchInitialData();
  }, []);

  // Get activity by ID
  const getActivityById = useCallback((activityId) => {
    return activities.find(activity => activity.id === activityId) || null;
  }, [activities]);

  // Get user's registrations
  const getUserRegistrations = useCallback(() => {
    if (!currentUser) return [];
    return registrations.filter(reg => reg.user_id === currentUser.id);
  }, [currentUser, registrations]);

  // Register for an activity
  const registerForActivity = useCallback((activityId, formData) => {
    if (!currentUser) return { success: false, error: 'User not logged in' };
    
    // In a real app, this would make an API call
    const newRegistration = {
      id: `R${Math.floor(Math.random() * 10000).toString().padStart(4, '0')}`,
      activity_id: activityId,
      user_id: currentUser.id,
      registration_time: new Date().toISOString().replace('T', ' ').substring(0, 19),
      status: 'pending',
      custom_fields: formData.fields,
      custom_answers: formData.answers
    };
    
    setRegistrations(prev => [...prev, newRegistration]);
    return { success: true, registrationId: newRegistration.id };
  }, [currentUser]);

  // Create a new activity
  const createActivity = useCallback((activityData) => {
    if (!currentUser) return { success: false, error: 'User not logged in' };
    
    // In a real app, this would make an API call
    const newActivity = {
      id: `A${Math.floor(Math.random() * 10000).toString().padStart(4, '0')}`,
      organizer_id: currentUser.id,
      organizer_name: currentUser.name,
      ...activityData,
      participant_count: 0,
      is_published: activityData.is_published || true,
      is_public: activityData.is_public || true,
    };
    
    setActivities(prev => [...prev, newActivity]);
    return { success: true, activityId: newActivity.id };
  }, [currentUser]);

  // Check in for an activity
  const checkInForActivity = useCallback((activityId, registrationId, method = 'manual') => {
    if (!currentUser) return { success: false, error: 'User not logged in' };
    
    // In a real app, this would make an API call
    const checkinData = {
      id: `C${Math.floor(Math.random() * 10000).toString().padStart(4, '0')}`,
      activity_id: activityId,
      user_id: currentUser.id,
      registration_id: registrationId,
      checkin_time: new Date().toISOString().replace('T', ' ').substring(0, 19),
      checkin_type: method,
      status: 'successful',
      is_late: false
    };
    
    // In a real app, we would update the backend
    return { success: true, checkin: checkinData };
  }, [currentUser]);

  // Get user messages
  const getUserMessages = useCallback(() => {
    if (!currentUser) return [];
    return userMessages.filter(msg => msg.recipient_id === currentUser.id);
  }, [currentUser, userMessages]);

  // Toggle read status of a message
  const toggleMessageReadStatus = useCallback((messageId) => {
    setUserMessages(prev => 
      prev.map(msg => 
        msg.id === messageId 
          ? { ...msg, read_status: !msg.read_status } 
          : msg
      )
    );
  }, []);

  const contextValue = {
    currentUser,
    activities,
    loading,
    error,
    registrations,
    userMessages,
    getActivityById,
    getUserRegistrations,
    registerForActivity,
    createActivity,
    checkInForActivity,
    getUserMessages,
    toggleMessageReadStatus
  };

  return (
    <AppContext.Provider value={contextValue}>
      {children}
    </AppContext.Provider>
  );
};

export const useApp = () => {
  const context = useContext(AppContext);
  if (!context) {
    throw new Error('useApp must be used within an AppProvider');
  }
  return context;
};

export default AppContext;