diff --git a/nuxt.config.ts b/nuxt.config.ts
index d4eb837..5b7cb0b 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -9,6 +9,7 @@ export default defineNuxtConfig({
vapidPrivateKeyFile: "",
public: {
defaultTimezone: "Europe/Oslo",
+ defaultLocale: "en-GB",
vapidPublicKey: "",
}
},
diff --git a/pages/account/settings.vue b/pages/account/settings.vue
index 04691d5..5b4ac8c 100644
--- a/pages/account/settings.vue
+++ b/pages/account/settings.vue
@@ -10,6 +10,10 @@
Timezone
+
@@ -38,6 +42,7 @@ const sessionStore = useSessionStore();
const accountStore = useAccountStore();
const timezone = ref(accountStore.timezone ?? "");
+const locale = ref(accountStore.locale ?? "");
async function changeSettings() {
try {
@@ -45,6 +50,7 @@ async function changeSettings() {
method: "patch",
body: {
timezone: timezone.value,
+ locale: locale.value,
}
});
await sessionStore.fetch();
diff --git a/server/api/auth/account.patch.ts b/server/api/auth/account.patch.ts
index 948392c..d148e67 100644
--- a/server/api/auth/account.patch.ts
+++ b/server/api/auth/account.patch.ts
@@ -24,6 +24,15 @@ export default defineEventHandler(async (event) => {
});
}
}
+ if (patch.locale?.length) {
+ const locale = DateTime.local({ locale: patch.locale }).resolvedLocaleOptions().locale;
+ if (locale !== patch.locale) {
+ throw createError({
+ status: 400,
+ message: `Invalid locale: the locale "${patch.locale}" is not supported (was treated as "${locale}")`
+ });
+ }
+ }
const accounts = await readAccounts();
const sessionAccount = accounts.find(account => account.id === session.accountId);
@@ -51,6 +60,12 @@ export default defineEventHandler(async (event) => {
else
delete sessionAccount.timezone;
}
+ if (patch.locale !== undefined) {
+ if (patch.locale)
+ sessionAccount.locale = patch.locale;
+ else
+ delete sessionAccount.locale;
+ }
await writeAccounts(accounts);
// Update Schedule counts.
diff --git a/shared/types/api.ts b/shared/types/api.ts
index 9ff31bc..ce51f71 100644
--- a/shared/types/api.ts
+++ b/shared/types/api.ts
@@ -9,6 +9,7 @@ export interface ApiAccount {
interestedEventIds?: number[],
interestedEventSlotIds?: number[],
timezone?: string,
+ locale?: string,
}
export const apiAccountPatchSchema = z.object({
@@ -16,6 +17,7 @@ export const apiAccountPatchSchema = z.object({
interestedEventIds: z.optional(z.array(z.number())),
interestedEventSlotIds: z.optional(z.array(z.number())),
timezone: z.optional(z.string()),
+ locale: z.optional(z.string()),
});
export type ApiAccountPatch = z.infer;
diff --git a/stores/account.ts b/stores/account.ts
index e1f4c03..bf92f77 100644
--- a/stores/account.ts
+++ b/stores/account.ts
@@ -8,6 +8,7 @@ export const useAccountStore = defineStore("account", () => {
id: ref(),
name: ref(),
timezone: ref(),
+ locale: ref(),
type: ref(),
interestedEventIds: ref>(new Set()),
interestedEventSlotIds: ref>(new Set()),
@@ -19,6 +20,7 @@ export const useAccountStore = defineStore("account", () => {
state.id.value = account?.id;
state.name.value = account?.name;
state.timezone.value = account?.timezone;
+ state.locale.value = account?.locale;
state.type.value = account?.type;
state.interestedEventIds.value = new Set(account?.interestedEventIds ?? []);
state.interestedEventSlotIds.value = new Set(account?.interestedEventSlotIds ?? []);
@@ -30,6 +32,8 @@ export const useAccountStore = defineStore("account", () => {
canEditPublic: computed(() => state.type.value === "admin"),
activeTimezone: computed(() => state.timezone.value || runtimeConfig.public.defaultTimezone),
defaultTimezone: computed(() => runtimeConfig.public.defaultTimezone),
+ activeLocale: computed(() => state.locale.value || runtimeConfig.public.defaultLocale),
+ defaultLocale: computed(() => runtimeConfig.public.defaultLocale),
};
const actions = {