Add language field and API

This commit is contained in:
Christian Cueni 2023-02-08 13:15:04 +01:00
parent b5e4c30d40
commit b667140d3e
7 changed files with 75 additions and 10 deletions

View File

@ -1,13 +1,15 @@
<script setup lang="ts">
import { loadLocaleMessages, setI18nLanguage } from "@/i18n";
import type { availableLanguages } from "@/stores/user";
import { useUserStore } from "@/stores/user";
import * as log from "loglevel";
log.debug("AppFooter created");
const userStore = useUserStore();
async function changeLocale(event: Event) {
const target = event.target as HTMLSelectElement;
await loadLocaleMessages(target.value);
setI18nLanguage(target.value);
userStore.setUserLanguages(target.value as availableLanguages);
}
</script>
@ -22,9 +24,16 @@ async function changeLocale(event: Event) {
<div class="lg:ml-8">Deutsch</div>
<!--div class="locale-changer">
<select @change="changeLocale($event)">
<option v-for="locale in ['de', 'fr']" :key="`locale-${locale}`" :value="locale">{{ locale }}</option>
<option
v-for="locale in ['de', 'fr']"
:key="`locale-${locale}`"
:value="locale"
:selected="locale === userStore.language"
>
{{ locale }}
</option>
</select>
</div-->
</div -->
<div class="lg:ml-8">{{ $t("footer.contact") }}</div>
</footer>
</template>

View File

@ -6,7 +6,9 @@ import { createI18n } from "vue-i18n";
export const SUPPORT_LOCALES = ["de", "fr", "it"];
let i18n: any = null;
export function setupI18n(options = { locale: "de", legacy: false }) {
export function setupI18n(
options = { locale: "de", legacy: false, fallbackLocale: "de" }
) {
i18n = createI18n(options);
setI18nLanguage(options.locale);
dayjs.locale(options.locale);

View File

@ -1,12 +1,15 @@
import log from "loglevel";
import { bustItGetCache, itGetCached, itPost } from "@/fetchHelpers";
import { loadLocaleMessages, setI18nLanguage } from "@/i18n";
import { useAppStore } from "@/stores/app";
import { defineStore } from "pinia";
const logoutRedirectUrl = import.meta.env.VITE_LOGOUT_REDIRECT;
// typed state https://stackoverflow.com/questions/71012513/when-using-pinia-and-typescript-how-do-you-use-an-action-to-set-the-state
export type availableLanguages = "de" | "fr" | "it";
export type UserState = {
id: number;
first_name: string;
@ -17,6 +20,7 @@ export type UserState = {
is_superuser: boolean;
course_session_experts: number[];
loggedIn: boolean;
language: availableLanguages;
};
const initialUserState: UserState = {
@ -29,8 +33,14 @@ const initialUserState: UserState = {
is_superuser: false,
course_session_experts: [],
loggedIn: false,
language: "de",
};
async function setLocale(language: availableLanguages) {
await loadLocaleMessages(language);
setI18nLanguage(language);
}
export const useUserStore = defineStore({
id: "user",
state: () => initialUserState as UserState,
@ -80,6 +90,12 @@ export const useUserStore = defineStore({
this.$state = data;
this.loggedIn = true;
appStore.userLoaded = true;
await setLocale(data.language);
},
async setUserLanguages(language: availableLanguages) {
await setLocale(language);
this.$state.language = language;
await itPost("/api/core/me/", { language }, { method: "PUT" });
},
},
});

View File

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("core", "0001_initial"),
]
@ -22,4 +21,13 @@ class Migration(migrations.Migration):
max_length=254, unique=True, verbose_name="email address"
),
),
migrations.AddField(
model_name="user",
name="language",
field=models.CharField(
choices=[("de", "Deutsch"), ("fr", "Français"), ("it", "Italiano")],
default="de",
max_length=2,
),
),
]

View File

@ -11,6 +11,12 @@ class User(AbstractUser):
If adding fields that need to be filled at user signup,
"""
LANGUAGE_CHOICES = (
("de", "Deutsch"),
("fr", "Français"),
("it", "Italiano"),
)
# FIXME: look into it...
# objects = UserManager()
avatar_url = models.CharField(max_length=254, blank=True, default="")
@ -19,6 +25,7 @@ class User(AbstractUser):
"SSO subscriber ID", unique=True, null=True, blank=True, default=None
)
additional_json_data = JSONField(default=dict, blank=True)
language = models.CharField(max_length=2, choices=LANGUAGE_CHOICES, default="de")
objects = UserManager()

View File

@ -18,6 +18,15 @@ class UserSerializer(serializers.ModelSerializer):
"avatar_url",
"is_superuser",
"course_session_experts",
"language",
]
read_only_fields = [
"id",
"is_superuser",
"first_name",
"last_name",
"email",
"username",
]
def get_course_session_experts(self, obj):

View File

@ -82,11 +82,25 @@ def vue_login(request):
)
@api_view(["GET"])
@api_view(["GET", "PUT"])
def me_user_view(request):
if request.user.is_authenticated:
if not request.user.is_authenticated:
return Response(status=403)
if request.method == "GET":
return Response(UserSerializer(request.user).data)
return Response(status=403)
if request.method == "PUT":
serializer = UserSerializer(
request.user,
data={"language": request.data.get("language", "de")},
partial=True,
)
if serializer.is_valid():
serializer.save()
return Response(UserSerializer(request.user).data)
return Response(status=400)
@api_view(["POST"])