feat: onboarding course type
This commit is contained in:
parent
4ac735c3be
commit
607789d599
|
|
@ -4,14 +4,15 @@ import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/vue";
|
||||||
import type { AvailableLanguages } from "@/stores/user";
|
import type { AvailableLanguages } from "@/stores/user";
|
||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps<{
|
||||||
courseName: String,
|
courseName: string;
|
||||||
});
|
imageUrl: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
async function changeLocale(language: AvailableLanguages) {
|
async function changeLocale(language: AvailableLanguages) {
|
||||||
userStore.setUserLanguages(language);
|
await userStore.setUserLanguages(language);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -70,12 +71,9 @@ async function changeLocale(language: AvailableLanguages) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="max-w-xs text-white">
|
<div class="max-w-xs text-white">
|
||||||
<img
|
<img :src="imageUrl" class="aspect-square rounded-full object-cover" alt="" />
|
||||||
src="/static/images/mood_uk.jpg"
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
class="aspect-square rounded-full object-cover"
|
<h3 class="mt-8 text-center" v-html="props.courseName"></h3>
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
<h3 class="mt-8 text-center">{{ props.courseName }}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-x-2 text-sm text-white">
|
<div class="flex items-center gap-x-2 text-sm text-white">
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const props = withDefaults(
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<img
|
<img
|
||||||
v-if="props?.imageUrl"
|
v-if="props?.imageUrl"
|
||||||
class="aspect-square h-[172px] w-[172px] rounded-full object-cover"
|
class="aspect-square w-[172px] rounded-full object-cover"
|
||||||
:class="{ 'opacity-30': props.loading }"
|
:class="{ 'opacity-30': props.loading }"
|
||||||
:src="props.imageUrl"
|
:src="props.imageUrl"
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import WizardPage from "@/components/onboarding/WizardPage.vue";
|
import WizardPage from "@/components/onboarding/WizardPage.vue";
|
||||||
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||||
import { ref, watch } from "vue";
|
import { computed, ref, watch } from "vue";
|
||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
import AvatarImage from "@/components/ui/AvatarImage.vue";
|
import AvatarImage from "@/components/ui/AvatarImage.vue";
|
||||||
import { useFileUpload } from "@/composables";
|
import { useFileUpload } from "@/composables";
|
||||||
import { companies } from "@/pages/onboarding/companies";
|
import { companies } from "@/pages/onboarding/companies";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
const user = useUserStore();
|
const user = useUserStore();
|
||||||
|
const route = useRoute();
|
||||||
const selectedCompany = ref(companies[0]);
|
const selectedCompany = ref(companies[0]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -25,6 +26,16 @@ watch(avatarFileInfo, (info) => {
|
||||||
watch(selectedCompany, (company) => {
|
watch(selectedCompany, (company) => {
|
||||||
console.log("company changed", company);
|
console.log("company changed", company);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const nextRoute = computed(() => {
|
||||||
|
if (route.params.courseType === "uk") {
|
||||||
|
return "setupComplete";
|
||||||
|
}
|
||||||
|
if (route.params.courseType === "vv") {
|
||||||
|
return "checkoutAddress";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -69,7 +80,7 @@ watch(selectedCompany, (company) => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<router-link :to="{ name: 'setupComplete' }" class="btn-blue flex items-center">
|
<router-link :to="{ name: nextRoute }" class="btn-blue flex items-center">
|
||||||
Weiter
|
Weiter
|
||||||
<it-icon-arrow-right class="it-icon ml-2 h-6 w-6" />
|
<it-icon-arrow-right class="it-icon ml-2 h-6 w-6" />
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
@ -12,12 +12,5 @@ import WizardPage from "@/components/onboarding/WizardPage.vue";
|
||||||
<p class="mb-4 mt-12">Hast du schon ein Konto?</p>
|
<p class="mb-4 mt-12">Hast du schon ein Konto?</p>
|
||||||
<a href="/sso/login/" class="btn-secondary">Anmelden</a>
|
<a href="/sso/login/" class="btn-secondary">Anmelden</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<button disabled class="btn-blue flex items-center">
|
|
||||||
Weiter
|
|
||||||
<it-icon-arrow-right class="it-icon ml-2 h-6 w-6" />
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
</WizardPage>
|
</WizardPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import WizardSidePanel from "@/components/onboarding/WizardSidePanel.vue";
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
courseType: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
type CourseMetaType = {
|
||||||
|
[key: string]: {
|
||||||
|
name: string;
|
||||||
|
imageUrl: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const courseMeta: CourseMetaType = {
|
||||||
|
uk: {
|
||||||
|
name: "Überbetriebliche Kurse",
|
||||||
|
imageUrl: "/static/images/mood_uk.jpg",
|
||||||
|
},
|
||||||
|
vv: {
|
||||||
|
name: "Versicherungs­vermittler/‑in",
|
||||||
|
imageUrl: "/static/images/mood_vv.jpg",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const courseData = computed(() => {
|
||||||
|
return courseMeta[props.courseType];
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-col lg:flex-row">
|
||||||
|
<WizardSidePanel :image-url="courseData.imageUrl" :course-name="courseData.name" />
|
||||||
|
<router-view />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<script setup lang="ts">
|
|
||||||
import WizardSidePanel from "@/components/onboarding/WizardSidePanel.vue";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="flex flex-col lg:flex-row">
|
|
||||||
<WizardSidePanel course-name="Überbetriebliche Kurse" />
|
|
||||||
<router-view />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import WizardPage from "@/components/onboarding/WizardPage.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<WizardPage :step="2">
|
||||||
|
<template #content>
|
||||||
|
<h2 class="my-10">Lehrgang kaufen</h2>
|
||||||
|
<p class="mb-4">
|
||||||
|
Der Preis für diesen Lehrgang beträgt
|
||||||
|
<b>300 CHF.</b>
|
||||||
|
Mit dem Kauf erhältst du Zugang auf den gesamten Kurs (inkl. Prüfung).
|
||||||
|
</p>
|
||||||
|
<p>Hier kannst du ausschliesslich mit einer Kreditkarte bezahlen.</p>
|
||||||
|
|
||||||
|
<h3 class="mb-4 mt-10">Adresse</h3>
|
||||||
|
<p>
|
||||||
|
Um die Zahlung vornehmen zu können, benötigen wir deine Privatadresse. Optional
|
||||||
|
kannst du die Rechnungsadresse deiner Gesellschaft hinzufügen.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-6 sm:grid-cols-6">
|
||||||
|
<div class="sm:col-span-3">
|
||||||
|
<label
|
||||||
|
for="first-name"
|
||||||
|
class="block text-sm font-medium leading-6 text-gray-900"
|
||||||
|
>
|
||||||
|
Vorname
|
||||||
|
</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input
|
||||||
|
id="first-name"
|
||||||
|
type="text"
|
||||||
|
name="first-name"
|
||||||
|
autocomplete="given-name"
|
||||||
|
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 sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-3">
|
||||||
|
<label
|
||||||
|
for="last-name"
|
||||||
|
class="block text-sm font-medium leading-6 text-gray-900"
|
||||||
|
>
|
||||||
|
Last name
|
||||||
|
</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input
|
||||||
|
id="last-name"
|
||||||
|
type="text"
|
||||||
|
name="last-name"
|
||||||
|
autocomplete="family-name"
|
||||||
|
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 sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-4">
|
||||||
|
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">
|
||||||
|
Email address
|
||||||
|
</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input
|
||||||
|
id="email"
|
||||||
|
name="email"
|
||||||
|
type="email"
|
||||||
|
autocomplete="email"
|
||||||
|
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 sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-3">
|
||||||
|
<label
|
||||||
|
for="country"
|
||||||
|
class="block text-sm font-medium leading-6 text-gray-900"
|
||||||
|
>
|
||||||
|
Country
|
||||||
|
</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<select
|
||||||
|
id="country"
|
||||||
|
name="country"
|
||||||
|
autocomplete="country-name"
|
||||||
|
class="block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:max-w-xs sm:text-sm sm:leading-6"
|
||||||
|
>
|
||||||
|
<option>United States</option>
|
||||||
|
<option>Canada</option>
|
||||||
|
<option>Mexico</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-span-full">
|
||||||
|
<label
|
||||||
|
for="street-address"
|
||||||
|
class="block text-sm font-medium leading-6 text-gray-900"
|
||||||
|
>
|
||||||
|
Street address
|
||||||
|
</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input
|
||||||
|
id="street-address"
|
||||||
|
type="text"
|
||||||
|
name="street-address"
|
||||||
|
autocomplete="street-address"
|
||||||
|
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 sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-2 sm:col-start-1">
|
||||||
|
<label for="city" class="block text-sm font-medium leading-6 text-gray-900">
|
||||||
|
City
|
||||||
|
</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input
|
||||||
|
id="city"
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
autocomplete="address-level2"
|
||||||
|
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 sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label for="region" class="block text-sm font-medium leading-6 text-gray-900">
|
||||||
|
State / Province
|
||||||
|
</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input
|
||||||
|
id="region"
|
||||||
|
type="text"
|
||||||
|
name="region"
|
||||||
|
autocomplete="address-level1"
|
||||||
|
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 sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label
|
||||||
|
for="postal-code"
|
||||||
|
class="block text-sm font-medium leading-6 text-gray-900"
|
||||||
|
>
|
||||||
|
ZIP / Postal code
|
||||||
|
</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input
|
||||||
|
id="postal-code"
|
||||||
|
type="text"
|
||||||
|
name="postal-code"
|
||||||
|
autocomplete="postal-code"
|
||||||
|
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 sm:text-sm sm:leading-6"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'accountProfile' }"
|
||||||
|
class="btn-secondary flex items-center"
|
||||||
|
>
|
||||||
|
<it-icon-arrow-left class="it-icon mr-2 h-6 w-6" />
|
||||||
|
Zurück
|
||||||
|
</router-link>
|
||||||
|
<router-link to="/" class="btn-blue flex items-center">
|
||||||
|
Mit Kreditkarte bezahlen
|
||||||
|
<it-icon-arrow-right class="it-icon ml-2 h-6 w-6" />
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
</WizardPage>
|
||||||
|
</template>
|
||||||
|
|
@ -7,7 +7,7 @@ import {
|
||||||
updateLoggedIn,
|
updateLoggedIn,
|
||||||
} from "@/router/guards";
|
} from "@/router/guards";
|
||||||
import { addToHistory } from "@/router/history";
|
import { addToHistory } from "@/router/history";
|
||||||
import { checkUKProcess } from "@/router/onboarding";
|
import { onboardingRedirect } from "@/router/onboarding";
|
||||||
import { createRouter, createWebHistory } from "vue-router";
|
import { createRouter, createWebHistory } from "vue-router";
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|
@ -231,39 +231,40 @@ const router = createRouter({
|
||||||
component: () => import("@/pages/AppointmentsPage.vue"),
|
component: () => import("@/pages/AppointmentsPage.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/onboarding/uk",
|
path: "/onboarding/:courseType",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import("@/pages/onboarding/uk/WizardBase.vue"),
|
component: () => import("@/pages/onboarding/WizardBase.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
public: true,
|
public: true,
|
||||||
hideChrome: true,
|
hideChrome: true,
|
||||||
},
|
},
|
||||||
beforeEnter: checkUKProcess,
|
beforeEnter: onboardingRedirect,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "account/create",
|
path: "account/create",
|
||||||
props: true,
|
component: () => import("@/pages/onboarding/AccountSetup.vue"),
|
||||||
component: () => import("@/pages/onboarding/uk/AccountSetup.vue"),
|
|
||||||
name: "accountCreate",
|
name: "accountCreate",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "account/confirm",
|
path: "account/confirm",
|
||||||
props: true,
|
component: () => import("@/pages/onboarding/AccountConfirm.vue"),
|
||||||
component: () => import("@/pages/onboarding/uk/AccountConfirm.vue"),
|
|
||||||
name: "accountConfirm",
|
name: "accountConfirm",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "account/profile",
|
path: "account/profile",
|
||||||
props: true,
|
component: () => import("@/pages/onboarding/AccountProfile.vue"),
|
||||||
component: () => import("@/pages/onboarding/uk/AccountProfile.vue"),
|
|
||||||
name: "accountProfile",
|
name: "accountProfile",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "account/complete",
|
path: "account/complete",
|
||||||
props: true,
|
|
||||||
component: () => import("@/pages/onboarding/uk/SetupComplete.vue"),
|
component: () => import("@/pages/onboarding/uk/SetupComplete.vue"),
|
||||||
name: "setupComplete",
|
name: "setupComplete",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "checkout/address",
|
||||||
|
component: () => import("@/pages/onboarding/vv/CheckoutAddress.vue"),
|
||||||
|
name: "checkoutAddress",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
import type { NavigationGuardNext, RouteLocationNormalized } from "vue-router";
|
import type { NavigationGuardNext, RouteLocationNormalized } from "vue-router";
|
||||||
|
|
||||||
export async function checkUKProcess(
|
export async function onboardingRedirect(
|
||||||
to: RouteLocationNormalized,
|
to: RouteLocationNormalized,
|
||||||
from: RouteLocationNormalized,
|
from: RouteLocationNormalized,
|
||||||
next: NavigationGuardNext
|
next: NavigationGuardNext
|
||||||
|
|
@ -11,14 +11,14 @@ export async function checkUKProcess(
|
||||||
// Guest
|
// Guest
|
||||||
if (!userStore.loggedIn) {
|
if (!userStore.loggedIn) {
|
||||||
if (to.name !== "accountCreate") {
|
if (to.name !== "accountCreate") {
|
||||||
return next({ name: "accountCreate" });
|
return next({ name: "accountCreate", params: to.params });
|
||||||
}
|
}
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logged in
|
// Logged in
|
||||||
if (to.name === "accountCreate") {
|
if (to.name === "accountCreate") {
|
||||||
return next({ name: "accountConfirm" });
|
return next({ name: "accountConfirm", params: to.params });
|
||||||
}
|
}
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue