feat: onboarding course checkout
This commit is contained in:
parent
607789d599
commit
9592005419
|
|
@ -0,0 +1,131 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: {
|
||||
street: string;
|
||||
streetNumber: string;
|
||||
postalCode: string;
|
||||
city: string;
|
||||
country: string;
|
||||
};
|
||||
}>();
|
||||
|
||||
const orgAddress = ref(props.modelValue);
|
||||
|
||||
// Emit update event for v-model
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
|
||||
watch(
|
||||
orgAddress,
|
||||
(newValue) => {
|
||||
emit("update:modelValue", newValue);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="my-10 grid grid-cols-1 gap-x-6 gap-y-6 sm:grid-cols-6">
|
||||
<div class="sm:col-span-5">
|
||||
<label
|
||||
for="company-street-address"
|
||||
class="block text-sm font-medium leading-6 text-gray-900"
|
||||
>
|
||||
Strasse
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="company-street-address"
|
||||
v-model="orgAddress.street"
|
||||
type="text"
|
||||
required
|
||||
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-1">
|
||||
<label
|
||||
for="company-street-number"
|
||||
class="block text-sm font-medium leading-6 text-gray-900"
|
||||
>
|
||||
Hausnummmer
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="company-street-number"
|
||||
v-model="orgAddress.streetNumber"
|
||||
name="street-number"
|
||||
type="text"
|
||||
autocomplete="street-number"
|
||||
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-1">
|
||||
<label
|
||||
for="company-postal-code"
|
||||
class="block text-sm font-medium leading-6 text-gray-900"
|
||||
>
|
||||
PLZ
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="company-postal-code"
|
||||
v-model="orgAddress.postalCode"
|
||||
type="text"
|
||||
required
|
||||
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 class="sm:col-span-5">
|
||||
<label
|
||||
for="company-city"
|
||||
class="block text-sm font-medium leading-6 text-gray-900"
|
||||
>
|
||||
Ort
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="company-city"
|
||||
v-model="orgAddress.city"
|
||||
type="text"
|
||||
name="city"
|
||||
required
|
||||
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="col-span-full">
|
||||
<label
|
||||
for="company-country"
|
||||
class="block text-sm font-medium leading-6 text-gray-900"
|
||||
>
|
||||
Land
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<select
|
||||
id="company-country"
|
||||
v-model="orgAddress.country"
|
||||
required
|
||||
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:text-sm sm:leading-6"
|
||||
>
|
||||
<option>Schweiz</option>
|
||||
<option>Deutschland</option>
|
||||
<option>Österreich</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
street: string;
|
||||
streetNumber: string;
|
||||
postalCode: string;
|
||||
city: string;
|
||||
country: string;
|
||||
};
|
||||
}>();
|
||||
|
||||
const address = ref(props.modelValue);
|
||||
|
||||
// Emit update event for v-model
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
|
||||
watch(
|
||||
address,
|
||||
(newValue) => {
|
||||
emit("update:modelValue", newValue);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="my-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"
|
||||
v-model="address.firstName"
|
||||
type="text"
|
||||
name="first-name"
|
||||
required
|
||||
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">
|
||||
Name
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="last-name"
|
||||
v-model="address.lastName"
|
||||
type="text"
|
||||
name="last-name"
|
||||
required
|
||||
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-5">
|
||||
<label
|
||||
for="street-address"
|
||||
class="block text-sm font-medium leading-6 text-gray-900"
|
||||
>
|
||||
Strasse
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="street-address"
|
||||
v-model="address.street"
|
||||
type="text"
|
||||
required
|
||||
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-1">
|
||||
<label
|
||||
for="street-number"
|
||||
class="block text-sm font-medium leading-6 text-gray-900"
|
||||
>
|
||||
Hausnummmer
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="street-number"
|
||||
v-model="address.streetNumber"
|
||||
name="street-number"
|
||||
type="text"
|
||||
autocomplete="street-number"
|
||||
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-1">
|
||||
<label
|
||||
for="postal-code"
|
||||
class="block text-sm font-medium leading-6 text-gray-900"
|
||||
>
|
||||
PLZ
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="postal-code"
|
||||
v-model="address.postalCode"
|
||||
type="text"
|
||||
required
|
||||
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 class="sm:col-span-5">
|
||||
<label for="city" class="block text-sm font-medium leading-6 text-gray-900">
|
||||
Ort
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<input
|
||||
id="city"
|
||||
v-model="address.city"
|
||||
type="text"
|
||||
name="city"
|
||||
required
|
||||
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="col-span-full">
|
||||
<label for="country" class="block text-sm font-medium leading-6 text-gray-900">
|
||||
Land
|
||||
</label>
|
||||
<div class="mt-2">
|
||||
<select
|
||||
id="country"
|
||||
v-model="address.country"
|
||||
required
|
||||
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:text-sm sm:leading-6"
|
||||
>
|
||||
<option>Schweiz</option>
|
||||
<option>Deutschland</option>
|
||||
<option>Österreich</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -7,14 +7,14 @@ const props = defineProps<{
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-1 flex-col">
|
||||
<div class="flex-grow p-16">
|
||||
<div class="flex h-screen flex-col">
|
||||
<div class="flex-grow scroll-smooth p-16 lg:overflow-auto">
|
||||
<ItNavigationProgress :steps="3" :current-step="props.step" />
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex justify-end space-x-2 px-6 py-4"
|
||||
class="flex flex-wrap justify-end gap-4 px-4 py-4 sm:px-6"
|
||||
:class="{ 'border border-t': $slots.footer }"
|
||||
>
|
||||
<slot name="footer"></slot>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,35 @@
|
|||
<script setup lang="ts">
|
||||
import WizardPage from "@/components/onboarding/WizardPage.vue";
|
||||
import { ref } from "vue";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import PersonalAddress from "@/components/onboarding/PersonalAddress.vue";
|
||||
import OrganisationAddress from "@/components/onboarding/OrganisationAddress.vue";
|
||||
|
||||
const user = useUserStore();
|
||||
|
||||
const address = ref({
|
||||
firstName: user.first_name,
|
||||
lastName: user.last_name,
|
||||
street: "",
|
||||
streetNumber: "",
|
||||
postalCode: "",
|
||||
city: "",
|
||||
country: "",
|
||||
});
|
||||
|
||||
const useCompanyAddress = ref(false);
|
||||
|
||||
const orgAddress = ref({
|
||||
street: "",
|
||||
streetNumber: "",
|
||||
postalCode: "",
|
||||
city: "",
|
||||
country: "",
|
||||
});
|
||||
|
||||
const executePayment = () => {
|
||||
console.log("Validate & Execute Payment");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -19,145 +49,34 @@ import WizardPage from "@/components/onboarding/WizardPage.vue";
|
|||
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>
|
||||
<PersonalAddress v-model="address" />
|
||||
|
||||
<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>
|
||||
<button
|
||||
v-if="!useCompanyAddress"
|
||||
class="underline"
|
||||
@click="useCompanyAddress = true"
|
||||
>
|
||||
Rechnungsadresse von Axa hinzufügen
|
||||
</button>
|
||||
|
||||
<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"
|
||||
/>
|
||||
<transition
|
||||
enter-active-class="transition ease-out duration-100"
|
||||
enter-from-class="transform opacity-0 scale-y-95"
|
||||
enter-to-class="transform opacity-100 scale-y-100"
|
||||
leave-active-class="transition ease-in duration-75"
|
||||
leave-from-class="transform opacity-100 scale-y-100"
|
||||
leave-to-class="transform opacity-0 scale-y-95"
|
||||
>
|
||||
<div v-if="useCompanyAddress">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3>Rechnungsaddresse von Axa</h3>
|
||||
<button class="underline" @click="useCompanyAddress = false">
|
||||
Entfernen
|
||||
</button>
|
||||
</div>
|
||||
<OrganisationAddress v-model="orgAddress" />
|
||||
</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>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
|
|
@ -168,10 +87,10 @@ import WizardPage from "@/components/onboarding/WizardPage.vue";
|
|||
<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">
|
||||
<button class="btn-blue flex items-center" @click="executePayment">
|
||||
Mit Kreditkarte bezahlen
|
||||
<it-icon-arrow-right class="it-icon ml-2 h-6 w-6" />
|
||||
</router-link>
|
||||
</button>
|
||||
</template>
|
||||
</WizardPage>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Reference in New Issue