feat: Contacts layout

This commit is contained in:
iamsivin
2024-11-04 15:14:01 +05:30
parent 8cdbdaaa07
commit a7bf762bcd
8 changed files with 118 additions and 15 deletions
@@ -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"
@@ -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 @@ 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>