feat: Assistants creation flow

This commit is contained in:
iamsivin
2025-09-17 17:34:30 +05:30
parent 6858a6f867
commit 0df627d5f5
12 changed files with 1182 additions and 9 deletions
@@ -100,14 +100,14 @@ const handlePageChange = event => {
<div
v-if="!showPaywall && buttonLabel"
v-on-clickaway="() => emit('close')"
class="relative group/campaign-button"
class="relative group/captain-button"
>
<Policy :permissions="buttonPolicy">
<Button
:label="buttonLabel"
icon="i-lucide-plus"
size="sm"
class="group-hover/campaign-button:brightness-110"
class="group-hover/captain-button:brightness-110"
@click="handleButtonClick"
/>
</Policy>
@@ -3,6 +3,7 @@ import { useRouter } from 'vue-router';
import PaginationFooter from 'dashboard/components-next/pagination/PaginationFooter.vue';
import Spinner from 'dashboard/components-next/spinner/Spinner.vue';
import Breadcrumb from 'dashboard/components-next/breadcrumb/Breadcrumb.vue';
import Button from 'dashboard/components-next/button/Button.vue';
defineProps({
isFetching: {
@@ -33,9 +34,13 @@ defineProps({
type: Array,
default: () => [],
},
headerButtonLabel: {
type: String,
default: '',
},
});
const emit = defineEmits(['update:currentPage']);
const emit = defineEmits(['update:currentPage', 'click']);
const router = useRouter();
@@ -48,6 +53,10 @@ const handleBreadcrumbClick = item => {
name: item.routeName,
});
};
const onHeaderButtonClick = () => {
emit('click');
};
</script>
<template>
@@ -55,8 +64,20 @@ const handleBreadcrumbClick = item => {
class="px-6 flex flex-col w-full h-screen overflow-y-auto bg-n-background"
>
<div class="max-w-[60rem] mx-auto flex flex-col w-full h-full mb-4">
<header class="mb-7 sticky top-0 bg-n-background pt-4 z-20">
<header
class="mb-7 sticky top-0 bg-n-background pt-4 z-20 w-full flex justify-between items-center"
>
<Breadcrumb :items="breadcrumbItems" @click="handleBreadcrumbClick" />
<div class="flex gap-4 items-center">
<slot name="headerControls" />
<Button
v-if="headerButtonLabel"
class="ml-auto"
@click="onHeaderButtonClick"
>
{{ headerButtonLabel }}
</Button>
</div>
</header>
<main class="flex gap-16 w-full flex-1 pb-16">
<section
@@ -0,0 +1,40 @@
<script setup>
import Icon from 'next/icon/Icon.vue';
defineProps({
title: {
type: String,
default: '',
},
icon: {
type: String,
default: '',
},
subtitle: {
type: String,
default: '',
},
description: {
type: String,
default: '',
},
});
</script>
<template>
<div class="flex items-center justify-between gap-14 mt-3">
<div class="flex flex-col items-start gap-4">
<div
class="p-2 flex items-center gap-1.5 rounded-[10px] border border-n-weak"
>
<Icon :icon="icon" class="size-4 text-n-slate-11" />
<h3 class="text-n-slate-12 text-sm font-medium">{{ title }}</h3>
</div>
<p class="text-n-slate-12 text-lg leading-6 font-semibold">
{{ subtitle }}
</p>
<p class="text-n-slate-11 text-sm">{{ description }}</p>
</div>
<slot />
</div>
</template>
@@ -0,0 +1,58 @@
<script setup>
import { ref, reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import Dialog from 'dashboard/components-next/dialog/Dialog.vue';
import InlineInput from 'dashboard/components-next/inline-input/InlineInput.vue';
const emit = defineEmits(['confirm', 'cancel']);
const { t } = useI18n();
const dialogRef = ref(null);
const state = reactive({
name: '',
url: '',
});
const handleConfirm = () => {
emit('confirm', state);
};
const handleCancel = () => {
emit('cancel');
};
defineExpose({ dialogRef });
</script>
<template>
<Dialog
ref="dialogRef"
type="edit"
:confirm-button-label="
t('CAPTAIN.ASSISTANTS.ONBOARDING.CREATE.CREATE_BUTTON')
"
@close="handleCancel"
@confirm="handleConfirm"
>
<fieldset class="flex flex-col gap-10 py-8">
<InlineInput
v-model="state.name"
:label="t('CAPTAIN.ASSISTANTS.ONBOARDING.CREATE.NAME')"
:placeholder="
t('CAPTAIN.ASSISTANTS.ONBOARDING.CREATE.NAME_PLACEHOLDER')
"
class="flex flex-col !items-start !gap-2 [&>input]:text-base [&>label]:text-xl"
/>
<InlineInput
v-model="state.url"
:label="t('CAPTAIN.ASSISTANTS.ONBOARDING.CREATE.URL')"
:placeholder="t('CAPTAIN.ASSISTANTS.ONBOARDING.CREATE.URL_PLACEHOLDER')"
class="flex flex-col !items-start !gap-2 [&>input]:text-base [&>label]:text-xl"
/>
</fieldset>
<template #footer />
</Dialog>
</template>