refactor: move component and routes to dashboard
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<with-label
|
||||
:label="label"
|
||||
:name="name"
|
||||
:has-error="hasError"
|
||||
:error-message="errorMessage"
|
||||
>
|
||||
<template #label> {{ label }} <slot /> </template>
|
||||
|
||||
<input
|
||||
:id="name"
|
||||
:name="name"
|
||||
:type="type"
|
||||
autocomplete="off"
|
||||
:required="required"
|
||||
:placeholder="placeholder"
|
||||
:data-testid="dataTestid"
|
||||
:value="value"
|
||||
:class="{
|
||||
'focus:ring-red-600 ring-red-600': hasError,
|
||||
'dark:ring-slate-600 dark:focus:ring-woot-500 ring-slate-200':
|
||||
!hasError,
|
||||
'px-3 py-3': spacing === 'base',
|
||||
'px-3 py-2': spacing === 'compact',
|
||||
}"
|
||||
class="block w-full border-0 rounded-md shadow-sm outline-none appearance-none ring-1 ring-inset text-slate-900 dark:text-slate-100 placeholder:text-slate-400 focus:ring-2 focus:ring-inset focus:ring-woot-500 sm:text-sm sm:leading-6 dark:bg-slate-700"
|
||||
@input="onInput"
|
||||
@blur="$emit('blur')"
|
||||
/>
|
||||
</with-label>
|
||||
</template>
|
||||
<script>
|
||||
import WithLabel from './WithLabel.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
WithLabel,
|
||||
},
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text',
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
},
|
||||
hasError: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
errorMessage: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
dataTestid: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
spacing: {
|
||||
type: String,
|
||||
default: 'base',
|
||||
validator: value => ['base', 'compact'].includes(value),
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onInput(e) {
|
||||
this.$emit('input', e.target.value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<with-label
|
||||
:label="label"
|
||||
:name="name"
|
||||
:has-error="hasError"
|
||||
:error-message="errorMessage"
|
||||
>
|
||||
<select
|
||||
:id="id"
|
||||
:selected="value"
|
||||
:name="name"
|
||||
:class="{
|
||||
'text-slate-400': !value,
|
||||
'text-slate-900 dark:text-slate-100': value,
|
||||
}"
|
||||
class="block w-full px-3 py-2 pr-6 border-0 rounded-md shadow-sm outline-none appearance-none select-caret ring-1 ring-inset placeholder:text-slate-400 focus:ring-2 focus:ring-inset focus:ring-woot-500 sm:text-sm sm:leading-6 dark:bg-slate-700 dark:ring-slate-600 dark:focus:ring-woot-500 ring-slate-200"
|
||||
@input="onInput"
|
||||
>
|
||||
<option value="" disabled selected class="hidden">
|
||||
{{ placeholder }}
|
||||
</option>
|
||||
<slot>
|
||||
<option v-for="opt in options" :key="opt.value" :value="opt.value">
|
||||
{{ opt.label }}
|
||||
</option>
|
||||
</slot>
|
||||
</select>
|
||||
</with-label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WithLabel from './WithLabel.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
WithLabel,
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
hasError: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
errorMessage: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onInput(e) {
|
||||
this.$emit('input', e.target.value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.select-caret {
|
||||
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='32' height='24' viewBox='0 0 32 24'><polygon points='0,0 32,0 16,24' style='fill: rgb%28110, 111, 115%29'></polygon></svg>");
|
||||
background-origin: content-box;
|
||||
background-position: right -1rem center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 9px 6px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<with-label
|
||||
:label="label"
|
||||
:name="name"
|
||||
:has-error="hasError"
|
||||
:error-message="errorMessage"
|
||||
>
|
||||
<template #label> {{ label }} <slot /> </template>
|
||||
|
||||
<textarea
|
||||
:id="name"
|
||||
:name="name"
|
||||
autocomplete="off"
|
||||
:required="required"
|
||||
:placeholder="placeholder"
|
||||
:data-testid="dataTestid"
|
||||
:value="value"
|
||||
:rows="rows"
|
||||
:class="{
|
||||
'focus:ring-red-600 ring-red-600': hasError,
|
||||
'dark:ring-slate-600 dark:focus:ring-woot-500 ring-slate-200':
|
||||
!hasError,
|
||||
'px-3 py-3': spacing === 'base',
|
||||
'px-3 py-2': spacing === 'compact',
|
||||
'resize-none': !allowResize,
|
||||
}"
|
||||
class="block w-full border-0 rounded-md shadow-sm outline-none appearance-none ring-1 ring-inset text-slate-900 dark:text-slate-100 placeholder:text-slate-400 focus:ring-2 focus:ring-inset focus:ring-woot-500 sm:text-sm sm:leading-6 dark:bg-slate-700"
|
||||
@input="onInput"
|
||||
@blur="$emit('blur')"
|
||||
/>
|
||||
</with-label>
|
||||
</template>
|
||||
<script>
|
||||
import WithLabel from './WithLabel.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
WithLabel,
|
||||
},
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
},
|
||||
rows: {
|
||||
type: Number,
|
||||
default: 3,
|
||||
},
|
||||
allowResize: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
hasError: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
errorMessage: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
dataTestid: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
spacing: {
|
||||
type: String,
|
||||
default: 'base',
|
||||
validator: value => ['base', 'compact'].includes(value),
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onInput(e) {
|
||||
this.$emit('input', e.target.value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div>
|
||||
<label
|
||||
v-if="label"
|
||||
:for="name"
|
||||
class="flex justify-between text-sm font-medium leading-6 text-slate-900 dark:text-white"
|
||||
:class="{ 'text-red-500': hasError }"
|
||||
>
|
||||
<slot name="label">
|
||||
{{ label }}
|
||||
</slot>
|
||||
</label>
|
||||
<div class="mt-1">
|
||||
<slot />
|
||||
<span
|
||||
v-if="errorMessage && hasError"
|
||||
class="text-xs text-red-400 leading-2"
|
||||
>
|
||||
{{ errorMessage }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
hasError: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
errorMessage: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -8,6 +8,9 @@ import helpcenterRoutes from './helpcenter/helpcenter.routes';
|
||||
|
||||
const AppContainer = () => import('./Dashboard.vue');
|
||||
const Suspended = () => import('./suspended/Index.vue');
|
||||
const SetupProfile = () => import('./start/SetupProfile.vue');
|
||||
const SetupCompany = () => import('./start/SetupCompany.vue');
|
||||
const FoundersNote = () => import('./start/FoundersNote.vue');
|
||||
|
||||
export default {
|
||||
routes: [
|
||||
@@ -29,5 +32,20 @@ export default {
|
||||
roles: ['administrator', 'agent'],
|
||||
component: Suspended,
|
||||
},
|
||||
{
|
||||
path: frontendURL('start/setup-profile'),
|
||||
name: 'onboarding_setup_profile',
|
||||
component: SetupProfile,
|
||||
},
|
||||
{
|
||||
path: frontendURL('start/setup-company'),
|
||||
name: 'onboarding_setup_company',
|
||||
component: SetupCompany,
|
||||
},
|
||||
{
|
||||
path: frontendURL('start/founders-note'),
|
||||
name: 'onboarding_founders_note',
|
||||
component: FoundersNote,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<modal-layout
|
||||
:title="$t('ONBOARDING.FOUNDERS_NOTE.TITLE')"
|
||||
current-step="founders-note"
|
||||
>
|
||||
<template #body>
|
||||
<section class="mt-4 space-y-3 text-sm leading-relaxed">
|
||||
<p>👋 Hey {{ user.name }},</p>
|
||||
<p>
|
||||
I'm Pranav, one of the co-founders at Chatwoot. Thanks for checking
|
||||
out Chatwoot. We're eager to understand your needs and expectations.
|
||||
</p>
|
||||
<p>
|
||||
If you are facing trouble using the app or achieving your use case, we
|
||||
want to help you as quickly as possible.
|
||||
</p>
|
||||
<p>
|
||||
Feel free to schedule a call with our team. We are open to your
|
||||
feedback. Talk soon!
|
||||
</p>
|
||||
</section>
|
||||
<figure class="mt-5 text-sm leading-relaxed">
|
||||
<thumbnail
|
||||
src="https://www.chatwoot.com/images/team/pranav.jpg"
|
||||
username="Pranav"
|
||||
/>
|
||||
<p class="mt-2">Pranav, <br />Co-founder & CEO, Chatwoot</p>
|
||||
</figure>
|
||||
</template>
|
||||
<submit-button
|
||||
button-class="text-sm"
|
||||
:button-text="$t('ONBOARDING.FOUNDERS_NOTE.SUBMIT')"
|
||||
/>
|
||||
</modal-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ModalLayout from './components/ModalLayout.vue';
|
||||
import Thumbnail from '../../../../dashboard/components/widgets/Thumbnail.vue';
|
||||
import SubmitButton from '../../../components/buttons/FormSubmitButton.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ModalLayout,
|
||||
Thumbnail,
|
||||
SubmitButton,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
user: {
|
||||
name: 'Shivam',
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<modal-layout
|
||||
:title="$t('ONBOARDING.COMPANY.TITLE')"
|
||||
:body="$t('ONBOARDING.COMPANY.BODY')"
|
||||
current-step="company"
|
||||
>
|
||||
<form class="space-y-8">
|
||||
<div class="space-y-3">
|
||||
<form-input
|
||||
v-model="companyName"
|
||||
name="companyName"
|
||||
spacing="compact"
|
||||
:label="$t('ONBOARDING.COMPANY.COMPANY_NAME.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.COMPANY.COMPANY_NAME.PLACEHOLDER')"
|
||||
:error-message="$t('ONBOARDING.COMPANY.COMPANY_NAME.ERROR')"
|
||||
/>
|
||||
<form-input
|
||||
v-model="industry"
|
||||
name="industry"
|
||||
spacing="compact"
|
||||
:label="$t('ONBOARDING.COMPANY.INDUSTRY.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.COMPANY.INDUSTRY.PLACEHOLDER')"
|
||||
/>
|
||||
<form-input
|
||||
v-model="timezone"
|
||||
name="timezone"
|
||||
spacing="compact"
|
||||
:label="$t('ONBOARDING.COMPANY.TIMEZONE.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.COMPANY.TIMEZONE.PLACEHOLDER')"
|
||||
/>
|
||||
<form-select
|
||||
v-model="locale"
|
||||
name="locale"
|
||||
:label="$t('ONBOARDING.COMPANY.LOCALE.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.COMPANY.LOCALE.PLACEHOLDER')"
|
||||
>
|
||||
<option
|
||||
v-for="lang in languagesSortedByCode"
|
||||
:key="lang.iso_639_1_code"
|
||||
:value="lang.iso_639_1_code"
|
||||
>
|
||||
{{ lang.name }}
|
||||
</option>
|
||||
</form-select>
|
||||
<form-select
|
||||
v-model="companySize"
|
||||
name="companySize"
|
||||
:label="$t('ONBOARDING.COMPANY.SIZE.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.COMPANY.SIZE.PLACEHOLDER')"
|
||||
:options="companySizeOptions"
|
||||
/>
|
||||
</div>
|
||||
<submit-button
|
||||
button-class="text-sm"
|
||||
:button-text="$t('ONBOARDING.COMPANY.SUBMIT')"
|
||||
/>
|
||||
</form>
|
||||
</modal-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormInput from '../../../components/form/Input.vue';
|
||||
import FormSelect from '../../../components/form/Select.vue';
|
||||
import SubmitButton from '../../../components/buttons/FormSubmitButton.vue';
|
||||
import ModalLayout from './components/ModalLayout.vue';
|
||||
import configMixin from 'shared/mixins/configMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormInput,
|
||||
SubmitButton,
|
||||
ModalLayout,
|
||||
FormSelect,
|
||||
},
|
||||
mixins: [configMixin],
|
||||
data() {
|
||||
return {
|
||||
companyName: '',
|
||||
timezone: '',
|
||||
locale: '',
|
||||
companySize: '',
|
||||
industry: '',
|
||||
companySizeOptions: [
|
||||
{ value: '1-10', label: '1-10' },
|
||||
{ value: '11-50', label: '11-50' },
|
||||
{ value: '51-200', label: '51-200' },
|
||||
{ value: '201-500', label: '201-500' },
|
||||
{ value: '501-1000', label: '501-1000' },
|
||||
{ value: '1001-5000', label: '1001-5000' },
|
||||
{ value: '5001+', label: 'Over 5000' },
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
languagesSortedByCode() {
|
||||
const enabledLanguages = [...this.enabledLanguages];
|
||||
return enabledLanguages.sort((l1, l2) =>
|
||||
l1.iso_639_1_code.localeCompare(l2.iso_639_1_code)
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<modal-layout
|
||||
:title="$t('ONBOARDING.PROFILE.TITLE')"
|
||||
:body="$t('ONBOARDING.PROFILE.BODY')"
|
||||
current-step="profile"
|
||||
>
|
||||
<form class="mt-8 space-y-8">
|
||||
<div class="space-y-3">
|
||||
<form-input
|
||||
v-model="fullName"
|
||||
name="full_name"
|
||||
spacing="compact"
|
||||
:label="$t('ONBOARDING.PROFILE.FULL_NAME.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.PROFILE.FULL_NAME.PLACEHOLDER')"
|
||||
:error-message="$t('ONBOARDING.PROFILE.FULL_NAME.ERROR')"
|
||||
/>
|
||||
<form-input
|
||||
v-model="displayName"
|
||||
name="display_name"
|
||||
spacing="compact"
|
||||
:label="$t('ONBOARDING.PROFILE.DISPLAY_NAME.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.PROFILE.DISPLAY_NAME.PLACEHOLDER')"
|
||||
/>
|
||||
<form-input
|
||||
v-model="phoneNumber"
|
||||
name="phone_number"
|
||||
spacing="compact"
|
||||
:label="$t('ONBOARDING.PROFILE.PHONE_NUMBER.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.PROFILE.PHONE_NUMBER.PLACEHOLDER')"
|
||||
/>
|
||||
<form-text-area
|
||||
v-model="signature"
|
||||
name="signature"
|
||||
spacing="compact"
|
||||
:allow-resize="false"
|
||||
:label="$t('ONBOARDING.PROFILE.SIGNATURE.LABEL')"
|
||||
:placeholder="$t('ONBOARDING.PROFILE.SIGNATURE.PLACEHOLDER')"
|
||||
/>
|
||||
</div>
|
||||
<submit-button
|
||||
button-class="text-sm"
|
||||
:button-text="$t('ONBOARDING.PROFILE.SUBMIT')"
|
||||
/>
|
||||
</form>
|
||||
</modal-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormInput from '../../../components/form/Input.vue';
|
||||
import FormTextArea from '../../../components/form/TextArea.vue';
|
||||
import SubmitButton from '../../../components/buttons/FormSubmitButton.vue';
|
||||
import ModalLayout from './components/ModalLayout.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormInput,
|
||||
SubmitButton,
|
||||
ModalLayout,
|
||||
FormTextArea,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fullName: '',
|
||||
displayName: '',
|
||||
phoneNumber: '',
|
||||
signature: '',
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<section
|
||||
class="relative h-screen px-8 py-20 dark:text-white bg-woot-25 dark:bg-slate-900"
|
||||
>
|
||||
<img
|
||||
id="bg-grad"
|
||||
src="/onboarding/bg-gradient.png"
|
||||
class="absolute inset-0 w-full opacity-50 dark:mix-blend-color"
|
||||
/>
|
||||
<div class="relative max-w-lg mx-auto">
|
||||
<div
|
||||
id="steps"
|
||||
class="rounded-md w-48 -left-52 dark:shadow-[#000] p-1 border shadow-sm border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 absolute grid gap-1"
|
||||
>
|
||||
<h6
|
||||
class="px-2 pt-1 font-bold tracking-widest uppercase text-xxs text-slate-500"
|
||||
>
|
||||
Get Started
|
||||
</h6>
|
||||
<modal-step
|
||||
v-for="(step, index) in steps"
|
||||
:key="step.name"
|
||||
v-bind="step"
|
||||
:step-number="index + 1"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
id="modal-body"
|
||||
class="dark:shadow-[#000] rounded-md mx-auto p-9 border shadow border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900"
|
||||
>
|
||||
<h2 class="text-lg font-bold tracking-tight">
|
||||
<slot name="title">
|
||||
{{ title }}
|
||||
</slot>
|
||||
</h2>
|
||||
<slot name="body">
|
||||
<p class="mt-2 text-sm dark:text-slate-200">
|
||||
{{ body }}
|
||||
</p>
|
||||
</slot>
|
||||
<div class="mt-8">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ModalStep from './ModalStep.vue';
|
||||
|
||||
const UISteps = [
|
||||
{
|
||||
name: 'profile',
|
||||
title: 'Setup Profile',
|
||||
isActive: false,
|
||||
isComplete: false,
|
||||
},
|
||||
{
|
||||
name: 'company',
|
||||
title: 'Setup Company',
|
||||
isActive: false,
|
||||
isComplete: false,
|
||||
},
|
||||
{
|
||||
name: 'invite',
|
||||
title: 'Invite your team',
|
||||
isActive: false,
|
||||
isComplete: false,
|
||||
},
|
||||
{
|
||||
name: 'founders-note',
|
||||
title: "Founder's Note",
|
||||
hidden: true,
|
||||
isActive: false,
|
||||
isComplete: false,
|
||||
},
|
||||
];
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ModalStep,
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
body: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
currentStep: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
steps() {
|
||||
let foundCurrentStep = false;
|
||||
|
||||
return UISteps.map(step => {
|
||||
if (step.name === this.currentStep) {
|
||||
foundCurrentStep = true;
|
||||
}
|
||||
|
||||
return {
|
||||
...step,
|
||||
isActive: step.name === this.currentStep,
|
||||
isComplete: !foundCurrentStep,
|
||||
};
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="!hidden"
|
||||
class="flex items-center gap-2 p-2 text-sm rounded"
|
||||
:class="{
|
||||
'text-slate-800 dark:text-slate-100 bg-slate-50 dark:bg-slate-800':
|
||||
isActive,
|
||||
'opacity-50': !isActive && !isComplete,
|
||||
hidden: hidden,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="grid w-4 h-4 font-bold rounded-full text-xxs place-content-center"
|
||||
:class="{
|
||||
'bg-slate-200 dark:bg-slate-600': !isComplete,
|
||||
'bg-green-500': isComplete,
|
||||
}"
|
||||
>
|
||||
<fluent-icon
|
||||
v-if="isComplete"
|
||||
size="13"
|
||||
class="text-white"
|
||||
icon="checkmark"
|
||||
/>
|
||||
<template v-else>
|
||||
{{ stepNumber }}
|
||||
</template>
|
||||
</div>
|
||||
<span
|
||||
:class="{
|
||||
'line-through': isComplete,
|
||||
}"
|
||||
>
|
||||
{{ title }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ModalStep',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
stepNumber: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
hidden: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isComplete: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user