fix: navigation under weeks switch

This commit is contained in:
kilyabin
2025-11-26 00:10:55 +04:00
parent 2cd392595f
commit 423178aefb
8 changed files with 123 additions and 35 deletions

3
settings.json Normal file
View File

@@ -0,0 +1,3 @@
{
"weekNavigationEnabled": false
}

View File

@@ -113,7 +113,10 @@ export default function AdminPage({ groups: initialGroups, settings: initialSett
} }
const handleUpdateSettings = async (newSettings: AppSettings) => { const handleUpdateSettings = async (newSettings: AppSettings) => {
setLoading(true) // Сохраняем предыдущее состояние для отката при ошибке
const previousSettings = settings
// Оптимистичное обновление UI
setSettings(newSettings)
setError(null) setError(null)
try { try {
@@ -126,14 +129,17 @@ export default function AdminPage({ groups: initialGroups, settings: initialSett
const data = await res.json() const data = await res.json()
if (res.ok && data.success) { if (res.ok && data.success) {
// Обновляем состояние из ответа сервера (для синхронизации)
setSettings(data.settings) setSettings(data.settings)
} else { } else {
// Откатываем изменения при ошибке
setSettings(previousSettings)
setError(data.error || 'Ошибка при обновлении настроек') setError(data.error || 'Ошибка при обновлении настроек')
} }
} catch (err) { } catch (err) {
// Откатываем изменения при ошибке
setSettings(previousSettings)
setError('Ошибка соединения с сервером') setError('Ошибка соединения с сервером')
} finally {
setLoading(false)
} }
} }

View File

@@ -20,3 +20,4 @@ export default function handler(

View File

@@ -32,3 +32,4 @@ export default function handler(

View File

@@ -20,3 +20,4 @@ export default function handler(

View File

@@ -34,7 +34,11 @@ async function handler(
try { try {
saveSettings(settings) saveSettings(settings)
res.status(200).json({ success: true, settings }) // Сбрасываем кеш и загружаем свежие настройки для подтверждения
const { clearSettingsCache } = await import('@/shared/data/settings-loader')
clearSettingsCache()
const savedSettings = loadSettings()
res.status(200).json({ success: true, settings: savedSettings })
} catch (error) { } catch (error) {
console.error('Error saving settings:', error) console.error('Error saving settings:', error)
res.status(500).json({ error: 'Failed to save settings' }) res.status(500).json({ error: 'Failed to save settings' })

View File

@@ -6,6 +6,8 @@ export type AppSettings = {
} }
let cachedSettings: AppSettings | null = null let cachedSettings: AppSettings | null = null
let cachedSettingsPath: string | null = null
let cachedSettingsMtime: number | null = null
const defaultSettings: AppSettings = { const defaultSettings: AppSettings = {
weekNavigationEnabled: true weekNavigationEnabled: true
@@ -13,13 +15,9 @@ const defaultSettings: AppSettings = {
/** /**
* Загружает настройки из JSON файла * Загружает настройки из JSON файла
* Использует кеш для оптимизации в production * Проверяет время модификации файла для инвалидации кеша
*/ */
export function loadSettings(): AppSettings { export function loadSettings(): AppSettings {
if (cachedSettings) {
return cachedSettings
}
// В production Next.js может использовать другую структуру директорий // В production Next.js может использовать другую структуру директорий
// Пробуем несколько путей // Пробуем несколько путей
const possiblePaths = [ const possiblePaths = [
@@ -28,10 +26,35 @@ export function loadSettings(): AppSettings {
path.join(process.cwd(), 'settings.json'), path.join(process.cwd(), 'settings.json'),
] ]
// Ищем существующий файл
let foundPath: string | null = null
for (const filePath of possiblePaths) { for (const filePath of possiblePaths) {
try {
if (fs.existsSync(filePath)) { if (fs.existsSync(filePath)) {
const fileContents = fs.readFileSync(filePath, 'utf8') foundPath = filePath
break
}
}
// Если файл найден, проверяем, изменился ли он
if (foundPath) {
try {
const stats = fs.statSync(foundPath)
const mtime = stats.mtimeMs
// Если файл изменился или путь изменился, сбрасываем кеш
if (cachedSettings && (cachedSettingsPath !== foundPath || cachedSettingsMtime !== mtime)) {
cachedSettings = null
cachedSettingsPath = null
cachedSettingsMtime = null
}
// Если кеш валиден, возвращаем его
if (cachedSettings && cachedSettingsPath === foundPath && cachedSettingsMtime === mtime) {
return cachedSettings
}
// Загружаем файл заново
const fileContents = fs.readFileSync(foundPath, 'utf8')
const settings = JSON.parse(fileContents) as AppSettings const settings = JSON.parse(fileContents) as AppSettings
// Убеждаемся, что все обязательные поля присутствуют // Убеждаемся, что все обязательные поля присутствуют
@@ -41,11 +64,13 @@ export function loadSettings(): AppSettings {
} }
cachedSettings = mergedSettings cachedSettings = mergedSettings
cachedSettingsPath = foundPath
cachedSettingsMtime = mtime
return mergedSettings return mergedSettings
}
} catch (error) { } catch (error) {
// Пробуем следующий путь console.error('Error reading settings.json:', error)
continue // Продолжаем дальше, чтобы создать файл с настройками по умолчанию
} }
} }
@@ -59,7 +84,12 @@ export function loadSettings(): AppSettings {
} }
fs.writeFileSync(mainPath, JSON.stringify(defaultSettings, null, 2), 'utf8') fs.writeFileSync(mainPath, JSON.stringify(defaultSettings, null, 2), 'utf8')
const stats = fs.statSync(mainPath)
cachedSettings = defaultSettings cachedSettings = defaultSettings
cachedSettingsPath = mainPath
cachedSettingsMtime = stats.mtimeMs
return defaultSettings return defaultSettings
} catch (error) { } catch (error) {
console.error('Error creating settings.json:', error) console.error('Error creating settings.json:', error)
@@ -72,15 +102,12 @@ export function loadSettings(): AppSettings {
* Сохраняет настройки в JSON файл * Сохраняет настройки в JSON файл
*/ */
export function saveSettings(settings: AppSettings): void { export function saveSettings(settings: AppSettings): void {
// Всегда сохраняем в основной путь // Сначала пытаемся найти существующий файл
const filePath = path.join(process.cwd(), 'src/shared/data/settings.json') const possiblePaths = [
path.join(process.cwd(), 'src/shared/data/settings.json'),
try { path.join(process.cwd(), '.next/standalone/src/shared/data/settings.json'),
// Создаем директорию, если её нет path.join(process.cwd(), 'settings.json'),
const dir = path.dirname(filePath) ]
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true })
}
// Объединяем с настройками по умолчанию для сохранения всех полей // Объединяем с настройками по умолчанию для сохранения всех полей
const mergedSettings: AppSettings = { const mergedSettings: AppSettings = {
@@ -88,9 +115,53 @@ export function saveSettings(settings: AppSettings): void {
...settings ...settings
} }
// Ищем существующий файл
let targetPath: string | null = null
for (const filePath of possiblePaths) {
if (fs.existsSync(filePath)) {
targetPath = filePath
break
}
}
// Если файл не найден, используем основной путь
if (!targetPath) {
targetPath = path.join(process.cwd(), 'src/shared/data/settings.json')
}
try {
// Создаем директорию, если её нет
const dir = path.dirname(targetPath)
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true })
}
// Сохраняем файл
fs.writeFileSync(targetPath, JSON.stringify(mergedSettings, null, 2), 'utf8')
// Обновляем кеш с новыми метаданными
try {
const stats = fs.statSync(targetPath)
cachedSettings = mergedSettings
cachedSettingsPath = targetPath
cachedSettingsMtime = stats.mtimeMs
} catch (error) {
// Если не удалось получить stats, просто обновляем кеш
cachedSettings = mergedSettings
cachedSettingsPath = targetPath
cachedSettingsMtime = null
}
// Также сохраняем в другие возможные пути для совместимости (если они существуют)
for (const filePath of possiblePaths) {
if (filePath !== targetPath && fs.existsSync(path.dirname(filePath))) {
try {
fs.writeFileSync(filePath, JSON.stringify(mergedSettings, null, 2), 'utf8') fs.writeFileSync(filePath, JSON.stringify(mergedSettings, null, 2), 'utf8')
// Сбрасываем кеш } catch (error) {
cachedSettings = null // Игнорируем ошибки при сохранении в дополнительные пути
}
}
}
} catch (error) { } catch (error) {
console.error('Error saving settings.json:', error) console.error('Error saving settings.json:', error)
throw new Error('Failed to save settings') throw new Error('Failed to save settings')
@@ -102,6 +173,8 @@ export function saveSettings(settings: AppSettings): void {
*/ */
export function clearSettingsCache(): void { export function clearSettingsCache(): void {
cachedSettings = null cachedSettings = null
cachedSettingsPath = null
cachedSettingsMtime = null
} }

View File

@@ -1,4 +1,3 @@
{ {
"weekNavigationEnabled": false "weekNavigationEnabled": false
} }