feat: Contacts layout
This commit is contained in:
@@ -82,9 +82,11 @@ const inboxIcon = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CardLayout class="flex flex-row justify-between flex-1 gap-8" layout="row">
|
||||
<CardLayout layout="row">
|
||||
<template #header>
|
||||
<div class="flex flex-col items-start gap-2">
|
||||
<div
|
||||
class="flex flex-col items-start justify-between flex-1 min-w-0 gap-2"
|
||||
>
|
||||
<div class="flex justify-between gap-3 w-fit">
|
||||
<span
|
||||
class="text-base font-medium capitalize text-n-slate-12 line-clamp-1"
|
||||
|
||||
-1
@@ -27,7 +27,6 @@ defineProps({
|
||||
:message="campaign.message"
|
||||
:is-enabled="campaign.enabled"
|
||||
:status="campaign.campaign_status"
|
||||
:trigger-rules="campaign.trigger_rules"
|
||||
:sender="campaign.sender"
|
||||
:inbox="campaign.inbox"
|
||||
:scheduled-at="campaign.scheduled_at"
|
||||
|
||||
-1
@@ -27,7 +27,6 @@ defineProps({
|
||||
:message="campaign.message"
|
||||
:is-enabled="campaign.enabled"
|
||||
:status="campaign.campaign_status"
|
||||
:trigger-rules="campaign.trigger_rules"
|
||||
:sender="campaign.sender"
|
||||
:inbox="campaign.inbox"
|
||||
:scheduled-at="campaign.scheduled_at"
|
||||
|
||||
@@ -27,7 +27,6 @@ const handleDelete = campaign => emit('delete', campaign);
|
||||
:message="campaign.message"
|
||||
:is-enabled="campaign.enabled"
|
||||
:status="campaign.campaign_status"
|
||||
:trigger-rules="campaign.trigger_rules"
|
||||
:sender="campaign.sender"
|
||||
:inbox="campaign.inbox"
|
||||
:scheduled-at="campaign.scheduled_at"
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
defineProps({
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'col',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['click']);
|
||||
|
||||
const handleClick = () => {
|
||||
emit('click');
|
||||
};
|
||||
@@ -13,11 +15,19 @@ const handleClick = () => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="relative flex w-full gap-3 px-6 py-5 shadow outline-1 outline outline-n-container group/cardLayout rounded-2xl bg-n-solid-2"
|
||||
:class="props.layout === 'col' ? 'flex-col' : 'flex-row'"
|
||||
@click="handleClick"
|
||||
class="relative flex flex-col w-full shadow outline-1 outline outline-n-container group/cardLayout rounded-2xl bg-n-solid-2"
|
||||
>
|
||||
<slot name="header" />
|
||||
<slot name="footer" />
|
||||
<div
|
||||
class="flex w-full gap-3 px-6 py-5"
|
||||
:class="
|
||||
layout === 'col' ? 'flex-col' : 'flex-row justify-between items-center'
|
||||
"
|
||||
@click="handleClick"
|
||||
>
|
||||
<slot name="header" />
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
|
||||
<slot name="expanded" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
<script setup>
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
import Input from 'dashboard/components-next/input/Input.vue';
|
||||
import Icon from 'dashboard/components-next/icon/Icon.vue';
|
||||
import PaginationFooter from 'dashboard/components-next/pagination/PaginationFooter.vue';
|
||||
|
||||
defineProps({
|
||||
headerTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
buttonLabel: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
showPaginationFooter: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
currentPage: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
totalItems: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
},
|
||||
itemsPerPage: {
|
||||
type: Number,
|
||||
default: 15,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['filter', 'more', 'message', 'update:currentPage']);
|
||||
|
||||
const updateCurrentPage = page => {
|
||||
emit('update:currentPage', page);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="flex flex-col w-full h-full overflow-hidden bg-n-background">
|
||||
<header class="sticky top-0 z-10 px-6 lg:px-0">
|
||||
<div class="w-full max-w-[900px] mx-auto">
|
||||
<div class="flex items-center justify-between w-full h-20 gap-2">
|
||||
<span class="text-xl font-medium text-n-slate-12">
|
||||
{{ headerTitle }}
|
||||
</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<Input
|
||||
:placeholder="$t('CONTACTS_LAYOUT.HEADER.SEARCH_PLACEHOLDER')"
|
||||
:custom-input-class="['h-8 ltr:!pl-8 rtl:!pr-8']"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon
|
||||
icon="i-lucide-search"
|
||||
class="absolute -translate-y-1/2 text-n-slate-11 size-4 top-1/2 ltr:left-2 rtl:right-2"
|
||||
/>
|
||||
</template>
|
||||
</Input>
|
||||
</div>
|
||||
<Button
|
||||
icon="i-lucide-list-filter"
|
||||
size="sm"
|
||||
color="slate"
|
||||
@click="emit('filter')"
|
||||
/>
|
||||
<Button
|
||||
icon="i-lucide-ellipsis-vertical"
|
||||
size="sm"
|
||||
color="slate"
|
||||
@click="emit('more')"
|
||||
/>
|
||||
<Button :label="buttonLabel" size="sm" @click="emit('message')" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="flex-1 px-6 overflow-y-auto lg:px-0">
|
||||
<div class="w-full max-w-[900px] mx-auto py-4">
|
||||
<slot name="default" />
|
||||
</div>
|
||||
</main>
|
||||
<footer v-if="showPaginationFooter" class="sticky bottom-0 z-10 px-4 pb-4">
|
||||
<PaginationFooter
|
||||
:current-page="currentPage"
|
||||
:total-items="totalItems"
|
||||
:items-per-page="itemsPerPage"
|
||||
@update:current-page="updateCurrentPage"
|
||||
/>
|
||||
</footer>
|
||||
</section>
|
||||
</template>
|
||||
@@ -125,7 +125,7 @@ const handleClick = id => {
|
||||
<template>
|
||||
<CardLayout>
|
||||
<template #header>
|
||||
<div class="flex justify-between gap-1">
|
||||
<div class="flex justify-between w-full gap-1">
|
||||
<span
|
||||
class="text-base cursor-pointer hover:underline underline-offset-2 hover:text-n-blue-text text-n-slate-12 line-clamp-1"
|
||||
@click="handleClick(id)"
|
||||
@@ -161,7 +161,7 @@ const handleClick = id => {
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<div class="flex items-center justify-between w-full gap-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex items-center gap-1">
|
||||
<Thumbnail
|
||||
@@ -169,7 +169,7 @@ const handleClick = id => {
|
||||
:name="authorName"
|
||||
:src="authorThumbnailSrc"
|
||||
/>
|
||||
<span class="text-sm text-n-slate-11">
|
||||
<span class="text-sm truncate text-n-slate-11">
|
||||
{{ authorName }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -161,7 +161,7 @@ const linkButtonClasses = computed(() => {
|
||||
<Spinner v-if="isLoading" class="!w-5 !h-5 flex-shrink-0" />
|
||||
|
||||
<slot v-if="label || $slots.default" name="default">
|
||||
<span class="min-w-0 truncate">{{ label }}</span>
|
||||
<span v-if="label" class="min-w-0 truncate">{{ label }}</span>
|
||||
</slot>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user