mirror of
https://github.com/LogicLabs-OU/OpenArchiver.git
synced 2026-04-06 00:31:57 +02:00
Formatting code
This commit is contained in:
@@ -75,9 +75,8 @@ export default defineConfig({
|
||||
{ text: 'Overview', link: '/services/' },
|
||||
{ text: 'Storage Service', link: '/services/storage-service' },
|
||||
{
|
||||
text: 'IAM Service', items: [
|
||||
{ text: 'IAM Policies', link: '/services/iam-service/iam-policy' }
|
||||
]
|
||||
text: 'IAM Service',
|
||||
items: [{ text: 'IAM Policies', link: '/services/iam-service/iam-policy' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -38,8 +38,7 @@ export class IngestionController {
|
||||
logger.error({ err: error }, 'Create ingestion source error');
|
||||
// Return a 400 Bad Request for connection errors
|
||||
return res.status(400).json({
|
||||
message:
|
||||
error.message || req.t('ingestion.failedToCreate'),
|
||||
message: error.message || req.t('ingestion.failedToCreate'),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,22 +4,22 @@ import { SettingsService } from '../../services/SettingsService';
|
||||
const settingsService = new SettingsService();
|
||||
|
||||
export const getSettings = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const settings = await settingsService.getSettings();
|
||||
res.status(200).json(settings);
|
||||
} catch (error) {
|
||||
// A more specific error could be logged here
|
||||
res.status(500).json({ message: req.t('settings.failedToRetrieve') });
|
||||
}
|
||||
try {
|
||||
const settings = await settingsService.getSettings();
|
||||
res.status(200).json(settings);
|
||||
} catch (error) {
|
||||
// A more specific error could be logged here
|
||||
res.status(500).json({ message: req.t('settings.failedToRetrieve') });
|
||||
}
|
||||
};
|
||||
|
||||
export const updateSettings = async (req: Request, res: Response) => {
|
||||
try {
|
||||
// Basic validation can be performed here if necessary
|
||||
const updatedSettings = await settingsService.updateSettings(req.body);
|
||||
res.status(200).json(updatedSettings);
|
||||
} catch (error) {
|
||||
// A more specific error could be logged here
|
||||
res.status(500).json({ message: req.t('settings.failedToUpdate') });
|
||||
}
|
||||
try {
|
||||
// Basic validation can be performed here if necessary
|
||||
const updatedSettings = await settingsService.updateSettings(req.body);
|
||||
res.status(200).json(updatedSettings);
|
||||
} catch (error) {
|
||||
// A more specific error could be logged here
|
||||
res.status(500).json({ message: req.t('settings.failedToUpdate') });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as path from 'path';
|
||||
import { storage as storageConfig } from '../../config/storage';
|
||||
|
||||
export class StorageController {
|
||||
constructor(private storageService: StorageService) { }
|
||||
constructor(private storageService: StorageService) {}
|
||||
|
||||
public downloadFile = async (req: Request, res: Response): Promise<void> => {
|
||||
const unsafePath = req.query.path as string;
|
||||
|
||||
@@ -5,21 +5,25 @@ import { requirePermission } from '../middleware/requirePermission';
|
||||
import { AuthService } from '../../services/AuthService';
|
||||
|
||||
export const createSettingsRouter = (authService: AuthService): Router => {
|
||||
const router = Router();
|
||||
const router = Router();
|
||||
|
||||
// Public route to get non-sensitive settings. settings read should not be scoped with a permission because all end users need the settings data in the frontend. However, for sensitive settings data, we need to add a new permission subject to limit access. So this route should only expose non-sensitive settings data.
|
||||
/**
|
||||
* @returns SystemSettings
|
||||
*/
|
||||
router.get('/', settingsController.getSettings);
|
||||
// Public route to get non-sensitive settings. settings read should not be scoped with a permission because all end users need the settings data in the frontend. However, for sensitive settings data, we need to add a new permission subject to limit access. So this route should only expose non-sensitive settings data.
|
||||
/**
|
||||
* @returns SystemSettings
|
||||
*/
|
||||
router.get('/', settingsController.getSettings);
|
||||
|
||||
// Protected route to update settings
|
||||
router.put(
|
||||
'/',
|
||||
requireAuth(authService),
|
||||
requirePermission('manage', 'settings', 'You do not have permission to update system settings.'),
|
||||
settingsController.updateSettings
|
||||
);
|
||||
// Protected route to update settings
|
||||
router.put(
|
||||
'/',
|
||||
requireAuth(authService),
|
||||
requirePermission(
|
||||
'manage',
|
||||
'settings',
|
||||
'You do not have permission to update system settings.'
|
||||
),
|
||||
settingsController.updateSettings
|
||||
);
|
||||
|
||||
return router;
|
||||
return router;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,132 +1,132 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1752225352591,
|
||||
"tag": "0000_amusing_namora",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1752326803882,
|
||||
"tag": "0001_odd_night_thrasher",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1752332648392,
|
||||
"tag": "0002_lethal_quentin_quire",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1752332967084,
|
||||
"tag": "0003_petite_wrecker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1752606108876,
|
||||
"tag": "0004_sleepy_paper_doll",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1752606327253,
|
||||
"tag": "0005_chunky_sue_storm",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1753112018514,
|
||||
"tag": "0006_majestic_caretaker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1753190159356,
|
||||
"tag": "0007_handy_archangel",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "7",
|
||||
"when": 1753370737317,
|
||||
"tag": "0008_eminent_the_spike",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1754337938241,
|
||||
"tag": "0009_late_lenny_balinger",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "7",
|
||||
"when": 1754420780849,
|
||||
"tag": "0010_perpetual_lightspeed",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "7",
|
||||
"when": 1754422064158,
|
||||
"tag": "0011_tan_blackheart",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1754476962901,
|
||||
"tag": "0012_warm_the_stranger",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1754659373517,
|
||||
"tag": "0013_classy_talkback",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "7",
|
||||
"when": 1754831765718,
|
||||
"tag": "0014_foamy_vapor",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 15,
|
||||
"version": "7",
|
||||
"when": 1755443936046,
|
||||
"tag": "0015_wakeful_norman_osborn",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 16,
|
||||
"version": "7",
|
||||
"when": 1755780572342,
|
||||
"tag": "0016_lonely_mariko_yashida",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"version": "7",
|
||||
"when": 1755961566627,
|
||||
"tag": "0017_tranquil_shooting_star",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1752225352591,
|
||||
"tag": "0000_amusing_namora",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1752326803882,
|
||||
"tag": "0001_odd_night_thrasher",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1752332648392,
|
||||
"tag": "0002_lethal_quentin_quire",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1752332967084,
|
||||
"tag": "0003_petite_wrecker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1752606108876,
|
||||
"tag": "0004_sleepy_paper_doll",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1752606327253,
|
||||
"tag": "0005_chunky_sue_storm",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1753112018514,
|
||||
"tag": "0006_majestic_caretaker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1753190159356,
|
||||
"tag": "0007_handy_archangel",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "7",
|
||||
"when": 1753370737317,
|
||||
"tag": "0008_eminent_the_spike",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1754337938241,
|
||||
"tag": "0009_late_lenny_balinger",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "7",
|
||||
"when": 1754420780849,
|
||||
"tag": "0010_perpetual_lightspeed",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "7",
|
||||
"when": 1754422064158,
|
||||
"tag": "0011_tan_blackheart",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1754476962901,
|
||||
"tag": "0012_warm_the_stranger",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1754659373517,
|
||||
"tag": "0013_classy_talkback",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "7",
|
||||
"when": 1754831765718,
|
||||
"tag": "0014_foamy_vapor",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 15,
|
||||
"version": "7",
|
||||
"when": 1755443936046,
|
||||
"tag": "0015_wakeful_norman_osborn",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 16,
|
||||
"version": "7",
|
||||
"when": 1755780572342,
|
||||
"tag": "0016_lonely_mariko_yashida",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"version": "7",
|
||||
"when": 1755961566627,
|
||||
"tag": "0017_tranquil_shooting_star",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,4 +5,4 @@ export * from './schema/compliance';
|
||||
export * from './schema/custodians';
|
||||
export * from './schema/ingestion-sources';
|
||||
export * from './schema/users';
|
||||
export * from './schema/system-settings'
|
||||
export * from './schema/system-settings';
|
||||
|
||||
@@ -2,6 +2,6 @@ import { pgTable, serial, jsonb } from 'drizzle-orm/pg-core';
|
||||
import type { SystemSettings } from '@open-archiver/types';
|
||||
|
||||
export const systemSettings = pgTable('system_settings', {
|
||||
id: serial('id').primaryKey(),
|
||||
config: jsonb('config').$type<SystemSettings>().notNull(),
|
||||
id: serial('id').primaryKey(),
|
||||
config: jsonb('config').$type<SystemSettings>().notNull(),
|
||||
});
|
||||
|
||||
@@ -61,17 +61,15 @@ const initializeI18next = async () => {
|
||||
const systemSettings = await settingsService.getSettings();
|
||||
const defaultLanguage = systemSettings?.language || 'en';
|
||||
logger.info({ language: defaultLanguage }, 'Default language');
|
||||
await i18next
|
||||
.use(FsBackend)
|
||||
.init({
|
||||
lng: defaultLanguage,
|
||||
fallbackLng: defaultLanguage,
|
||||
ns: ['translation'],
|
||||
defaultNS: 'translation',
|
||||
backend: {
|
||||
loadPath: path.resolve(__dirname, './locales/{{lng}}/{{ns}}.json'),
|
||||
},
|
||||
});
|
||||
await i18next.use(FsBackend).init({
|
||||
lng: defaultLanguage,
|
||||
fallbackLng: defaultLanguage,
|
||||
ns: ['translation'],
|
||||
defaultNS: 'translation',
|
||||
backend: {
|
||||
loadPath: path.resolve(__dirname, './locales/{{lng}}/{{ns}}.json'),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// --- Express App Initialization ---
|
||||
|
||||
@@ -4,57 +4,52 @@ import type { SystemSettings } from '@open-archiver/types';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
const DEFAULT_SETTINGS: SystemSettings = {
|
||||
language: 'en',
|
||||
theme: 'system',
|
||||
supportEmail: null,
|
||||
language: 'en',
|
||||
theme: 'system',
|
||||
supportEmail: null,
|
||||
};
|
||||
|
||||
export class SettingsService {
|
||||
/**
|
||||
* Retrieves the current system settings.
|
||||
* If no settings exist, it initializes and returns the default settings.
|
||||
* @returns The system settings.
|
||||
*/
|
||||
public async getSettings(): Promise<SystemSettings> {
|
||||
const settings = await db.select().from(systemSettings).limit(1);
|
||||
/**
|
||||
* Retrieves the current system settings.
|
||||
* If no settings exist, it initializes and returns the default settings.
|
||||
* @returns The system settings.
|
||||
*/
|
||||
public async getSettings(): Promise<SystemSettings> {
|
||||
const settings = await db.select().from(systemSettings).limit(1);
|
||||
|
||||
if (settings.length === 0) {
|
||||
return this.createDefaultSettings();
|
||||
}
|
||||
if (settings.length === 0) {
|
||||
return this.createDefaultSettings();
|
||||
}
|
||||
|
||||
return settings[0].config;
|
||||
}
|
||||
return settings[0].config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the system settings by merging the new configuration with the existing one.
|
||||
* @param newConfig - A partial object of the new settings configuration.
|
||||
* @returns The updated system settings.
|
||||
*/
|
||||
public async updateSettings(
|
||||
newConfig: Partial<SystemSettings>
|
||||
): Promise<SystemSettings> {
|
||||
const currentConfig = await this.getSettings();
|
||||
const mergedConfig = { ...currentConfig, ...newConfig };
|
||||
/**
|
||||
* Updates the system settings by merging the new configuration with the existing one.
|
||||
* @param newConfig - A partial object of the new settings configuration.
|
||||
* @returns The updated system settings.
|
||||
*/
|
||||
public async updateSettings(newConfig: Partial<SystemSettings>): Promise<SystemSettings> {
|
||||
const currentConfig = await this.getSettings();
|
||||
const mergedConfig = { ...currentConfig, ...newConfig };
|
||||
|
||||
// Since getSettings ensures a record always exists, we can directly update.
|
||||
const [result] = await db
|
||||
.update(systemSettings)
|
||||
.set({ config: mergedConfig })
|
||||
.returning();
|
||||
// Since getSettings ensures a record always exists, we can directly update.
|
||||
const [result] = await db.update(systemSettings).set({ config: mergedConfig }).returning();
|
||||
|
||||
return result.config;
|
||||
}
|
||||
return result.config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and saves the default system settings.
|
||||
* This is called internally when no settings are found.
|
||||
* @returns The newly created default settings.
|
||||
*/
|
||||
private async createDefaultSettings(): Promise<SystemSettings> {
|
||||
const [result] = await db
|
||||
.insert(systemSettings)
|
||||
.values({ config: DEFAULT_SETTINGS })
|
||||
.returning();
|
||||
return result.config;
|
||||
}
|
||||
/**
|
||||
* Creates and saves the default system settings.
|
||||
* This is called internally when no settings are found.
|
||||
* @returns The newly created default settings.
|
||||
*/
|
||||
private async createDefaultSettings(): Promise<SystemSettings> {
|
||||
const [result] = await db
|
||||
.insert(systemSettings)
|
||||
.values({ config: DEFAULT_SETTINGS })
|
||||
.returning();
|
||||
return result.config;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,70 +15,70 @@ import el from './el.json';
|
||||
// This is your config object.
|
||||
// It defines the languages and how to load them.
|
||||
const config: Config = {
|
||||
// Define the loaders for each language
|
||||
loaders: [
|
||||
// English 🇬🇧
|
||||
{
|
||||
locale: 'en',
|
||||
key: 'app', // This key matches the top-level key in your en.json
|
||||
loader: async () => en.app, // We return the nested 'app' object
|
||||
},
|
||||
// German 🇩🇪
|
||||
{
|
||||
locale: 'de',
|
||||
key: 'app', // This key matches the top-level key in your en.json
|
||||
loader: async () => de.app, // We return the nested 'app' object
|
||||
},
|
||||
// Spanish 🇪🇸
|
||||
{
|
||||
locale: 'es',
|
||||
key: 'app',
|
||||
loader: async () => es.app,
|
||||
},
|
||||
// French 🇫🇷
|
||||
{
|
||||
locale: 'fr',
|
||||
key: 'app',
|
||||
loader: async () => fr.app,
|
||||
},
|
||||
// Italian 🇮🇹
|
||||
{
|
||||
locale: 'it',
|
||||
key: 'app',
|
||||
loader: async () => it.app,
|
||||
},
|
||||
// Portuguese 🇵🇹
|
||||
{
|
||||
locale: 'pt',
|
||||
key: 'app',
|
||||
loader: async () => pt.app,
|
||||
},
|
||||
// Dutch 🇳🇱
|
||||
{
|
||||
locale: 'nl',
|
||||
key: 'app',
|
||||
loader: async () => nl.app,
|
||||
},
|
||||
// Japanese 🇯🇵
|
||||
{
|
||||
locale: 'ja',
|
||||
key: 'app',
|
||||
loader: async () => ja.app,
|
||||
},
|
||||
// Estonian 🇪🇪
|
||||
{
|
||||
locale: 'et',
|
||||
key: 'app',
|
||||
loader: async () => et.app,
|
||||
},
|
||||
// Greek 🇬🇷
|
||||
{
|
||||
locale: 'el',
|
||||
key: 'app',
|
||||
loader: async () => el.app,
|
||||
},
|
||||
],
|
||||
fallbackLocale: 'en',
|
||||
// Define the loaders for each language
|
||||
loaders: [
|
||||
// English 🇬🇧
|
||||
{
|
||||
locale: 'en',
|
||||
key: 'app', // This key matches the top-level key in your en.json
|
||||
loader: async () => en.app, // We return the nested 'app' object
|
||||
},
|
||||
// German 🇩🇪
|
||||
{
|
||||
locale: 'de',
|
||||
key: 'app', // This key matches the top-level key in your en.json
|
||||
loader: async () => de.app, // We return the nested 'app' object
|
||||
},
|
||||
// Spanish 🇪🇸
|
||||
{
|
||||
locale: 'es',
|
||||
key: 'app',
|
||||
loader: async () => es.app,
|
||||
},
|
||||
// French 🇫🇷
|
||||
{
|
||||
locale: 'fr',
|
||||
key: 'app',
|
||||
loader: async () => fr.app,
|
||||
},
|
||||
// Italian 🇮🇹
|
||||
{
|
||||
locale: 'it',
|
||||
key: 'app',
|
||||
loader: async () => it.app,
|
||||
},
|
||||
// Portuguese 🇵🇹
|
||||
{
|
||||
locale: 'pt',
|
||||
key: 'app',
|
||||
loader: async () => pt.app,
|
||||
},
|
||||
// Dutch 🇳🇱
|
||||
{
|
||||
locale: 'nl',
|
||||
key: 'app',
|
||||
loader: async () => nl.app,
|
||||
},
|
||||
// Japanese 🇯🇵
|
||||
{
|
||||
locale: 'ja',
|
||||
key: 'app',
|
||||
loader: async () => ja.app,
|
||||
},
|
||||
// Estonian 🇪🇪
|
||||
{
|
||||
locale: 'et',
|
||||
key: 'app',
|
||||
loader: async () => et.app,
|
||||
},
|
||||
// Greek 🇬🇷
|
||||
{
|
||||
locale: 'el',
|
||||
key: 'app',
|
||||
loader: async () => el.app,
|
||||
},
|
||||
],
|
||||
fallbackLocale: 'en',
|
||||
};
|
||||
|
||||
// Create the i18n instance.
|
||||
@@ -89,7 +89,6 @@ export const { t, locale, locales, loading, loadTranslations } = new i18n(config
|
||||
// Export the t store for use in components
|
||||
// export const t = i18n.t;
|
||||
|
||||
|
||||
// import i18n from 'sveltekit-i18n';
|
||||
// import type { Config } from 'sveltekit-i18n';
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ export const load: LayoutServerLoad = async (event) => {
|
||||
}
|
||||
|
||||
const settingsResponse = await api('/settings', event);
|
||||
const settings: SystemSettings | null = settingsResponse.ok ? await settingsResponse.json() : null;
|
||||
const settings: SystemSettings | null = settingsResponse.ok
|
||||
? await settingsResponse.json()
|
||||
: null;
|
||||
|
||||
return {
|
||||
user: locals.user,
|
||||
|
||||
@@ -4,18 +4,18 @@ import { browser } from '$app/environment';
|
||||
import type { SupportedLanguage } from '@open-archiver/types';
|
||||
|
||||
export const load: LayoutLoad = async ({ url, data }) => {
|
||||
const { pathname } = url;
|
||||
const { pathname } = url;
|
||||
|
||||
let initLocale: SupportedLanguage = 'en'; // Default fallback
|
||||
let initLocale: SupportedLanguage = 'en'; // Default fallback
|
||||
|
||||
if (data.settings?.language) {
|
||||
initLocale = data.settings.language;
|
||||
}
|
||||
if (data.settings?.language) {
|
||||
initLocale = data.settings.language;
|
||||
}
|
||||
|
||||
console.log(initLocale);
|
||||
await loadTranslations(initLocale, pathname);
|
||||
console.log(initLocale);
|
||||
await loadTranslations(initLocale, pathname);
|
||||
|
||||
return {
|
||||
...data
|
||||
};
|
||||
return {
|
||||
...data,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,47 +4,47 @@ import { error, fail } from '@sveltejs/kit';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async (event) => {
|
||||
const response = await api('/settings', event);
|
||||
const response = await api('/settings', event);
|
||||
|
||||
if (!response.ok) {
|
||||
const { message } = await response.json();
|
||||
throw error(response.status, message || 'Failed to fetch system settings');
|
||||
}
|
||||
if (!response.ok) {
|
||||
const { message } = await response.json();
|
||||
throw error(response.status, message || 'Failed to fetch system settings');
|
||||
}
|
||||
|
||||
const settings: SystemSettings = await response.json();
|
||||
return {
|
||||
settings,
|
||||
};
|
||||
const settings: SystemSettings = await response.json();
|
||||
return {
|
||||
settings,
|
||||
};
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
default: async (event) => {
|
||||
const formData = await event.request.formData();
|
||||
const language = formData.get('language');
|
||||
const theme = formData.get('theme');
|
||||
const supportEmail = formData.get('supportEmail');
|
||||
default: async (event) => {
|
||||
const formData = await event.request.formData();
|
||||
const language = formData.get('language');
|
||||
const theme = formData.get('theme');
|
||||
const supportEmail = formData.get('supportEmail');
|
||||
|
||||
const body: Partial<SystemSettings> = {
|
||||
language: language as SystemSettings['language'],
|
||||
theme: theme as SystemSettings['theme'],
|
||||
supportEmail: supportEmail ? String(supportEmail) : null,
|
||||
};
|
||||
const body: Partial<SystemSettings> = {
|
||||
language: language as SystemSettings['language'],
|
||||
theme: theme as SystemSettings['theme'],
|
||||
supportEmail: supportEmail ? String(supportEmail) : null,
|
||||
};
|
||||
|
||||
const response = await api('/settings', event, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const response = await api('/settings', event, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const { message } = await response.json();
|
||||
return fail(response.status, { message: message || 'Failed to update settings' });
|
||||
}
|
||||
if (!response.ok) {
|
||||
const { message } = await response.json();
|
||||
return fail(response.status, { message: message || 'Failed to update settings' });
|
||||
}
|
||||
|
||||
const updatedSettings: SystemSettings = await response.json();
|
||||
const updatedSettings: SystemSettings = await response.json();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
settings: updatedSettings,
|
||||
};
|
||||
},
|
||||
return {
|
||||
success: true,
|
||||
settings: updatedSettings,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
export type SupportedLanguage =
|
||||
| 'en' // English
|
||||
| 'es' // Spanish
|
||||
| 'fr' // French
|
||||
| 'de' // German
|
||||
| 'it' // Italian
|
||||
| 'pt' // Portuguese
|
||||
| 'nl' // Dutch
|
||||
| 'ja' // Japanese
|
||||
| 'et' // Estonian
|
||||
| 'el'; // Greek
|
||||
| 'en' // English
|
||||
| 'es' // Spanish
|
||||
| 'fr' // French
|
||||
| 'de' // German
|
||||
| 'it' // Italian
|
||||
| 'pt' // Portuguese
|
||||
| 'nl' // Dutch
|
||||
| 'ja' // Japanese
|
||||
| 'et' // Estonian
|
||||
| 'el'; // Greek
|
||||
|
||||
export type Theme = 'light' | 'dark' | 'system';
|
||||
|
||||
export interface SystemSettings {
|
||||
/** The default display language for the application UI. */
|
||||
language: SupportedLanguage;
|
||||
/** The default display language for the application UI. */
|
||||
language: SupportedLanguage;
|
||||
|
||||
/** The default color theme for the application. */
|
||||
theme: Theme;
|
||||
/** The default color theme for the application. */
|
||||
theme: Theme;
|
||||
|
||||
/** A public-facing email address for user support inquiries. */
|
||||
supportEmail: string | null;
|
||||
/** A public-facing email address for user support inquiries. */
|
||||
supportEmail: string | null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user