fix: added steps with icon in help modal
This commit is contained in:
parent
56c3692a04
commit
b5add306c3
@ -9,7 +9,9 @@
|
||||
<div class="text-ink-gray-9 font-medium">
|
||||
{{ __('Gettings started') }}
|
||||
</div>
|
||||
<div class="text-ink-gray-7">{{ __('4/10 steps') }}</div>
|
||||
<div class="text-ink-gray-7">
|
||||
{{ __('{0}/{1} steps', [stepsCompleted, totalSteps]) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
@ -21,6 +23,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import StepsIcon from '@/components/Icons/StepsIcon.vue'
|
||||
import { useOnboarding } from '@/composables/onboarding'
|
||||
|
||||
const props = defineProps({
|
||||
isSidebarCollapsed: {
|
||||
@ -30,4 +33,6 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const emit = defineEmits(['completeNow'])
|
||||
|
||||
const { stepsCompleted, totalSteps } = useOnboarding()
|
||||
</script>
|
||||
|
||||
16
frontend/src/components/Icons/ConvertIcon.vue
Normal file
16
frontend/src/components/Icons/ConvertIcon.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8.71639 1.68847C7.20728 1.49315 5.6781 1.84427 4.40534 2.67832C3.50159 3.27056 2.7695 4.07854 2.26943 5.02055C2.13995 5.26445 2.23271 5.56714 2.47662 5.69662C2.72052 5.8261 3.02321 5.73334 3.15269 5.48943C3.57431 4.69521 4.19153 4.01402 4.95345 3.51473C6.02649 2.81155 7.31573 2.51553 8.58803 2.6802C9.86034 2.84487 11.0317 3.45936 11.8904 4.41255C12.5455 5.13978 12.9856 6.02752 13.1713 6.97711L12.0682 6.38995C11.8245 6.2602 11.5217 6.35263 11.3919 6.59639C11.2622 6.84015 11.3546 7.14294 11.5984 7.27269L13.8052 8.44735C14.049 8.5771 14.3518 8.48468 14.4815 8.24091L15.6562 6.03407C15.7859 5.79031 15.6935 5.48752 15.4497 5.35777C15.206 5.22802 14.9032 5.32044 14.7734 5.5642L14.1448 6.74523C13.92 5.63395 13.4012 4.59563 12.6334 3.74325C11.6149 2.61265 10.2255 1.88379 8.71639 1.68847ZM7.51332 14.3501C9.0288 14.4875 10.5434 14.0781 11.7833 13.1959C12.5865 12.6244 13.2401 11.8789 13.7005 11.0233C13.8314 10.7801 13.7404 10.4769 13.4972 10.3461C13.254 10.2152 12.9508 10.3062 12.82 10.5494C12.4317 11.2708 11.8807 11.8993 11.2035 12.3811C10.1582 13.1249 8.88128 13.47 7.6036 13.3542C6.32592 13.2384 5.13186 12.6692 4.23732 11.7496C3.50475 10.9965 3.01266 10.0491 2.81428 9.02749L3.95178 9.68895C4.1905 9.82776 4.49655 9.74677 4.63536 9.50805C4.77417 9.26934 4.69318 8.96329 4.45447 8.82448L2.29329 7.56777C2.05458 7.42895 1.74853 7.50994 1.60972 7.74866L0.353003 9.90983C0.214191 10.1485 0.295179 10.4546 0.533896 10.5934C0.772613 10.7322 1.07866 10.6512 1.21747 10.4125L1.85313 9.31938C2.10072 10.4924 2.67584 11.5786 3.52051 12.4469C4.58154 13.5377 5.99784 14.2128 7.51332 14.3501Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
16
frontend/src/components/Icons/InviteIcon.vue
Normal file
16
frontend/src/components/Icons/InviteIcon.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M13.5 0C13.7761 0 14 0.223858 14 0.5V2H15.5C15.7761 2 16 2.22386 16 2.5C16 2.77614 15.7761 3 15.5 3H14V4.5C14 4.77614 13.7761 5 13.5 5C13.2239 5 13 4.77614 13 4.5V3H11.5C11.2239 3 11 2.77614 11 2.5C11 2.22386 11.2239 2 11.5 2H13V0.5C13 0.223858 13.2239 0 13.5 0ZM7.9998 2C4.6862 2 2 4.6862 2 7.9998C2 9.49431 2.54643 10.8612 3.45041 11.9116C4.18218 10.8499 5.63104 9.51974 7.99595 9.50011L8.0001 9.50008C9.89267 9.50009 11.5613 10.456 12.5506 11.91C13.4537 10.8598 13.9996 9.49355 13.9996 7.9998C13.9996 7.72366 14.2235 7.4998 14.4996 7.4998C14.7757 7.4998 14.9996 7.72366 14.9996 7.9998C14.9996 11.8657 11.8657 14.9996 7.9998 14.9996C4.13392 14.9996 1 11.8657 1 7.9998C1 4.13392 4.13392 1 7.9998 1C8.27594 1 8.4998 1.22386 8.4998 1.5C8.4998 1.77614 8.27594 2 7.9998 2ZM11.8227 12.6242C11.0281 11.3487 9.61378 10.5008 8.00216 10.5001C5.94811 10.518 4.73746 11.7366 4.17676 12.6241C5.21484 13.4833 6.54702 13.9996 7.9998 13.9996C9.45251 13.9996 10.7846 13.4833 11.8227 12.6242ZM8 4.5C7.0335 4.5 6.25 5.2835 6.25 6.25C6.25 7.2165 7.0335 8 8 8C8.9665 8 9.75 7.2165 9.75 6.25C9.75 5.2835 8.9665 4.5 8 4.5ZM5.25 6.25C5.25 4.73122 6.48122 3.5 8 3.5C9.51878 3.5 10.75 4.73122 10.75 6.25C10.75 7.76878 9.51878 9 8 9C6.48122 9 5.25 7.76878 5.25 6.25Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
@ -1,20 +1,64 @@
|
||||
<template>
|
||||
<div
|
||||
v-show="show"
|
||||
class="fixed z-20 w-80 h-[calc(100%_-_80px)] text-ink-gray-9 m-5 mt-[62px] p-3 flex gap-2 flex-col rounded-lg bg-surface-modal shadow-2xl"
|
||||
class="fixed z-20 w-80 h-[calc(100%_-_80px)] text-ink-gray-9 m-5 mt-[62px] p-3 flex gap-2 flex-col justify-between rounded-lg bg-surface-modal shadow-2xl"
|
||||
:class="[minimize ? 'right-0 top-[calc(100%_-_110px)]' : 'right-0']"
|
||||
@click.stop
|
||||
>
|
||||
<div class="flex justify-between">
|
||||
<div></div>
|
||||
<div>
|
||||
<Button @click="minimize = !minimize" variant="ghost">
|
||||
<MaximizeIcon v-if="minimize" class="h-3.5 w-3.5" />
|
||||
<MinimizeIcon v-else class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
<Button variant="ghost" @click="show = false">
|
||||
<FeatherIcon name="x" class="h-3.5" />
|
||||
</Button>
|
||||
<div class="overflow-hidden flex flex-col gap-4">
|
||||
<div class="flex justify-between">
|
||||
<div></div>
|
||||
<div>
|
||||
<Button @click="minimize = !minimize" variant="ghost">
|
||||
<MaximizeIcon v-if="minimize" class="h-3.5 w-3.5" />
|
||||
<MinimizeIcon v-else class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
<Button variant="ghost" @click="show = false">
|
||||
<FeatherIcon name="x" class="h-3.5" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center items-center gap-1 mb-3">
|
||||
<CRMLogo class="size-10 shrink-0 rounded mb-4" />
|
||||
<div class="text-base font-medium">
|
||||
{{ __('Welcome to Frappe CRM') }}
|
||||
</div>
|
||||
<div class="text-p-base font-normal">
|
||||
{{ __('{0}/{1} steps completed', [stepsCompleted, totalSteps]) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2.5 overflow-hidden">
|
||||
<div class="flex justify-between items-center py-0.5">
|
||||
<div class="text-base font-medium">{{ __('Getting started') }}</div>
|
||||
<Badge
|
||||
:label="__('{0}% completed', [completedPercentage])"
|
||||
theme="orange"
|
||||
size="lg"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1.5 overflow-y-auto">
|
||||
<div
|
||||
v-for="step in steps"
|
||||
:key="step.title"
|
||||
class="w-full flex gap-2 items-center hover:bg-surface-gray-1 rounded px-2 py-1.5 cursor-pointer"
|
||||
:class="[
|
||||
step.completed
|
||||
? 'text-ink-gray-5 line-through'
|
||||
: 'text-ink-gray-8',
|
||||
]"
|
||||
>
|
||||
<component :is="step.icon" class="h-4" />
|
||||
<div class="text-base">{{ step.title }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<div
|
||||
class="w-full flex gap-2 items-center hover:bg-surface-gray-1 text-ink-gray-8 rounded px-2 py-1.5 cursor-pointer"
|
||||
>
|
||||
<HelpIcon class="h-4" />
|
||||
<div class="text-base">{{ __('Help centre') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -22,6 +66,9 @@
|
||||
<script setup>
|
||||
import MinimizeIcon from '@/components/Icons/MinimizeIcon.vue'
|
||||
import MaximizeIcon from '@/components/Icons/MaximizeIcon.vue'
|
||||
import HelpIcon from '@/components/Icons/HelpIcon.vue'
|
||||
import CRMLogo from '@/components/Icons/CRMLogo.vue'
|
||||
import { useOnboarding } from '@/composables/onboarding'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
@ -30,4 +77,7 @@ const props = defineProps({
|
||||
|
||||
const show = defineModel()
|
||||
const minimize = ref(false)
|
||||
|
||||
const { steps, stepsCompleted, totalSteps, completedPercentage } =
|
||||
useOnboarding()
|
||||
</script>
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
import WhatsAppIcon from '@/components/Icons/WhatsAppIcon.vue'
|
||||
import ERPNextIcon from '@/components/Icons/ERPNextIcon.vue'
|
||||
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||
import InviteIcon from '@/components/Icons/InviteIcon.vue'
|
||||
import GeneralSettings from '@/components/Settings/GeneralSettings.vue'
|
||||
import InviteMemberPage from '@/components/Settings/InviteMemberPage.vue'
|
||||
import ProfileSettings from '@/components/Settings/ProfileSettings.vue'
|
||||
@ -96,7 +97,7 @@ const tabs = computed(() => {
|
||||
},
|
||||
{
|
||||
label: __('Invite Members'),
|
||||
icon: 'user-plus',
|
||||
icon: InviteIcon,
|
||||
component: markRaw(InviteMemberPage),
|
||||
condition: () => isManager(),
|
||||
},
|
||||
|
||||
80
frontend/src/composables/onboarding.js
Normal file
80
frontend/src/composables/onboarding.js
Normal file
@ -0,0 +1,80 @@
|
||||
import LeadsIcon from '@/components/Icons/LeadsIcon.vue'
|
||||
import InviteIcon from '@/components/Icons/InviteIcon.vue'
|
||||
import ConvertIcon from '@/components/Icons/ConvertIcon.vue'
|
||||
import NoteIcon from '@/components/Icons/NoteIcon.vue'
|
||||
import CommentIcon from '@/components/Icons/CommentIcon.vue'
|
||||
import EmailIcon from '@/components/Icons/EmailIcon.vue'
|
||||
import TaskIcon from '@/components/Icons/TaskIcon.vue'
|
||||
import StepsIcon from '@/components/Icons/StepsIcon.vue'
|
||||
import { ref, reactive, computed, markRaw } from 'vue'
|
||||
|
||||
const steps = reactive([
|
||||
{
|
||||
title: 'Create your first lead',
|
||||
icon: markRaw(LeadsIcon),
|
||||
completed: true,
|
||||
},
|
||||
{
|
||||
title: 'Invite your team',
|
||||
icon: markRaw(InviteIcon),
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
title: 'Convert lead to deal',
|
||||
icon: markRaw(ConvertIcon),
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
title: 'Create your first note',
|
||||
icon: markRaw(NoteIcon),
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
title: 'Create your first task',
|
||||
icon: markRaw(TaskIcon),
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
title: 'Add your first comment',
|
||||
icon: markRaw(CommentIcon),
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
title: 'Send email',
|
||||
icon: markRaw(EmailIcon),
|
||||
completed: false,
|
||||
},
|
||||
{
|
||||
title: 'Change deal status',
|
||||
icon: markRaw(StepsIcon),
|
||||
completed: false,
|
||||
},
|
||||
])
|
||||
|
||||
const stepsCompleted = computed(
|
||||
() => steps.filter((step) => step.completed).length,
|
||||
)
|
||||
const totalSteps = ref(steps.length)
|
||||
|
||||
const completedPercentage = computed(() =>
|
||||
Math.floor((stepsCompleted.value / totalSteps.value) * 100),
|
||||
)
|
||||
|
||||
export function useOnboarding() {
|
||||
const incrementStep = () => {
|
||||
stepsCompleted.value++
|
||||
}
|
||||
|
||||
const decrementStep = () => {
|
||||
stepsCompleted.value--
|
||||
}
|
||||
|
||||
return {
|
||||
steps,
|
||||
stepsCompleted,
|
||||
totalSteps,
|
||||
completedPercentage,
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user