feat: onboarding course checkout

This commit is contained in:
Reto Aebersold 2023-11-10 10:01:27 +01:00 committed by Christian Cueni
parent 607789d599
commit 9592005419
4 changed files with 352 additions and 140 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>