fix: navigation under weeks switch
This commit is contained in:
3
settings.json
Normal file
3
settings.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"weekNavigationEnabled": false
|
||||||
|
}
|
||||||
@@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,3 +20,4 @@ export default function handler(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,3 +32,4 @@ export default function handler(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,3 +20,4 @@ export default function handler(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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' })
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{
|
{
|
||||||
"weekNavigationEnabled": false
|
"weekNavigationEnabled": false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user