From 69a5e4ade1c576584c2f062f25149c7447c223ab Mon Sep 17 00:00:00 2001 From: DmitriyA Date: Tue, 10 Jun 2025 09:29:14 -0400 Subject: [PATCH] sidebar menu improvement --- src/Components/Layout/SidebarMenuWrapper.jsx | 76 +++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/src/Components/Layout/SidebarMenuWrapper.jsx b/src/Components/Layout/SidebarMenuWrapper.jsx index 22255f9..2980c64 100644 --- a/src/Components/Layout/SidebarMenuWrapper.jsx +++ b/src/Components/Layout/SidebarMenuWrapper.jsx @@ -5,16 +5,54 @@ import axios from 'axios'; const SidebarMenuWrapper = ({ isDarkMode, setIsDarkMode, onMenuSelect }) => { const [menuData, setMenuData] = useState(null); + const [lastModified, setLastModified] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [editingItem, setEditingItem] = useState(null); const [editModalOpen, setEditModalOpen] = useState(false); + const [backgroundLoading, setBackgroundLoading] = useState(false); + // Загружаем меню из localStorage при инициализации + useEffect(() => { + const loadCachedMenu = () => { + try { + const cached = localStorage.getItem('menuCache'); + if (cached) { + const { data, timestamp } = JSON.parse(cached); + setMenuData(data); + setLastModified(timestamp); + } + } catch (e) { + console.warn('Failed to load menu from cache', e); + } + }; + + loadCachedMenu(); + }, []); + + // Основная загрузка меню useEffect(() => { const fetchMenuData = async () => { try { - const response = await axios.get(`${import.meta.env.VITE_BACK_URL}/api/menu/full`); - setMenuData(response.data); // axios хранит данные в response.data + setLoading(true); + const headers = lastModified ? { 'If-Modified-Since': lastModified } : {}; + + const response = await axios.get(`${import.meta.env.VITE_BACK_URL}/api/menu/full`, { + headers, + validateStatus: status => status === 200 || status === 304 + }); + + if (response.status === 200) { + const newLastModified = response.headers['last-modified']; + setMenuData(response.data); + setLastModified(newLastModified); + + // Сохраняем в кэш + localStorage.setItem('menuCache', JSON.stringify({ + data: response.data, + timestamp: newLastModified + })); + } } catch (err) { console.error('Error fetching menu data:', err); setError(err.message || 'Failed to fetch menu data'); @@ -26,6 +64,40 @@ const SidebarMenuWrapper = ({ isDarkMode, setIsDarkMode, onMenuSelect }) => { fetchMenuData(); }, []); + // Фоновая проверка обновлений + useEffect(() => { + if (!lastModified) return; + + const checkForUpdates = async () => { + try { + setBackgroundLoading(true); + const response = await axios.get(`${import.meta.env.VITE_BACK_URL}/api/menu/check-updates`, { + headers: { 'If-Modified-Since': lastModified } + }); + + if (response.data.hasUpdates) { + // Если есть обновления, загружаем их в фоне + const updateResponse = await axios.get(`${import.meta.env.VITE_BACK_URL}/api/menu/full`); + setMenuData(updateResponse.data); + setLastModified(updateResponse.headers['last-modified']); + + localStorage.setItem('menuCache', JSON.stringify({ + data: updateResponse.data, + timestamp: updateResponse.headers['last-modified'] + })); + } + } catch (err) { + console.warn('Background update check failed', err); + } finally { + setBackgroundLoading(false); + } + }; + + // Проверяем обновления каждые 5 минут + const interval = setInterval(checkForUpdates, 5 * 60 * 1000); + return () => clearInterval(interval); + }, [lastModified]); + const handleSaveChanges = async (updatedItem) => { try { const response = await axios.put(