235 lines
6.9 KiB
JavaScript
235 lines
6.9 KiB
JavaScript
import { createContext, useContext, useState, useEffect } from 'react'
|
||
import { auth, signInWithEmailAndPassword, signOut as firebaseSignOut, onAuthStateChanged } from '../firebase'
|
||
import { db, collection, getDocs, doc, setDoc, updateDoc } from 'firebase/firestore'
|
||
|
||
const StorageContext = createContext(null)
|
||
|
||
const CITIES = [
|
||
'Алматы', 'Астана', 'Шымкент', 'Караганда', 'Актобе', 'Тараз', 'Павлодар',
|
||
'Усть-Каменогорск', 'Семей', 'Атырау', 'Орал', 'Кызылорда', 'Костанай',
|
||
'Петропавловск', 'Актау', 'Темиртау', 'Другой'
|
||
]
|
||
|
||
const DEFAULT_DATA = {
|
||
program: {
|
||
title: 'Адаптационная программа стажёров',
|
||
description: 'Программа профессиональной адаптации для новых сотрудников',
|
||
startDate: '',
|
||
endDate: '',
|
||
collectionOpen: false,
|
||
groupsFormed: false,
|
||
examEnabled: false,
|
||
numberOfGroups: 2
|
||
},
|
||
trainers: [
|
||
{ id: 1, name: 'Тренер 1', login: 'trainer1', password: 'pass1' },
|
||
{ id: 2, name: 'Тренер 2', login: 'trainer2', password: 'pass2' }
|
||
],
|
||
programRules: 'Правила программы:\n1. Посещаемость обязательна\n2. Домашние задания сдавать вовремя\n3. Активно участвовать в обсуждениях',
|
||
examRules: 'Правила экзамена:\n1. 10 вопросов\n2. Порог сдачи: 9 правильных ответов (90%)\n3. Время выполнения: 60 минут',
|
||
sessions: [],
|
||
trainees: []
|
||
}
|
||
|
||
export function StorageProvider({ children }) {
|
||
const [user, setUser] = useState(null)
|
||
const [data, setData] = useState(DEFAULT_DATA)
|
||
const [loading, setLoading] = useState(true)
|
||
|
||
useEffect(() => {
|
||
const unsubscribe = onAuthStateChanged(auth, (user) => {
|
||
setUser(user)
|
||
setLoading(false)
|
||
})
|
||
return unsubscribe
|
||
}, [])
|
||
|
||
useEffect(() => {
|
||
loadData()
|
||
}, [])
|
||
|
||
const loadData = async () => {
|
||
try {
|
||
const stored = localStorage.getItem('internAdaptationData')
|
||
if (stored) {
|
||
setData(JSON.parse(stored))
|
||
}
|
||
} catch (error) {
|
||
console.error('Error loading data:', error)
|
||
}
|
||
}
|
||
|
||
const saveData = (newData) => {
|
||
setData(newData)
|
||
localStorage.setItem('internAdaptationData', JSON.stringify(newData))
|
||
}
|
||
|
||
const updateProgram = (updates) => {
|
||
const newData = { ...data, program: { ...data.program, ...updates } }
|
||
saveData(newData)
|
||
}
|
||
|
||
const updateTrainers = (trainers) => {
|
||
const newData = { ...data, trainers }
|
||
saveData(newData)
|
||
}
|
||
|
||
const updateProgramRules = (rules) => {
|
||
const newData = { ...data, programRules: rules }
|
||
saveData(newData)
|
||
}
|
||
|
||
const updateExamRules = (rules) => {
|
||
const newData = { ...data, examRules: rules }
|
||
saveData(newData)
|
||
}
|
||
|
||
const addSession = (session) => {
|
||
const newSessions = [...data.sessions, { ...session, id: Date.now() }]
|
||
const newData = { ...data, sessions: newSessions }
|
||
saveData(newData)
|
||
}
|
||
|
||
const removeSession = (sessionId) => {
|
||
const newSessions = data.sessions.filter(s => s.id !== sessionId)
|
||
const newData = { ...data, sessions: newSessions }
|
||
saveData(newData)
|
||
}
|
||
|
||
const addTrainee = (trainee) => {
|
||
const newTrainees = [...data.trainees, { ...trainee, id: Date.now(), groupId: null, attendance: {}, homeworkStatus: {}, examScore: null }]
|
||
const newData = { ...data, trainees: newTrainees }
|
||
saveData(newData)
|
||
}
|
||
|
||
const updateTrainee = (id, updates) => {
|
||
const newTrainees = data.trainees.map(t => t.id === id ? { ...t, ...updates } : t)
|
||
const newData = { ...data, trainees: newTrainees }
|
||
saveData(newData)
|
||
}
|
||
|
||
const deleteTrainee = (id) => {
|
||
const newTrainees = data.trainees.filter(t => t.id !== id)
|
||
const newData = { ...data, trainees: newTrainees }
|
||
saveData(newData)
|
||
}
|
||
|
||
const formGroups = () => {
|
||
const { numberOfGroups } = data.program
|
||
const trainees = [...data.trainees]
|
||
|
||
// Группировка по подразделениям и городам
|
||
const groups = Array.from({ length: numberOfGroups }, () => [])
|
||
|
||
// Сортировка для равномерного распределения
|
||
trainees.sort((a, b) => {
|
||
if (a.division !== b.division) return a.division.localeCompare(b.division)
|
||
return a.city.localeCompare(b.city)
|
||
})
|
||
|
||
// Распределение по группам
|
||
trainees.forEach((trainee, index) => {
|
||
groups[index % numberOfGroups].push(trainee.id)
|
||
})
|
||
|
||
// Обновление trainees с groupId
|
||
const updatedTrainees = data.trainees.map(t => {
|
||
const groupIndex = groups.findIndex(g => g.includes(t.id))
|
||
return { ...t, groupId: groupIndex >= 0 ? groupIndex + 1 : null }
|
||
})
|
||
|
||
const newData = {
|
||
...data,
|
||
trainees: updatedTrainees,
|
||
program: { ...data.program, groupsFormed: true, collectionOpen: false }
|
||
}
|
||
saveData(newData)
|
||
}
|
||
|
||
const resetGroups = () => {
|
||
const updatedTrainees = data.trainees.map(t => ({
|
||
...t,
|
||
groupId: null,
|
||
attendance: {},
|
||
homeworkStatus: {},
|
||
examScore: null
|
||
}))
|
||
const newData = {
|
||
...data,
|
||
trainees: updatedTrainees,
|
||
program: { ...data.program, groupsFormed: false, examEnabled: false }
|
||
}
|
||
saveData(newData)
|
||
}
|
||
|
||
const login = async (login, password) => {
|
||
const trainer = data.trainers.find(t => t.login === login && t.password === password)
|
||
if (!trainer) {
|
||
throw new Error('Неверный логин или пароль')
|
||
}
|
||
// Используем демо-режим с localStorage
|
||
localStorage.setItem('demoUser', JSON.stringify(trainer))
|
||
window.dispatchEvent(new Event('storage'))
|
||
}
|
||
|
||
const logout = () => {
|
||
localStorage.removeItem('demoUser')
|
||
window.dispatchEvent(new Event('storage'))
|
||
}
|
||
|
||
const value = {
|
||
user,
|
||
data,
|
||
loading,
|
||
CITIES,
|
||
updateProgram,
|
||
updateTrainers,
|
||
updateProgramRules,
|
||
updateExamRules,
|
||
addSession,
|
||
removeSession,
|
||
addTrainee,
|
||
updateTrainee,
|
||
deleteTrainee,
|
||
formGroups,
|
||
resetGroups,
|
||
login,
|
||
logout
|
||
}
|
||
|
||
return (
|
||
<StorageContext.Provider value={value}>
|
||
{children}
|
||
</StorageContext.Provider>
|
||
)
|
||
}
|
||
|
||
export function useStorage() {
|
||
const context = useContext(StorageContext)
|
||
if (!context) {
|
||
throw new Error('useStorage must be used within StorageProvider')
|
||
}
|
||
return context
|
||
}
|
||
|
||
export function useAuth() {
|
||
const [demoUser, setDemoUser] = useState(null)
|
||
|
||
useEffect(() => {
|
||
const user = localStorage.getItem('demoUser')
|
||
if (user) {
|
||
setDemoUser(JSON.parse(user))
|
||
}
|
||
|
||
const handler = () => {
|
||
const user = localStorage.getItem('demoUser')
|
||
setDemoUser(user ? JSON.parse(user) : null)
|
||
}
|
||
|
||
window.addEventListener('storage', handler)
|
||
return () => window.removeEventListener('storage', handler)
|
||
}, [])
|
||
|
||
return { user: demoUser, loading: false }
|
||
}
|