vbv/client/src/pages/onboarding/AccountProfile.vue

159 lines
4.8 KiB
Vue

<script setup lang="ts">
import WizardPage from "@/components/onboarding/WizardPage.vue";
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
import { computed, ref, watch } from "vue";
import { useUserStore } from "@/stores/user";
import { useRoute, useRouter } from "vue-router";
import { useTranslation } from "i18next-vue";
import { isOtherOrganisation, profileNextRoute } from "@/services/onboarding";
import { useEntities } from "@/services/entities";
import AvatarImage from "@/components/ui/AvatarImage.vue";
const { t } = useTranslation();
const user = useUserStore();
const route = useRoute();
const router = useRouter();
const { organisations } = useEntities();
const organisationDetailName = ref<string>("");
const selectedOrganisation = ref({
id: 0,
name: t("a.Auswählen"),
});
watch(
organisations,
(newOrganisations) => {
if (newOrganisations) {
const userOrganisation = newOrganisations.find((c) => c.id === user.organisation);
if (userOrganisation) {
selectedOrganisation.value = userOrganisation;
}
}
},
{ immediate: true }
);
const validOrganisation = computed(() => {
const organisationSelected = selectedOrganisation.value.id !== 0;
const organisationNameSet =
!isOtherOrganisation(selectedOrganisation.value.id) ||
!!organisationDetailName.value.trim();
return organisationSelected && organisationNameSet;
});
const avatarError = ref(false);
const avatarLoading = ref(false);
async function avatarUpload(e: Event) {
const { files } = e.target as HTMLInputElement;
if (!files?.length) return;
avatarLoading.value = true;
avatarError.value = false;
try {
await user.setUserAvatar(files[0]);
} catch (e) {
avatarError.value = true;
} finally {
avatarLoading.value = false;
}
}
async function updateUserProfile() {
await user.updateUserProfile({
organisation: selectedOrganisation.value.id,
organisation_detail_name: organisationDetailName.value.trim(),
});
}
const nextRoute = computed(() => {
return profileNextRoute(route.params.courseType);
});
async function navigateNextRoute() {
await updateUserProfile();
await router.push({ name: nextRoute.value });
}
</script>
<template>
<WizardPage :step="1">
<template #content>
<h2 class="my-10" data-cy="account-profile-title">
{{ $t("a.Profil ergänzen") }}
</h2>
<h3 class="mb-3">{{ $t("a.Gesellschaft") }}</h3>
<p class="mb-6 max-w-md hyphens-none">
{{
$t(
"a.Wähle hier den Namen der Gesellschaft aus, in der du arbeitest. So können dich andere Personen einfacher finden."
)
}}
</p>
<ItDropdownSelect v-model="selectedOrganisation" :items="organisations" />
<div v-if="isOtherOrganisation(selectedOrganisation.id)" class="my-8">
<label for="organisationDetailName" class="heading-3 block pb-1.5">
{{ $t("a.Firmenname") }}
</label>
<input
id="organisationDetailName"
v-model="organisationDetailName"
type="text"
name="phone"
class="block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 disabled:cursor-not-allowed disabled:text-gray-500 disabled:ring-gray-200 sm:max-w-sm sm:text-sm sm:leading-6"
/>
</div>
<div class="mt-16 flex flex-col justify-between gap-12 lg:flex-row lg:gap-24">
<div>
<h3 class="mb-3">{{ $t("a.Profilbild") }}</h3>
<p class="mb-6 max-w-md hyphens-none">
{{
$t(
"a.Lade ein Profilbild hoch, damit dich andere Personen auf den ersten Blick erkennen."
)
}}
</p>
<div class="btn-primary relative inline-flex cursor-pointer items-center">
<input
id="upload"
type="file"
class="absolute opacity-0"
accept="image/*"
:disabled="avatarLoading"
@change="avatarUpload"
/>
{{ $t("a.Bild hochladen") }}
<it-icon-upload class="it-icon ml-2 h-6 w-6" />
</div>
<p v-if="avatarError" class="mt-3 text-red-700">
{{ $t("a.Datei kann nicht gespeichert werden.") }}
</p>
</div>
<AvatarImage :loading="avatarLoading" :image-url="user.avatar_url" />
</div>
</template>
<template #footer>
<button
:disabled="!validOrganisation"
class="btn-blue flex items-center"
role="link"
data-cy="continue-button"
@click="navigateNextRoute"
>
{{ $t("general.next") }}
<it-icon-arrow-right class="it-icon ml-2 h-6 w-6" />
</button>
</template>
</WizardPage>
</template>