Source: frontend/src/context/AuthContext.jsx

/**
 * Модуль керування автентифікацією у frontend-застосунку.
 *
 * Цей файл відповідає за глобальний стан користувача, відновлення
 * сесії з localStorage, а також за надання компонентам доступу
 * до методів входу і виходу через React Context.
 *
 * Завдяки цьому логіка автентифікації не дублюється в окремих
 * сторінках і централізовано використовується в App.jsx,
 *`Login.jsx, Register.jsx та інших компонентах.
 */

import { createContext, useContext, useState, useEffect } from 'react'

/**
 * Контекст автентифікації застосунку.
 *
 * Зберігає поточного користувача, стан завантаження та методи входу і виходу.
 */
const AuthContext = createContext(null)

/**
 * Провайдер автентифікації, який керує станом користувача в застосунку.
 *
 * Під час ініціалізації відновлює користувача з localStorage, якщо збережено
 * токен і серіалізовані дані користувача. Надає дочірнім компонентам доступ
 * до user, loading, login і logout через AuthContext.
 * @param {object} props Властивості компонента.
 * @param {object} props.children Дочірній елемент, який буде відображено всередині провайдера.
 * @returns {object} JSX-елемент провайдера автентифікації.
 */
export function AuthProvider({ children }) {
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    const token = localStorage.getItem('token')
    const savedUser = localStorage.getItem('user')

    if(token && savedUser) {
      try {
        // eslint-disable-next-line react-hooks/set-state-in-effect
        setUser(JSON.parse(savedUser))
      } catch {
        localStorage.removeItem('token')
        localStorage.removeItem('user')
      }
    }
    setLoading(false)
  }, [])

  /**
   * Зберігає токен і дані користувача та оновлює стан автентифікації.
   * @param {object} userData Дані авторизованого користувача.
   * @param {string} token JWT-токен доступу.
   * @returns {void}
   */
  const login = (userData, token) => {
    localStorage.setItem('token', token)
    localStorage.setItem('user', JSON.stringify(userData))
    setUser(userData)
  }

  /**
   * Очищає дані автентифікації з localStorage і скидає поточного користувача.
   * @returns {void}
   */
  const logout = () => {
    localStorage.removeItem('token')
    localStorage.removeItem('user')
    setUser(null)
  }

  return (
    <AuthContext.Provider value={{ user, loading, login, logout }}>
      {children}
    </AuthContext.Provider>
  )
}

/**
 * Повертає значення контексту автентифікації.
 *
 * Використовується компонентами для доступу до поточного користувача,
 * стану завантаження та методів login/logout.
 * @returns {object} Об'єкт контексту автентифікації з user, loading, login і logout.
 */
// eslint-disable-next-line react-refresh/only-export-components
export function useAuth() {
  return useContext(AuthContext)
}