Add new samples for landing

pull/5880/head
Cagatay Civici 2024-06-12 00:33:37 +03:00
parent 3ceabc2ffa
commit 65e817324f
8 changed files with 3056 additions and 253 deletions

View File

@ -1,9 +1,8 @@
<template> <template>
<section class="landing-hero py-20 px-8 lg:px-20"> <section class="landing-hero py-20 px-8 lg:px-20">
<div class="flex flex-wrap"> <div class="flex flex-col items-center">
<div class="w-full xl:w-6/12 flex flex-col justify-center lg:pr-20 items-center xl:items-stretch">
<h1 class="text-5xl font-bold text-center xl:text-left leading-tight">The Next-Gen UI Suite for <span class="font-bold text-primary">Vue.js</span></h1> <h1 class="text-5xl font-bold text-center xl:text-left leading-tight">The Next-Gen UI Suite for <span class="font-bold text-primary">Vue.js</span></h1>
<p class="xl:text-left text-center px-0 mt-0 mb-8 text-surface-500 dark:text-surface-400 font-medium text-xl leading-relaxed"> <p class="text-center mt-0 mb-8 text-surface-500 dark:text-surface-400 font-medium text-xl leading-relaxed">
Enhance your web applications with PrimeVue's comprehensive suite of customizable, feature-rich UI components. With PrimeVue, turning your development vision into reality has never been easier. Enhance your web applications with PrimeVue's comprehensive suite of customizable, feature-rich UI components. With PrimeVue, turning your development vision into reality has never been easier.
</p> </p>
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
@ -17,265 +16,184 @@
</a> </a>
</div> </div>
</div> </div>
<div class="w-full xl:w-6/12 pt-16 xl:pt-0 hidden md:block"> <div class="w-full flex lg:hidden items-center justify-center mt-16 mb-4">
<div class="flex"> <SelectButton v-model="selectedSampleOption" :options="sampleOptions" optionLabel="title" class="dark:border dark:border-white/20">
<div class="flex flex-col w-6/12 gap-8 pt-20 pr-4">
<div class="box p-6 animate-fadein animate-duration-500">
<div class="flex gap-2">
<div class="w-24 shrink-0">
<span class="text-surface-500 dark:text-surface-400 font-medium block mb-4">Amount</span>
<InputNumber v-model="value1" mode="currency" currency="USD" locale="en-US" class="w-full" inputClass="w-full" />
</div>
<div class="flex-auto" style="width: 1%">
<span class="text-surface-500 dark:text-surface-400 font-semibold block mb-4">Beneficiary</span>
<Select v-model="user" :options="users" optionLabel="name" placeholder="Select a User" class="w-full">
<template #option="slotProps"> <template #option="slotProps">
<div class="flex items-center gap-2"> <i :class="slotProps.option.icon"></i>
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" width="28" /> <div class="hidden sm:flex flex-1 text-sm font-medium leading-5">{{ slotProps.option.title }}</div>
<span>{{ slotProps.option.name }}</span>
</div>
</template> </template>
</Select> </SelectButton>
</div> </div>
<div class="bg-surface-0 border border-black/10 dark:border-white/20 dark:bg-surface-950 w-full rounded-3xl p-0 flex lg:hidden items-start gap-6 overflow-hidden">
<img :src="selectedSampleOption.src + (isDark() ? '-dark.jpg' : '.jpg')" class="w-full" alt="Hero" />
</div> </div>
<span class="text-surface-500 dark:text-surface-400 font-medium block mt-8 mb-4">Account</span> <div class="bg-surface-0 border border-black/10 dark:border-white/20 dark:bg-surface-950 w-full h-[85vh] max-h-[1040px] rounded-3xl p-6 hidden lg:flex lg:mt-20 items-start gap-6 overflow-hidden">
<div class="flex flex-wrap gap-4"> <div :class="isSlimMenu ? 'w-auto' : 'w-72'" class="rounded-2xl p-5 bg-surface-50 dark:bg-surface-900 h-full flex flex-col justify-between">
<div class="flex items-center"> <div :class="isSlimMenu ? 'w-12 flex flex-col items-center' : 'w-auto'">
<RadioButton v-model="radioValue" inputId="category1" value="S" name="radiovalue" @change="setCategory('S')" /> <div class="flex items-center gap-3">
<label for="category1" class="ml-2 font-medium">Savings</label> <div class="w-11 h-11">
</div> <span
<div class="flex items-center"> class="bg-surface-950 dark:bg-surface-0 rounded-xl flex items-center justify-center p-2 drop-shadow-[0px_2px_0px_var(--p-surface-700)] dark:drop-shadow-[0px_2px_0px_var(--p-surface-100)] shadow-[0px_0px_3px_0px_rgba(188, 190, 195, 0.64)_inset]"
<RadioButton v-model="radioValue" inputId="category2" value="C" name="radiovalue" @change="setCategory('C')" /> >
<label for="category2" class="ml-2 font-medium">Checking</label> <svg width="20" height="24" viewBox="0 0 20 24" fill="none" xmlns="http://www.w3.org/2000/svg">
</div> <path d="M14.65 11.0645L13.1283 10.7253L14.3119 12.4216V17.6803L18.3698 14.2876V8.52002L16.5099 9.19856L14.65 11.0645Z" class="fill-surface-0 dark:fill-surface-950" />
</div> <path d="M5.18078 11.0645L6.70251 10.7253L5.51894 12.4216V17.6803L1.46098 14.2876V8.52002L3.32088 9.19856L5.18078 11.0645Z" class="fill-surface-0 dark:fill-surface-950" />
<span class="text-surface-500 dark:text-surface-400 font-medium block mt-8 mb-4">Date</span> <path
<DatePicker v-model="dateValue" :showWeek="true" class="w-full" showIcon iconDisplay="input" /> fill-rule="evenodd"
</div> clip-rule="evenodd"
<div class="box p-6 animate-fadein animate-duration-500"> d="M6.02649 12.7634L7.37914 10.7278L8.22455 11.2367H11.6062L12.4516 10.7278L13.8042 12.7634V20.397L12.7898 21.9237L11.6062 23.1111H8.22455L7.04098 21.9237L6.02649 20.397V12.7634Z"
<Chart type="line" :data="chartData" :options="chartOptions" /> class="fill-surface-0 dark:fill-surface-950"
</div>
<div class="box p-6 animate-fadein animate-duration-500">
<div class="flex items-center">
<Chip label="Vue" class="mr-2 font-medium" />
<Chip label="Typescript" class="mr-2 font-medium" />
<ToggleSwitch v-model="switchValue" class="ml-auto"></ToggleSwitch>
</div>
<div class="mt-8 flex justify-center">
<SelectButton v-model="selectButtonValue" :options="selectButtonOptions" optionLabel="name" />
</div>
<div class="mt-8 pt-1 pb-2">
<Slider v-model="rangeValues" range class="w-full" />
</div>
</div>
</div>
<div class="flex flex-col w-6/12 gap-8 pl-4">
<div class="box p-6 animate-fadein animate-duration-500">
<div class="mb-6 w-full text-center p-8" style="border-radius: '10px'">
<img src="https://primefaces.org/cdn/primevue/images/landing/air-jordan-noir.png" alt="Watch" class="w-40" />
</div>
<div class="flex items-center mb-6">
<div class="flex flex-col">
<span class="block font-semibold mb-1">Sneaker</span>
<span class="text-surface-500 dark:text-surface-400 text-sm">Premium Quality</span>
</div>
<span class="font-medium text-xl ml-auto">$990</span>
</div>
<Button label="Add to Cart" icon="pi pi-shopping-cart" severity="secondary" class="w-full"></Button>
</div>
<div class="box p-6 animate-fadein animate-duration-500">
<ul class="list-none p-0 m-0">
<li class="flex items-center mb-4">
<span class="mr-4">
<Avatar label="AW" class="w-12 h-12" />
</span>
<div class="flex flex-col">
<span class="font-bold mb-1">Amanda Williams</span>
<span class="text-surface-500 dark:text-surface-400 text-sm">Administrator</span>
</div>
</li>
<li class="flex">
<a class="flex items-center p-4 rounded w-full hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors duration-150 cursor-pointer" style="border-radius: '10px'">
<i class="pi pi-home text-xl mr-4"></i>
<span class="flex flex-col">
<span class="font-bold mb-1">Dashboard</span>
<span class="m-0 text-surface-500 dark:text-surface-400 text-sm">Control Panel</span>
</span>
</a>
</li>
<li class="flex">
<a class="flex items-center p-4 rounded w-full hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors duration-150 cursor-pointer" style="border-radius: '10px'">
<i class="pi pi-envelope text-xl mr-4"></i>
<span class="flex flex-col">
<span class="font-bold mb-1">Inbox</span>
<span class="m-0 text-surface-500 dark:text-surface-400 text-sm">View Messages</span>
</span>
<Badge value="3" class="ml-auto"></Badge>
</a>
</li>
</ul>
</div>
<div class="box p-6 animate-fadein animate-duration-500">
<div class="flex justify-between items-center mb-8">
<span class="inline-flex items-center">
<Checkbox id="cbox" v-model="checked" :binary="true" />
<label for="cbox" class="ml-2">Confirm</label>
</span>
<SplitButton
label="Save"
icon="pi pi-plus"
:model="splitButtonItems"
outlined
:pt="{
button: {
root: 'p-2'
},
menuButton: {
width: 'auto',
root: 'p-2'
},
menu: {
root: {
style: 'width: 10rem; min-width: auto'
},
action: 'p-2'
}
}"
/> />
<path d="M14.311 20.9058L16.5091 18.7005V16.4952L14.311 18.3612V20.9058Z" class="fill-surface-0 dark:fill-surface-950" />
<path d="M5.51868 20.9058L3.32062 18.7005V16.4952L5.51868 18.3612V20.9058Z" class="fill-surface-0 dark:fill-surface-950" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M9.578 0.888672H7.7177L6.36505 4.11174L8.56311 10.5579H11.4375L13.4665 4.11174L12.1138 0.888672H10.2543V10.5578H9.578V0.888672Z"
class="fill-surface-0 dark:fill-surface-950"
/>
<path d="M8.56283 10.5575L1.29232 7.84329L0.277832 3.60242L6.53385 4.11132L8.73191 10.5575H8.56283Z" class="fill-surface-0 dark:fill-surface-950" />
<path d="M11.4372 10.5575L18.7077 7.84329L19.7222 3.60242L13.2971 4.11132L11.2681 10.5575H11.4372Z" class="fill-surface-0 dark:fill-surface-950" />
<path d="M13.8041 3.60283L17.3548 3.26356L14.9876 0.888672H12.6205L13.8041 3.60283Z" class="fill-surface-0 dark:fill-surface-950" />
<path d="M6.02676 3.60283L2.47604 3.26356L4.84318 0.888672H7.21033L6.02676 3.60283Z" class="fill-surface-0 dark:fill-surface-950" />
</svg>
</span>
</div> </div>
<TabMenu v-model:activeIndex="activeTabIndex" :model="items" /> <div :class="isSlimMenu ? 'hidden' : 'block'" class="text-surface-950 dark:text-surface-0 font-medium text-3xl">Prime</div>
</div>
<div class="mt-10 flex flex-col gap-2">
<div
v-for="(navItem, index) in sampleAppsSidebarNavs"
:key="index"
v-tooltip="isSlimMenu ? navItem.title : null"
@click="setSelectedSampleAppsSidebarNav(navItem.title)"
class="px-4 py-1 flex items-center gap-1 cursor-pointer text-base rounded-lg transition-all select-none"
:class="[
{
'w-12 justify-center py-4': isSlimMenu,
'w-full': !isSlimMenu
},
{ 'text-muted-color hover:bg-emphasis bg-transparent': selectedSampleAppsSidebarNav !== navItem.title, 'text-primary-contrast bg-primary hover:bg-primary-emphasis': selectedSampleAppsSidebarNav === navItem.title }
]"
>
<i :class="navItem.icon"></i>
<span :class="isSlimMenu ? 'hidden' : 'font-medium leading-8'"></span>
<span :class="isSlimMenu ? 'hidden' : 'font-medium leading-none'">{{ navItem.title }}</span>
</div>
</div>
</div>
<div :class="isSlimMenu ? 'w-12 flex flex-col items-center' : 'w-auto'">
<div class="mt-10 flex flex-col gap-2">
<div
v-tooltip="isSlimMenu ? 'Expanded Mode' : null"
class="px-4 py-1 flex items-center gap-1 cursor-pointer text-base rounded-lg transition-all select-none text-muted-color hover:bg-emphasis"
:class="[
{
'w-12 justify-center py-4': isSlimMenu,
'w-full': !isSlimMenu
}
]"
>
<a @click="toggleSlimMenu" class="cursor-pointer block p-0 m-0 leading-none">
<i :class="isSlimMenu ? 'pi pi-window-maximize' : 'pi pi-window-minimize'"></i>
<span :class="isSlimMenu ? 'hidden' : 'font-medium leading-8'"></span>
<span :class="isSlimMenu ? 'hidden' : 'font-medium leading-none'"> Slim Mode</span>
</a>
</div>
<div
v-for="(navItem, index) in sampleAppsSidebarNavsMore"
:key="index"
v-tooltip="isSlimMenu ? navItem.title : null"
class="px-4 py-1 flex items-center gap-1 cursor-pointer text-base rounded-lg transition-all select-none"
:class="[
{
'w-12 justify-center py-4': isSlimMenu,
'w-full': !isSlimMenu
},
{ 'text-muted-color hover:bg-emphasis bg-transparent': selectedSampleAppsSidebarNav !== navItem.title, 'text-primary-contrast bg-primary hover:bg-primary-emphasis ': selectedSampleAppsSidebarNav === navItem.title }
]"
>
<i :class="navItem.icon"></i>
<span :class="isSlimMenu ? 'hidden' : 'font-medium leading-8'"></span>
<span :class="isSlimMenu ? 'hidden' : 'font-medium leading-none'">{{ navItem.title }}</span>
</div>
</div>
<Divider />
<div :class="isSlimMenu ? 'justify-center' : ' gap-3'" class="flex items-center">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/main-avatar.png" size="large" shape="circle" class="shrink-0" />
<div>
<div :class="isSlimMenu ? 'hidden' : 'text-base font-medium text-color leading-5'">Robin Jonas</div>
<div :class="isSlimMenu ? 'hidden' : 'text-sm text-muted-color mt-1'">hi@robin.xyz</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<OverviewApp v-if="selectedSampleAppsSidebarNav === 'Overview'" />
<ChatApp v-if="selectedSampleAppsSidebarNav === 'Chat'" />
<MoviesApp v-if="selectedSampleAppsSidebarNav === 'Movies'" />
<CardsApp v-if="selectedSampleAppsSidebarNav === 'Cards'" />
<InboxApp v-if="selectedSampleAppsSidebarNav === 'Inbox'" />
<CustomersApp v-if="selectedSampleAppsSidebarNav === 'Customers'" />
</div> </div>
</section> </section>
</template> </template>
<script> <script>
import EventBus from '@/layouts/AppEventBus';
import { NodeService } from '@/service/NodeService';
export default { export default {
redrawListener: null,
data() { data() {
return { return {
value1: 24, sampleAppsSidebarNavs: [
category: 'C', { icon: 'pi pi-home', title: 'Overview' },
chartData: {}, { icon: 'pi pi-comment', title: 'Chat' },
chartOptions: {}, { icon: 'pi pi-inbox', title: 'Inbox' },
pbValue1: 15, { icon: 'pi pi-th-large', title: 'Cards' },
pbValue2: 85, { icon: 'pi pi-user', title: 'Customers' },
pbValue3: 50, { icon: 'pi pi-video', title: 'Movies' }
pbValue4: 75,
pbValue5: 60,
activeTabIndex: 0,
radioValue: 'S',
nodes: null,
switchValue: true,
selectButtonValue: { name: 'Styled', value: 1 },
dateValue: null,
rangeValues: [20, 80],
checked: false,
splitButtonItems: [
{
label: 'Update',
icon: 'pi pi-refresh'
},
{
label: 'Delete',
icon: 'pi pi-times'
}
], ],
items: [ sampleAppsSidebarNavsMore: [
{ label: 'Home', icon: 'pi pi-fw pi-home' }, { icon: 'pi pi-flag', title: 'Support' },
{ label: 'Inbox', icon: 'pi pi-fw pi-inbox' } { icon: 'pi pi-cog', title: 'Settings' }
], ],
selectButtonOptions: [ selectedSampleAppsSidebarNav: 'Overview',
{ name: 'Styled', value: 1 }, isSlimMenu: false,
{ name: 'Unstyled', value: 2 } isSlimMenuSelected: false,
sampleOptions: [
{ icon: 'pi pi-home', title: 'Overview', src: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/sampleshots/overview' },
{ icon: 'pi pi-comment', title: 'Chat', src: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/sampleshots/chat' },
{ icon: 'pi pi-inbox', title: 'Inbox', src: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/sampleshots/mail' },
{ icon: 'pi pi-th-large', title: 'Cards', src: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/sampleshots/cards' },
{ icon: 'pi pi-user', title: 'Customers', src: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/sampleshots/customers' },
{ icon: 'pi pi-video', title: 'Movies', src: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/sampleshots/movies' }
], ],
user: null, selectedSampleOption: { icon: 'pi pi-home', title: 'Overview', src: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/sampleshots/overview' }
users: [
{ name: 'Amy Elsner', image: 'amyelsner.png' },
{ name: 'Bernardo Dominic', image: 'bernardodominic.png' },
{ name: 'Onyama Limba', image: 'onyamalimba.png' }
]
}; };
}, },
beforeUnmount() { beforeUnmount() {
EventBus.off('dark-mode-toggle-complete', this.redrawListener); window.removeEventListener('resize', this.handleResize);
EventBus.off('theme-palette-change', this.redrawListener);
}, },
mounted() { mounted() {
this.chartData = this.setChartData(); window.addEventListener('resize', this.handleResize);
this.chartOptions = this.setChartOptions(); this.handleResize();
this.redrawListener = () => {
this.chartData = this.setChartData();
this.chartOptions = this.setChartOptions();
};
EventBus.on('dark-mode-toggle-complete', this.redrawListener);
EventBus.on('theme-palette-change', this.redrawListener);
NodeService.getTreeNodes().then((data) => (this.nodes = data));
}, },
methods: { methods: {
setCategory(category) { setSelectedSampleAppsSidebarNav(title) {
this.category = category; this.selectedSampleAppsSidebarNav = title;
}, },
setChartData() { isDark() {
const documentStyle = getComputedStyle(document.documentElement); return this.$appState.darkTheme;
const primaryColor = documentStyle.getPropertyValue('--primary-color');
return {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [
{
label: 'Annual Income',
data: [40, 59, 40, 50, 56],
fill: true,
borderColor: primaryColor,
tension: 0.4,
backgroundColor: `color-mix(in srgb, ${primaryColor}, transparent 80%)`
}
]
};
}, },
setChartOptions() { handleResize() {
const documentStyle = getComputedStyle(document.documentElement); if (!this.isSlimMenuSelected || window.innerWidth <= 1400) {
const textColorSecondary = documentStyle.getPropertyValue('--p-text-muted-color'); this.isSlimMenu = window.innerWidth <= 1400;
const surfaceBorder = documentStyle.getPropertyValue('p-content-border-color');
return {
plugins: {
legend: {
display: false
} }
}, },
scales: { toggleSlimMenu() {
x: { this.isSlimMenu = !this.isSlimMenu;
ticks: { this.isSlimMenuSelected = this.isSlimMenu;
color: textColorSecondary
}, },
grid: { changeMenu() {
color: surfaceBorder this.isSlimMenu = !this.isSlimMenu;
} this.isSlimMenuSelected = this.isSlimMenu;
},
y: {
beginAtZero: true,
ticks: {
color: textColorSecondary
},
min: 0,
max: 100,
grid: {
color: surfaceBorder
}
}
}
};
} }
} }
}; };

View File

@ -0,0 +1,589 @@
<template>
<div class="flex-1 h-full overflow-y-auto overflow-x-clip overflow-hidden border border-surface rounded-2xl p-6">
<div class="text-color text-2xl font-medium leading-8">Cards</div>
<div class="mt-1 text-muted-color leading-6">You can make cards using Aura like below 👇</div>
<div class="mt-6 flex flex-wrap items-start gap-6">
<div class="flex-1 flex flex-col gap-6">
<div class="border border-surface rounded-3xl p-6 flex flex-col gap-6">
<div class="flex items-center gap-3">
<OverlayBadge severity="danger" class="w-fit">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/main-avatar.png" size="large" class="rounded-lg overflow-hidden flex" />
</OverlayBadge>
<div>
<div class="font-medium text-color leading-6">Jacob Jones</div>
<div class="mt-1 text-muted-color leading-5">hi@jacobjones.co</div>
</div>
</div>
<div class="flex items-center gap-6">
<div class="text-sm leading-5 text-color">14.k <span class="text-muted-color">Followers</span></div>
<div class="text-sm leading-5 text-color">359 <span class="text-muted-color">Following</span></div>
</div>
<p class="text-sm text-muted-color leading-5 mb-0">Meet Jacob Jones, the whimsical adventurer on a quest for life's quirks. From sock mysteries to subway adventures, join him for a laughter-filled journey!</p>
<div class="flex items-center justify-between gap-2">
<div class="text-sm leading-5 text-color font-medium">Mutual Friends</div>
<AvatarGroup>
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar1.png" size="small" class="rounded-lg overflow-hidden" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar9.jpg" size="small" class="rounded-lg overflow-hidden" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg" size="small" class="rounded-lg overflow-hidden" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg" size="small" class="rounded-lg overflow-hidden" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar5.png" size="small" class="rounded-lg overflow-hidden" />
<Avatar label="+99" size="small" class="rounded-lg overflow-hidden text-xs" />
</AvatarGroup>
</div>
<SelectButton
v-model="selectedUserSelectButtonOption"
:options="userSelectButtonOptions"
:pt="{
root: {
class: 'w-full'
},
pcbutton: {
root: {
class: 'flex-1'
}
}
}"
/>
<div class="flex flex-col gap-4">
<div class="p-2 rounded-2xl flex items-center gap-3 bg-emphasis">
<OverlayBadge severity="danger" class="w-fit">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/main-avatar.png" class="rounded-lg overflow-hidden w-10 h-10 block" />
</OverlayBadge>
<div class="flex-1">
<div class="text-color text-sm font-medium leading-5">Jacob Jones</div>
<div class="mt-1 text-muted-color text-xs leading-4">hi@jacobjones.co</div>
</div>
<Button label="Join" />
</div>
<div class="p-2 rounded-2xl flex items-center gap-3 bg-emphasis">
<OverlayBadge severity="danger" class="w-fit">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar9.jpg" class="rounded-lg overflow-hidden w-10 h-10 flex" />
</OverlayBadge>
<div class="flex-1">
<div class="text-color text-sm font-medium leading-5">Courtney Henry</div>
<div class="mt-1 text-muted-color text-xs leading-4">cou.henry41@courtney.co</div>
</div>
<Button label="Join" />
</div>
</div>
</div>
<div class="border border-surface rounded-3xl p-6">
<div class="flex items-center gap-3 p-3 border border-surface rounded-xl shadow-[0px_1px_2px_0px_rgba(18,18,23,0.05)]">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/main-avatar.png" class="rounded-lg overflow-hidden w-14 h-14" />
<div class="flex-1">
<div class="text-color font-medium leading-7">Jacob Jones</div>
<div class="text-muted-color text-sm mt-1">hi@jacobjones.co</div>
</div>
<Button icon="pi pi-bell" severity="contrast" text />
</div>
<div class="mt-4 flex flex-col gap-1">
<button class="w-full flex items-center gap-2 text-color p-2 bg-transparent hover:bg-emphasis active:bg-surface-200 dark:active:bg-surface-700 cursor-pointer rounded-lg transition-all select-none">
<i class="pi pi-envelope text-lg w-7 h-7 flex items-center justify-center"></i>
<div class="font-medium leading-normal flex-1 text-left">Messages</div>
</button>
<button class="w-full flex items-center gap-2 text-color p-2 bg-transparent hover:bg-emphasis active:bg-surface-200 dark:active:bg-surface-700 cursor-pointer rounded-lg transition-all select-none">
<i class="pi pi-cog text-lg w-7 h-7 flex items-center justify-center"></i>
<div class="font-medium leading-normal flex-1 text-left">Settings</div>
</button>
<button class="w-full flex items-center gap-2 text-color p-2 bg-transparent hover:bg-emphasis active:bg-surface-200 dark:active:bg-surface-700 cursor-pointer rounded-lg transition-all select-none">
<i class="pi pi-sync text-lg w-7 h-7 flex items-center justify-center"></i>
<div class="font-medium leading-normal flex-1 text-left">Switch Accounts</div>
</button>
<button class="w-full flex items-center gap-2 text-color p-2 bg-transparent hover:bg-emphasis active:bg-surface-200 dark:active:bg-surface-700 cursor-pointer rounded-lg transition-all select-none">
<i class="pi pi-sign-in text-lg w-7 h-7 flex items-center justify-center"></i>
<div class="font-medium leading-normal flex-1 text-left">Log out</div>
</button>
</div>
<Divider />
<div class="w-full flex items-center gap-2 text-color p-2 bg-transparent cursor-pointer rounded-lg transition-all select-none">
<i
class="pi text-lg w-7 h-7 flex items-center justify-center"
:class="{
'pi-moon': !darkMode,
'pi-sun': darkMode
}"
></i>
<div class="font-medium leading-normal flex-1 text-left">Switch to {{ darkMode ? 'Light' : 'Dark' }}</div>
<ToggleSwitch v-model="darkMode" />
</div>
</div>
<div class="border border-surface rounded-3xl">
<div class="pt-6 px-6 flex flex-col gap-6">
<div class="flex items-start gap-2 justify-between">
<div>
<div class="text-2xl text-color font-medium">Data Analyst</div>
<div class="mt-2 text-color">Data Insights Ltd.</div>
</div>
<Button @click="jobApplication = !jobApplication" :icon="jobApplication ? 'pi pi-bookmark-fill' : 'pi pi-bookmark'" severity="secondary" outlined rounded />
</div>
<div class="flex flex-wrap gap-1 items-center justify-between">
<div class="flex items-center gap-2 whitespace-nowrap text-muted-color">
<i class="pi pi-users text-xl"></i>
<div class="font-medium leading-none">Senior</div>
</div>
<div class="flex items-center gap-2 whitespace-nowrap text-muted-color">
<i class="pi pi-stopwatch text-xl"></i>
<div class="font-medium leading-none">Full-Time</div>
</div>
<div class="flex items-center gap-2 whitespace-nowrap text-muted-color">
<i class="pi pi-money-bill text-xl"></i>
<div class="font-medium leading-none">$80,000</div>
</div>
</div>
<p class="leading-6 text-muted-color mb-0">Expert in data analysis? Join Data Insights Ltd. as a senior data analyst. Lead in the world of data with us!</p>
<div class="flex flex-wrap gap-2 items-center">
<Tag value="Data Analysis" rounded class="font-normal"></Tag>
<Tag value="Analytics" rounded class="font-normal"></Tag>
<Tag value="Big Data" rounded class="font-normal"></Tag>
</div>
</div>
<div class="p-1 mt-4">
<button class="p-4 rounded-3xl w-full bg-emphasis transition-all text-color hover:text-color-emphasis flex items-center gap-2 justify-between cursor-pointer">
<div class="flex items-center [&>*]:-mr-2">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar10.jpg" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar12.jpg" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar9.jpg" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar5.png" size="small" shape="circle" />
</div>
<div class="flex items-center gap-2">
<div class="font-medium leading-6">12 Applicants</div>
<i class="pi pi-arrow-right"></i>
</div>
</button>
</div>
</div>
</div>
<div class="flex-1 flex flex-col gap-6">
<div class="border border-surface rounded-3xl p-6 flex flex-col gap-6">
<div class="flex items-center gap-2 text-color">
<i class="pi pi-cloud-upload text-xl"></i>
<div class="flex-1 font-medium leading-6">Upload Files</div>
<Button icon="pi pi-times" text rounded />
</div>
<div>
<label for="document-name" class="text-color font-medium leading-6">Document Name </label>
<InputText id="document-name" v-model="documentName" class="mt-2 w-full" />
</div>
<div>
<label class="text-color font-medium leading-6">Upload Files</label>
<FileUpload
name="demo[]"
url="/api/upload"
@upload="onTemplatedUpload($event)"
:pt="{
root: {
class: 'bg-transparent border-dashed mt-2'
},
content: {
class: 'p-0'
}
}"
accept="image/*"
:maxFileSize="1000000"
@select="onSelectedFiles"
>
<template #header="{ chooseCallback, uploadCallback, clearCallback, files, uploadedFiles }">
<div v-if="files.length > 0 || uploadedFiles.length > 0" class="flex w-full flex-wrap justify-between items-center flex-1 gap-4 border-b border-surface pb-4">
<div class="flex gap-2">
<Button @click="chooseCallback()" icon="pi pi-images" rounded outlined severity="secondary"></Button>
<Button @click="uploadEvent(uploadCallback)" icon="pi pi-cloud-upload" rounded outlined severity="success" :disabled="!files || files.length === 0"></Button>
<Button @click="clearCallback()" icon="pi pi-times" rounded outlined severity="danger" :disabled="!files || files.length === 0"></Button>
</div>
</div>
<div v-if="files.length <= 0 && uploadedFiles.length <= 0" class="flex flex-col items-center justify-center p-6 cursor-pointer" @click="chooseCallback()">
<i class="pi pi-cloud-upload text-4xl text-color" />
<div class="text-sm text-color font-medium mt-2">Click to upload <span class="text-muted-color">or and drop</span></div>
<p class="mt-2 mb-0 text-sm text-muted-color text-center">PDF, JPG, PNG, JPEG, DOC, CSV, XML, XMLX, XLS, XLSX (max 10MB)</p>
</div>
</template>
<template #content="{ files, uploadedFiles, removeUploadedFileCallback, removeFileCallback }">
<div v-if="files.length > 0" class="px-4 py-0">
<h5 class="m-0 mb-2">Pending</h5>
<div class="flex flex-wrap gap-2 grow overflow-auto max-h-[210px]">
<div v-for="(file, index) of files" :key="file.name + file.type + file.size" class="card max-w-[120px] !p-2 m-0 flex flex-col border-1 surface-border items-center gap-2 text-center">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" />
</div>
<span class="font-semibold max-w-[100px] text-ellipsis whitespace-nowrap overflow-hidden">{{ file.name }}</span>
<span class="text-sm text-muted-color">{{ formatSize(file.size) }}</span>
<div class="grow flex flex-col gap-2 justify-end">
<Badge value="Pending" severity="warning" />
<Button icon="pi pi-times text-sm leading-none" @click="onRemoveTemplatingFile(file, removeFileCallback, index)" class="!text-sm !leading-none" label="Cancel" text severity="danger" />
</div>
</div>
</div>
</div>
<div v-if="uploadedFiles.length > 0" class="px-4 py-0">
<h5 class="m-0 mb-2">Completed</h5>
<div class="flex flex-wrap gap-2">
<div v-for="(file, index) of uploadedFiles" :key="file.name + file.type + file.size" class="card max-w-[120px] !p-2 m-0 flex flex-col border-1 surface-border items-center gap-2 text-center">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" />
</div>
<span class="font-semibold max-w-[100px] text-ellipsis whitespace-nowrap overflow-hidden">{{ file.name }}</span>
<span class="text-sm text-muted-color">{{ formatSize(file.size) }}</span>
<div class="grow flex flex-col gap-2 justify-end">
<Badge value="Completed" class="mt-3" severity="success" />
<Button icon="pi pi-times text-sm leading-none" @click="removeUploadedFileCallback(index)" class="!text-sm !leading-none" label="Cancel" text severity="danger" />
</div>
</div>
</div>
</div>
</template>
</FileUpload>
</div>
<div>
<label class="text-color font-medium leading-6">Tag (Optional)</label>
<AutoComplete v-model="filesTag" class="w-full mt-2" inputId="multiple-ac-2" multiple @complete="search" :typeahead="false" />
</div>
<div class="flex items-center gap-2">
<label v-for="permission in permissions" :key="permission.key" :for="permission.key" class="cursor-pointer flex-1 flex items-center gap-1 p-2 rounded-border border border-surface hover:bg-emphasis transition-all select-none">
<i class="text-color" :class="permission.icon"></i>
<div class="flex-1 text-sm leading-5 text-color">{{ permission.name }}</div>
<RadioButton v-model="selectedPermission" :inputId="permission.key" variant="filled" name="dynamic" :value="permission.name" />
</label>
</div>
<div class="flex items-center gap-2">
<Button label="Cancel" outlined class="flex-1" />
<Button label="Upload" class="flex-1" />
</div>
</div>
<div class="border border-surface rounded-3xl p-6">
<div class="flex items-start justify-between gap-1">
<div class="flex items-center gap-x-2 gap-y-1 flex-wrap flex-1">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar1.png" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar2.png" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar9.jpg" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg" size="small" shape="circle" />
<div class="w-full"></div>
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar5.png" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar7.png" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar8.png" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar10.jpg" size="small" shape="circle" />
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar12.jpg" size="small" shape="circle" />
</div>
<Button icon="pi pi-arrow-up-right" rounded text />
</div>
<div class="text-2xl font-medium text-color mt-6 leading-8">That's your avatar</div>
<div class="leading-6 text-muted-color mt-2">Easy to use! place it, watch it.</div>
</div>
<div class="border border-surface rounded-3xl p-6 flex flex-col gap-6">
<div class="flex items-center justify-between gap-2">
<div class="text-2xl font-medium leading-8 flex-1">Add Member</div>
<Button icon="pi pi-times" rounded text severity="secondary" />
</div>
<div>
<div class="text-muted-color leading-6">Email</div>
<div class="flex items-start gap-3 mt-2">
<AutoComplete v-model="emailChips" inputId="multiple-ac-2" class="flex-1" multiple @complete="search" :typeahead="false" />
<Button label="Invite" />
</div>
</div>
<div>
<div class="font-medium leading-6 text-muted-color">Members</div>
<div class="mt-4 flex flex-col gap-4">
<div class="flex items-center gap-2 justify-between">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar8.png" class="w-9 h-9" shape="circle" />
<div class="flex-1">
<div class="text-sm font-medium text-color leading-5">Brook Simmons</div>
<div class="text-sm text-muted-color leading-5 line-clamp-4">brook.sim42@primevue.org</div>
</div>
<Select
v-model="memberSelectedTypes[0]"
:options="memberTypes"
optionLabel="name"
placeholder="Select a role"
class="w-16"
:pt="{
root: { class: 'border-0 shadow-none' },
label: { class: 'p-0 text-muted-color text-sm' },
dropdown: { class: 'p-0 w-auto' },
dropdownicon: { class: 'w-3 h-3' },
option: { class: 'text-sm px-2 py-1' }
}"
/>
</div>
<div class="flex items-center gap-2 justify-between">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg" class="w-9 h-9" shape="circle" />
<div class="flex-1">
<div class="text-sm font-medium text-color leading-5">Dianne Russell</div>
<div class="text-sm text-muted-color leading-5 line-clamp-4">di.russ23@primevue.org</div>
</div>
<Select
v-model="memberSelectedTypes[1]"
:options="memberTypes"
optionLabel="name"
placeholder="Select a role"
class="w-16"
:pt="{
root: { class: 'border-0 shadow-none' },
label: { class: 'p-0 text-muted-color text-sm' },
dropdown: { class: 'p-0 w-auto' },
dropdownicon: { class: 'w-3 h-3' },
option: { class: 'text-sm px-2 py-1' }
}"
/>
</div>
<div class="flex items-center gap-2 justify-between">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar12.jpg" class="w-9 h-9" shape="circle" />
<div class="flex-1">
<div class="text-sm font-medium text-color leading-5">Jacob Jones</div>
<div class="text-sm text-muted-color leading-5 line-clamp-4">jac.jon87@primevue.org</div>
</div>
<Select
v-model="memberSelectedTypes[2]"
:options="memberTypes"
optionLabel="name"
placeholder="Select a role"
class="w-16"
:pt="{
root: { class: 'border-0 shadow-none' },
label: { class: 'p-0 text-muted-color text-sm' },
dropdown: { class: 'p-0 w-auto' },
dropdownicon: { class: 'w-3 h-3' },
option: { class: 'text-sm px-2 py-1' }
}"
/>
</div>
</div>
</div>
<div>
<div class="font-medium leading-6 text-muted-color">Copy Link</div>
<div class="flex items-center gap-3 mt-2">
<InputText v-model="copiedText" type="text" class="flex-1" readOnly />
<Button label="Copy" severity="secondary" />
</div>
</div>
</div>
</div>
<div class="flex-1 flex flex-wrap gap-6">
<div class="flex-1 border border-surface rounded-3xl p-6">
<div class="text-color font-medium leading-6 mb-4">User Profiles</div>
<SelectButton
v-model="userProfiles"
:options="userProfilesOptions"
:pt="{
root: {
class: 'w-full'
},
pcbutton: {
root: {
class: 'flex-1'
}
}
}"
/>
<div class="flex flex-col gap-4 mt-6">
<div class="flex items-center gap-3">
<i class="pi pi-volume-down text-color text-xl"></i>
<div class="leading-6 text-color flex-1">Sound</div>
<ToggleSwitch v-model="userProfilesValues[0]" />
</div>
<div class="flex items-center gap-3">
<i class="pi pi-wifi text-color text-xl"></i>
<div class="leading-6 text-color flex-1">Wi-Fi</div>
<ToggleSwitch v-model="userProfilesValues[1]" />
</div>
<div class="flex items-center gap-3">
<i class="pi pi-moon text-color text-xl"></i>
<div class="leading-6 text-color flex-1">Dark Mode</div>
<ToggleSwitch v-model="userProfilesValues[2]" />
</div>
<div class="flex items-center gap-3">
<i class="pi pi-map-marker text-color text-xl"></i>
<div class="leading-6 text-color flex-1">Location Services</div>
<ToggleSwitch v-model="userProfilesValues[3]" />
</div>
<div class="flex items-center gap-3">
<i class="pi pi-shield text-color text-xl"></i>
<div class="leading-6 text-color flex-1">Privacy Settings</div>
<ToggleSwitch v-model="userProfilesValues[4]" />
</div>
<div class="flex items-center gap-3">
<i class="pi pi-sync text-color text-xl"></i>
<div class="leading-6 text-color flex-1">Auto Update</div>
<ToggleSwitch v-model="userProfilesValues[5]" />
</div>
</div>
</div>
<div class="flex-1 border border-surface rounded-3xl p-6 flex flex-col gap-6">
<div class="font-medium text-color text-2xl text-center">Forgot Password</div>
<div>
<div class="text-muted-color text-lg text-center leading-snug">
Verification code <br />
has been sent to email
</div>
<div class="rounded-full px-4 py-1 bg-surface-200 dark:bg-surface-800 w-fit mx-auto mt-4 text-color text-lg leading-relaxed">u*******m@gmail.com</div>
</div>
<div class="flex items-center justify-center">
<Button label="Resend" text />
</div>
<div class="flex items-center justify-center">
<InputOtp
v-model="forgotPasswordOTP"
:length="6"
integerOnly
:pt="{
root: {
class: 'w-full [&>*]:flex-1 [&>*]:min-h-14 [&>*]:text-2xl '
}
}"
/>
</div>
<Button label="Change password" />
</div>
<div class="border border-surface rounded-3xl p-6">
<div class="text-color font-medium leading-6 mb-6">Price Range</div>
<div>
<Slider v-model="priceRange" :min="0" range :max="15000" />
</div>
<div class="mt-4 flex gap-2">
<div class="flex-1">
<label for="price-min-val" class="leading-6 text-color">Min Value</label>
<InputNumber
v-model="priceRange[0]"
:min="0"
inputId="price-min-val"
mode="currency"
currency="USD"
locale="en-US"
:pt="{
root: {
class: '[&>*]:w-full mt-2'
}
}"
/>
</div>
<div class="flex-1">
<label for="price-max-val" class="leading-6 text-color">Max Value</label>
<InputNumber
v-model="priceRange[1]"
inputId="price-max-val"
mode="currency"
currency="USD"
locale="en-US"
:pt="{
root: {
class: '[&>*]:w-full mt-2'
}
}"
/>
</div>
</div>
<div class="mt-4">
<div class="text-color font-medium leading-6 mb-6">Popular specs</div>
<div class="flex items-center gap-4 flex-wrap">
<div v-for="(data, index) of priceRangePopularSpecs" :key="index" class="flex align-items-center">
<Checkbox v-model="priceRangePopularSpecsChecked" :inputId="data.value" :name="data.value" :value="data.value" />
<label :for="data.value" class="ml-2">{{ data.value }}</label>
</div>
</div>
</div>
<div class="flex items-center gap-3 flex-wrap [&>*]:flex-1 mt-6">
<Button label="Undo" outlined />
<Button label="Random" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Cards',
redrawListener: null,
data() {
return {
files: [],
totalSize: 0,
totalSizePercent: 0,
jobApplication: false,
userProfiles: 'Chilling',
userProfilesOptions: ['Chilling', 'Do Not Disturb'],
userProfilesValues: [true, true, false, false, true, false],
forgotPasswordOTP: '023',
priceRange: [0, 10000],
priceMinVal: 0,
priceMaxVal: 100000,
priceRangePopularSpecs: [
{ value: 'Furnished', checked: true },
{ value: 'Unfurnished', checked: false },
{ value: 'Detached', checked: true },
{ value: 'Underfloor heating', checked: false },
{ value: 'Balcony', checked: true },
{ value: 'Duplex', checked: false },
{ value: 'Triplex', checked: false },
{ value: 'Garden', checked: false },
{ value: 'Central location', checked: false },
{ value: 'Sea view', checked: true }
],
priceRangePopularSpecsChecked: ['Furnished', 'Detached', 'Balcony', 'Sea view'],
userSelectButtonOptions: ['Joined', 'Hosted'],
selectedUserSelectButtonOption: 'Joined',
darkMode: false,
emailChips: [],
memberSelectedTypes: ['O', 'E', 'V'],
memberTypes: [
{ name: 'Owner', code: 'O' },
{ name: 'Editor', code: 'E' },
{ name: 'Viewer', code: 'V' }
],
copiedText: 'https://www.example.com/shared-files/user123/document-collection/file12345',
documentName: 'Aura Theme',
filesTag: ['ui', 'redesign', 'dashboard'],
selectedPermission: 'Everyone',
permissions: [
{ name: 'Everyone', icon: 'pi pi-globe', key: 'E' },
{ name: 'Admins only', icon: 'pi pi-users', key: 'A' }
]
};
},
methods: {
onRemoveTemplatingFile(file, removeFileCallback, index) {
removeFileCallback(index);
this.totalSize -= parseInt(this.formatSize(file.size));
this.totalSizePercent = this.totalSize / 10;
},
onClearTemplatingUpload(clear) {
clear();
this.totalSize = 0;
this.totalSizePercent = 0;
},
onSelectedFiles(event) {
this.files = event.files;
this.files.forEach((file) => {
this.totalSize += parseInt(this.formatSize(file.size));
});
},
uploadEvent(callback) {
this.totalSizePercent = this.totalSize / 10;
callback();
},
onTemplatedUpload() {
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
formatSize(bytes) {
const k = 1024;
const dm = 3;
const sizes = this.$primevue.config.locale.fileSizeTypes;
if (bytes === 0) {
return `0 ${sizes[0]}`;
}
const i = Math.floor(Math.log(bytes) / Math.log(k));
const formattedSize = parseFloat((bytes / Math.pow(k, i)).toFixed(dm));
return `${formattedSize} ${sizes[i]}`;
},
search(event) {
this.items = [...Array(10).keys()].map((item) => event.query + '-' + item);
}
},
components: {}
};
</script>

View File

@ -0,0 +1,433 @@
<template>
<div class="flex-1 h-full overflow-y-auto overflow-x-clip overflow-hidden flex border border-surface rounded-2xl">
<div class="w-4/12 xl:w-3/12 min-w-40 overflow-auto flex flex-col gap-6">
<div class="flex flex-col gap-6 pt-3 pb-2 -mb-2 px-5 sticky top-0 bg-surface-0 dark:bg-surface-950 z-10">
<div class="flex items-center justify-between gap-6 text-color">
<div class="text-2xl font-medium lead">Chats</div>
<Button icon="pi pi-plus" text />
</div>
</div>
<div class="px-5">
<IconField iconPosition="left">
<InputIcon class="pi pi-search"> </InputIcon>
<InputText v-model="search" placeholder="Search" class="w-full" />
</IconField>
</div>
<div class="w-full px-5">
<SelectButton
v-model="value"
:options="options"
aria-labelledby="basic"
:pt="{
root: {
class: 'w-full'
},
pcbutton: {
root: {
class: 'flex-1'
}
}
}"
/>
</div>
<div class="flex-1 flex flex-col">
<div
v-for="chat in chats"
:key="chat.name"
class="flex items-center gap-2 p-4 cursor-pointer hover:bg-emphasis transition-all"
:class="{
'bg-emphasis': chat.name === activeChat
}"
>
<div class="relative">
<div v-if="chat.active !== undefined" class="absolute top-0 right-0 p-[1px] bg-surface-0 dark:bg-surface-950 rounded-full flex items-center justify-center">
<Badge :severity="chat.active ? 'success' : 'danger'" class="p-1.5"></Badge>
</div>
<Avatar
v-bind="chat.image ? { image: chat.image } : { label: chat.capName }"
:class="{
'bg-violet-100 text-violet-950': !chat.image
}"
class="text-base font-medium flex"
size="large"
shape="circle"
/>
</div>
<div class="flex-1">
<div class="flex items-start gap-1 justify-between">
<div class="text-color font-medium leading-6">{{ chat.name }}</div>
<div class="text-sm text-muted-color leading-5">{{ chat.time }}</div>
</div>
<div class="flex items-center gap-5 justify-between mt-1">
<div class="text-muted-color text-sm leading-5 line-clamp-1">{{ chat.lastMessage }}</div>
<Badge v-if="chat.unreadMessageCount > 0" :value="chat.unreadMessageCount" severity="contrast"></Badge>
</div>
</div>
</div>
</div>
</div>
<div class="w-8/12 xl:w-6/12 border-x border-surface flex flex-col">
<div class="flex items-center p-4 gap-7 border-b border-surface">
<div class="flex items-center">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar-primetek.png" class="mr-2 av" size="large" shape="circle" />
<div class="flex-1">
<div class="text-color leading-6 cursor-pointer hover:text-muted-color-emphasis transition-colors">PrimeTek</div>
<div class="text-muted-color leading-5 line-clamp-1 mt-1">Cody Fisher, Esther Howard, Jerome Bell, Kristin Watson, Ronald Richards, Darrell Steward</div>
</div>
</div>
<div class="flex items-center gap-2">
<Button icon="pi pi-phone" text />
<Button icon="pi pi-search" text />
<Button type="button" icon="pi pi-ellipsis-h" text @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" />
<Menu ref="menu" id="overlay_menu" :model="menuItems" :popup="true" />
</div>
</div>
<div class="flex-1 overflow-y-auto flex flex-col gap-8 py-8 px-6">
<div v-for="message in chatMessages" :key="message.id" class="flex items-start min-w-64 w-fit max-w-[60%]" :class="{ 'ml-auto mr-0 flex-row-reverse': message.type === 'sent' }">
<div
class="flex items-center gap-2 sticky top-0 transition-all"
:class="{
'flex-row-reverse': message.type === 'sent'
}"
>
<Avatar
v-bind="message.image ? { image: message.image } : { label: message.capName }"
:class="{
'bg-blue-100 text-blue-950': !message.image
}"
class="w-10 h-10 text-sm font-medium"
shape="circle"
/>
<div>
<svg :class="message.type === 'received' ? 'fill-surface-100 dark:fill-surface-800' : 'fill-primary rotate-180'" class="" xmlns="http://www.w3.org/2000/svg" width="7" height="11" viewBox="0 0 7 11" fill="none">
<path d="M1.79256 7.09551C0.516424 6.31565 0.516426 4.46224 1.79256 3.68238L7 0.500055L7 10.2778L1.79256 7.09551Z" />
</svg>
</div>
</div>
<div :class="message.type === 'received' ? 'flex-1 bg-surface-100 dark:bg-surface-800 px-2 py-1 rounded-lg' : 'flex-1 bg-primary px-2 py-1 rounded-lg'">
<p :class="message.type === 'received' ? 'text-color leading-6 mb-0' : 'text-primary-contrast leading-6 mb-0'">
{{ message.message }}
</p>
<div v-if="message.attachment" :class="message.type === 'received' ? 'bg-surface-200 dark:bg-surface-700' : 'bg-primary-emphasis'" class="mt-2 w-full rounded-lg mb-0.5 hover:opacity-75 transition-all">
<img class="w-full h-auto block cursor-pointer" :src="message.attachment" alt="Message Image" />
</div>
</div>
</div>
</div>
<div class="p-4 border-t border-surface flex items-end justify-between gap-2">
<div class="flex items-end gap-1 flex-1">
<Button icon="pi pi-face-smile" text />
<Button icon="pi pi-paperclip" text />
<Textarea class="ml-1 flex-1 border-0 shadow-none max-h-32 min-h-9 bg-emphasis overflow-auto" autoResize rows="1" placeholder="Write your message..." />
</div>
<Button icon="pi pi-send" />
</div>
</div>
<div class="w-3/12 xl:block hidden min-w-40 py-6 px-3 overflow-auto">
<div class="flex flex-col items-center justify-center">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar-primetek.png" class="w-32 h-32" size="xlarge" shape="circle" />
<div class="leading-6 font-medium text-color mt-4 w-full text-center">PrimeTek</div>
<div class="leading-5 text-sm text-muted-color mt-1 w-full text-center">@primetek</div>
<div class="flex items-center justify-center flex-wrap gap-1 mt-4">
<Button icon="pi pi-phone text-muted-color" severity="secondary" text />
<Button icon="pi pi-video text-muted-color" severity="secondary" text />
<Button icon="pi pi-sign-in text-muted-color" severity="secondary" text />
<Button icon="pi pi-info-circle text-muted-color" severity="secondary" text />
<Button type="button" icon="pi pi-ellipsis-v text-muted-color" severity="secondary" text @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" />
<Menu ref="menu" id="overlay_menu" :model="menuItems" :popup="true" />
</div>
</div>
<div class="flex flex-col gap-4 mt-4">
<div class="flex items-center gap-2">
<i class="pi pi-bell text-color"></i>
<div class="leading-6 font-medium text-color flex-1">Notification</div>
<ToggleSwitch v-model="notification" />
</div>
<div class="flex items-center gap-2">
<i class="pi pi-volume-down text-color"></i>
<div class="leading-6 font-medium text-color flex-1">Sound</div>
<ToggleSwitch v-model="sound" />
</div>
<div class="flex items-center gap-2">
<i class="pi pi-download text-color"></i>
<div class="leading-6 font-medium text-color flex-1">Save to downloads</div>
<ToggleSwitch v-model="download" />
</div>
</div>
<div class="mt-6">
<div class="flex items-center gap-2">
<div class="flex-1 text-color leading-6 font-medium">Members</div>
<Button label="See All" class="text-sm py-0.5 px-2 text-muted-color" text />
</div>
<div class="mt-4 flex flex-col gap-4">
<div v-for="member in members" :key="member.name" class="flex items-center gap-2 cursor-pointer">
<Avatar
v-bind="member.image ? { image: member.image } : { label: member.capName }"
:class="{
'bg-orange-100 text-orange-950': !member.image
}"
class="font-medium text-xs"
shape="circle"
/>
<div class="text-sm text-color hover:text-muted-color-emphasis transition-colors font-medium leading-5 flex-1">
{{ member.name }}
</div>
<i class="pi pi-chevron-right text-xs text-muted-color"></i>
</div>
</div>
</div>
<div class="mt-5">
<SelectButton
v-model="media"
:options="mediaOptions"
:pt="{
root: {
class: 'w-full'
},
pcbutton: {
root: {
class: 'flex-1'
}
}
}"
/>
<div class="mt-3 mb-5 grid grid-cols-3 gap-2">
<div v-for="(media, index) in chatMedia" :key="index" class="bg-emphasis hover:opacity-70 transition-all flex-1 aspect-square rounded-lg border border-surface cursor-pointer">
<img class="w-full h-full object-cover block" :src="media" alt="Media Image" />
</div>
<div class="bg-emphasis hover:opacity-70 transition-all flex-1 aspect-square rounded-lg border border-surface cursor-pointer flex items-center justify-center">
<span class="text-muted-color font-medium">99+</span>
</div>
</div>
<Button
label="Show more"
icon="pi pi-arrow-right"
iconPos="right"
outlined
class="w-full text-left"
:pt="{
root: {
class: 'justify-between'
}
}"
/>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Chat',
redrawListener: null,
data() {
return {
search: '',
download: false,
notification: true,
sound: false,
value: 'Chat',
value2: '',
options: ['Chat', 'Call'],
media: 'Media',
mediaOptions: ['Media', 'Link', 'Docs'],
activeChat: 'PrimeTek Team',
menuItems: [
{
label: 'Group Info',
icon: 'pi pi-info-circle'
},
{
label: 'Leave group',
icon: 'pi pi-sign-out'
}
],
chats: [
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg',
name: 'Cody Fisher',
capName: 'CF',
active: true,
unreadMessageCount: 8,
time: '12.30',
lastMessage: "Hey there! I've heard about PrimeVue. Any cool tips for getting started?"
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar-primetek.png',
name: 'PrimeTek Team',
capName: 'PT',
active: undefined,
unreadMessageCount: 0,
time: '11.15',
lastMessage: "Let's implement PrimeVue. Elevating our UI game! 🚀"
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar2.png',
name: 'Jerome Bell',
capName: 'JB',
active: true,
unreadMessageCount: 4,
time: '11.15',
lastMessage: "Absolutely! PrimeVue's documentation is gold—simplifies our UI work."
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar12.jpg',
name: 'Robert Fox',
capName: 'RF',
active: false,
unreadMessageCount: 0,
time: '11.15',
lastMessage: "Interesting! PrimeVue sounds amazing. What's your favorite feature?"
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg',
name: 'Esther Howard',
capName: 'EH',
active: true,
unreadMessageCount: 9,
time: '11.15',
lastMessage: 'Quick one, team! Anyone using PrimeVue for mobile app development?'
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar9.jpg',
name: 'Darlene Robertson',
capName: 'DR',
active: false,
unreadMessageCount: 0,
time: '11.15',
lastMessage: "Just explored PrimeVue's themes. Can we talk about those stunning designs? 😍"
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar6.png',
name: 'Ralph Edwards',
capName: 'RE',
active: false,
unreadMessageCount: 0,
time: '11.15',
lastMessage: 'PrimeVue is a game-changer, right? What are your thoughts, folks?'
},
{ image: '', name: 'Ronald Richards', capName: 'RR', active: false, unreadMessageCount: 0, time: '11.15', lastMessage: "Jumping in! PrimeVue's community forum is buzzing. Any engaging discussions?" },
{ image: '', name: 'Kristin Watson', capName: 'KW', active: false, unreadMessageCount: 0, time: '11.15', lastMessage: 'Sharing a quick win-PrimeVue tutorials are leveling up my UI skills. 👩‍💻' },
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar7.png',
name: 'Darrell Steward',
capName: 'DS',
active: false,
unreadMessageCount: 0,
time: '11.15',
lastMessage: "Reflecting on PrimeVue's impact on our workflow. What's your take?"
}
],
chatMessages: [
{ id: 1, attachment: '', name: '', image: '', capName: 'OS', type: 'received', message: "Awesome! What's the standout feature?" },
{ id: 2, attachment: '', name: '', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar8.png', capName: 'A', type: 'received', message: 'PrimeVue rocks! Simplifies UI dev with versatile components.' },
{ id: 3, attachment: '', name: '', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg', capName: 'A', type: 'received', message: 'Intriguing! Tell us more about its impact.' },
{
id: 4,
attachment: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/message-image.png',
name: '',
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar2.png',
capName: 'A',
type: 'received',
message: "It's design-neutral and compatible with Tailwind. Features accessible, high-grade components!"
},
{ id: 5, attachment: '', name: '', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar5.png', capName: 'A', type: 'sent', message: 'Customizable themes, responsive design UI excellence!' },
{ id: 6, attachment: '', name: '', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar8.png', capName: 'A', type: 'received', message: 'Love it! Fast-tracking our development is key.' },
{ id: 7, attachment: '', name: '', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar6.png', capName: 'A', type: 'received', message: 'Documentation rocks too smooth integration for all.' },
{
id: 8,
attachment: '',
name: '',
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar5.png',
capName: 'B',
type: 'sent',
message: 'The flexibility and ease of use are truly impressive. Have you explored the new components?'
},
{
id: 9,
attachment: '',
name: '',
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar12.jpg',
capName: 'C',
type: 'received',
message: 'Absolutely, the new calendar component has saved us a ton of development time!'
},
{
id: 10,
attachment: '',
name: '',
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg',
capName: 'D',
type: 'received',
message: "And the accessibility features are top-notch. It's great to see a library focusing on inclusivity."
},
{
id: 11,
attachment: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/message-image.png',
name: '',
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar5.png',
capName: 'E',
type: 'sent',
message: "I couldn't agree more. Plus, the documentation is incredibly thorough, which makes onboarding new team members a breeze."
},
{
id: 12,
attachment: '',
name: '',
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar6.png',
capName: 'F',
type: 'received',
message: 'Do you have any tips for optimizing performance when using multiple complex components?'
},
{
id: 13,
attachment: '',
name: '',
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg',
capName: 'G',
type: 'received',
message: 'Yes! Lazy loading and code splitting can make a huge difference, especially in larger applications.'
},
{
id: 14,
attachment: '',
name: '',
image: '',
capName: 'HS',
type: 'received',
message: "I've also found that leveraging the component's internal state management capabilities can help streamline data flow and improve performance."
},
{
id: 15,
attachment: '',
name: '',
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar5.png',
capName: 'H',
type: 'sent',
message: "That's great advice. It's amazing how much detail and thought has gone into making PrimeVue such a powerful tool for developers."
}
],
chatMedia: [
'https://www.primefaces.org/cdn/primevue/images/landing/apps/chat-image1.png',
'https://www.primefaces.org/cdn/primevue/images/landing/apps/chat-image2.png',
'https://www.primefaces.org/cdn/primevue/images/landing/apps/chat-image3.png',
'https://www.primefaces.org/cdn/primevue/images/landing/apps/chat-image4.png',
'https://www.primefaces.org/cdn/primevue/images/landing/apps/chat-image5.png'
],
members: [
{ name: 'Robin Jonas', capName: 'RJ', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar2.png' },
{ name: 'Cameron Williamson', capName: 'CW', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg' },
{ name: 'Eleanor Pena', capName: 'EP', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar5.png' },
{ name: 'Arlene McCoy', capName: 'AM', image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar8.png' },
{ name: 'Dianne Russell', capName: 'DR', image: '' }
]
};
},
methods: {
toggle(event) {
this.$refs.menu.toggle(event);
}
},
components: {}
};
</script>

View File

@ -0,0 +1,928 @@
<template>
<div class="h-full flex-1 flex flex-col overflow-hidden border border-surface rounded-2xl p-6">
<div class="flex items-start gap-2 justify-between">
<div>
<div class="text-2xl leading-8 text-color font-medium">Customers</div>
<div class="mt-1 leading-6 text-muted-color">The analysis list here shows all users</div>
</div>
<Button icon="pi pi-circle-fill text-green-500" label="950 Active User" outlined severity="secondary" />
</div>
<div class="mt-10 mb-4 flex items-center justify-between">
<IconField iconPosition="left">
<InputIcon class="pi pi-search"> </InputIcon>
<InputText v-model="search" placeholder="Search" />
</IconField>
<div class="flex items-center gap-3">
<Button icon="pi pi-filter" outlined severity="secondary" />
<Divider layout="vertical" class="m-0" />
<Button icon="pi pi-refresh" outlined severity="secondary" />
<Button label="1 of 15" outlined severity="secondary" />
<Button icon="pi pi-chevron-left" outlined severity="secondary" />
<Button icon="pi pi-chevron-right" outlined severity="secondary" />
</div>
</div>
<div class="flex-1 last:[&>td]:border-0 rounded-lg border border-surface w-full overflow-auto">
<DataTable
v-model:selection="selectedRows"
selectionMode="multiple"
:value="tableData"
:rows="10"
:pt="{
root: {
class: 'w-full flex-1 overflow-auto '
},
thead: {
class: 'sticky top-0 z-10'
}
}"
>
<template #empty>There is no customer.</template>
<Column selectionMode="multiple" headerStyle="width: 1rem" style="width: 1rem"></Column>
<Column field="name" header="Name">
<template #body="{ data }">
<div class="flex items-center">
<OverlayBadge :severity="data.active === undefined ? 'contrast' : data.active ? 'success' : 'danger'" class="w-fit">
<Avatar
v-bind="data.image ? { image: data.image } : { label: data.capName }"
:class="{
'bg-violet-100 text-violet-950 text-xs font-medium': !data.image
}"
class="rounded-md overflow-hidden flex"
/>
</OverlayBadge>
<div class="ml-4 leading-6 text-color font-medium">{{ data.name }}</div>
</div>
</template>
</Column>
<Column field="title" header="Title">
<template #body="{ data }">
<div class="leading-6 text-muted-color">{{ data.title }}</div>
</template>
</Column>
<Column field="company" header="Company Name">
<template #body="{ data }">
<div class="flex items-center gap-2">
<div class="flex items-center justify-center" v-html="companyLogos[data.company.logo]"></div>
<div class="leading-6 text-surface-600 dark:text-surface-400">{{ data.company.name }}</div>
</div>
</template>
</Column>
<Column field="email" header="Email Address">
<template #body="{ data }">
<div class="leading-6 text-muted-color truncate">{{ data.email }}</div>
</template>
</Column>
<Column field="lead" header="Lead Source">
<template #body="{ data }">
<div class="leading-6 text-muted-color">{{ data.lead }}</div>
</template>
</Column>
<Column field="status" header="Status">
<template #body="{ data }">
<Tag :severity="data.status === 'Active' ? 'success' : data.status === 'Inactive' ? 'danger' : 'info'" :value="data.status" class="font-medium"></Tag>
</template>
</Column>
<Column field="more" header="More">
<template #body>
<div class="flex justify-end w-full">
<Button @click="visibleRight = true" icon="pi pi-ellipsis-h" outlined severity="secondary" />
</div>
</template>
</Column>
</DataTable>
</div>
</div>
<Drawer
v-model:visible="visibleRight"
:containerVisible="true"
header="Right Sidebar"
position="right"
closeIcon="pi pi-sign-out"
:pt="{
root: {
class: '!max-w-2xl !w-full !h-[100vh] rounded-l-2xl'
},
footer: {
class: 'hidden'
},
content: {
class: 'flex-1 flex flex-col'
}
}"
>
<template #container="">
<div class="flex flex-col h-[100vh] overflow-auto">
<div class="">
<div class="flex align-items-center gap-3 p-6">
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg" size="large" class="rounded-xl overflow-hidden" />
<div class="flex-1">
<div class="leading-6 text-color font-medium">Brook Simmons</div>
<div class="mt-1 leading-5 text-muted-color text-sm">Sales Executive</div>
</div>
<Button icon="pi pi-sign-out" text rounded severity="secondary" />
</div>
<SelectButton
v-model="selectedSidebarOption"
:options="sidebarOptions"
:pt="{
root: {
class: 'px-6 py-3 w-full'
},
pcButton: {
root: {
class: 'flex-1 py-2.5'
},
label: {
class: 'text-sm'
}
}
}"
/>
</div>
<div v-if="selectedSidebarOption === 'Interaction Logs'" class="h-[calc(100%-172px)] flex flex-col gap-4 p-6">
<div class="h-1/3 flex flex-col p-3 rounded-xl bg-emphasis">
<div class="flex items-start justify-between">
<div class="leading-6 font-medium text-color">Call Logs</div>
<Button icon="pi pi-download text-sm" class="w-8 h-8 !border-surface !bg-surface-0 dark:!bg-surface-900 hover:opacity-75 transition-all" severity="secondary" text />
</div>
<div class="overflow-y-auto flex-1 bg-surface-0 dark:bg-surface-900 mt-2 flex flex-col rounded-lg overflow-hidden divide-y divide-surface-200 dark:divide-surface-800">
<div v-for="(data, index) of callLogs" :key="index" class="flex items-center gap-3 p-2">
<OverlayBadge severity="success" class="w-fit">
<Avatar :image="data.image" size="small" class="rounded-md w-10 h-10 overflow-hidden flex" />
</OverlayBadge>
<div class="flex-1">
<div class="text-sm leading-5 font-medium text-color">{{ data.name }}</div>
<div class="mt-1 text-sm leading-5 text-muted-color">{{ data.time }}</div>
</div>
<Button icon="pi pi-phone text-sm" text class="bg-primary/10 dark:bg-primary/20 w-8 h-8" />
</div>
</div>
</div>
<div class="h-1/3 flex flex-col p-3 rounded-xl bg-emphasis">
<div class="flex items-start justify-between">
<div class="leading-6 font-medium text-color">Email Records</div>
<Button icon="pi pi-download text-sm" class="w-8 h-8 !border-surface !bg-surface-0 dark:!bg-surface-900 hover:opacity-75 transition-all" severity="secondary" text />
</div>
<div class="overflow-y-auto flex-1 bg-surface-0 dark:bg-surface-900 mt-2 flex flex-col rounded-lg overflow-hidden divide-y divide-surface-200 dark:divide-surface-800">
<div v-for="(data, index) of emailRecords" :key="index" class="flex items-center gap-3 p-2">
<OverlayBadge severity="danger" class="w-fit">
<Avatar :image="data.image" size="small" class="rounded-md overflow-hidden w-10 h-10 flex" />
</OverlayBadge>
<div class="w-1/5 text-sm leading-5 font-medium text-color">{{ data.name }}</div>
<div class="flex-1">
<div class="text-sm leading-5 font-medium text-color line-clamp-2">
{{ data.title }}
<span class="text-muted-color">
{{ data.text }}
</span>
</div>
</div>
<div class="w-1/6 text-sm leading-5 text-muted-color text-right">{{ data.time }}</div>
</div>
</div>
</div>
<div class="h-1/3 flex flex-col p-3 rounded-xl bg-emphasis">
<div class="flex items-start justify-between">
<div class="leading-6 font-medium text-color">Meeting Notes</div>
<Button icon="pi pi-download text-sm" class="w-8 h-8 !border-surface !bg-surface-0 dark:!bg-surface-900 hover:opacity-75 transition-all leading-none" severity="secondary" text />
</div>
<div class="overflow-y-auto flex-1 bg-surface-0 dark:bg-surface-900 mt-2 p-4 flex flex-col rounded-lg overflow-hidden">
<div class="flex items-start justify-between gap-1">
<div class="text-sm text-color font-medium max-w-60">Subject: Meeting Wrap-up & Action Items: Jacob Jones</div>
<div class="text-sm text-muted-color">February 14, 2024 / 2:00 PM</div>
</div>
<div class="text-sm text-muted-color mt-6">
Here's a quick review of our meeting with Brook Simmons and next steps. Summary:
<br />
<ul class="list-disc pl-5">
<li>Reviewed our SaaS solution and its features.</li>
<li>Arlene McCoy intrigued by user experience potential.</li>
<li>Voiced concerns on integration with current system.Action Items:</li>
</ul>
Demo: Schedule product demo with Arlene McCoy. (Assigned to: Jerome Bell)<br /><br />
Integration Blueprint: Draft and deliver technical blueprint. (Assigned to: Cameron Williamson)<br /><br />
Follow-up Meeting: Arrange to discuss any queries post-demo. (Assigned to: Dianne Russell)
<br /><br />
Please act on these items promptly.
</div>
</div>
</div>
</div>
<div v-if="selectedSidebarOption === 'Preferences'" class="h-[calc(100%-72px)] flex flex-col gap-4 p-6">
<div v-for="(data, i) of preferences" :key="i" class="h-1/4 flex flex-col p-3 rounded-xl bg-emphasis">
<div class="leading-6 font-medium text-color p-2">{{ data.title }}</div>
<div class="overflow-y-auto flex-1 bg-surface-0 dark:bg-surface-900 mt-2 p-4 flex flex-col gap-3 rounded-lg">
<div v-for="(pref, j) of data.prefs" :key="j" class="flex items-center gap-2">
<i class="text-lg text-color" :class="pref.icon"></i>
<div class="font-medium text-color flex-1">{{ pref.title }}</div>
<ToggleSwitch v-model="pref.checked" />
</div>
</div>
</div>
</div>
<div v-if="selectedSidebarOption === 'Opportunities'" class="grid grid-cols-2 gap-6 p-6">
<div v-for="(data, i) of opportunities" :key="i" class="flex flex-col p-3 rounded-xl bg-emphasis">
<div class="flex items-start justify-between gap-2">
<div class="font-medium text-color mt-0.5">{{ data.title }}</div>
<NuxtLink :to="data.link" target="_blank" rel="noopener">
<Button icon="pi pi-arrow-up-right text-sm !leading-none" class="w-8 h-8 !border-surface !bg-surface-0 dark:!bg-surface-900" severity="secondary" text />
</NuxtLink>
</div>
<img class="w-full rounded-lg mt-2 block" :src="data.image" alt="Opportunutiy Image" />
<div class="flex-1 mt-2 p-2 rounded-lg bg-surface-0 dark:bg-surface-900 text-xs text-color">
{{ data.text }}
</div>
</div>
</div>
<div v-if="selectedSidebarOption === 'Statistics'" class="h-[calc(100%-160px)] p-6">
<div class="grid grid-cols-2 gap-4">
<div class="w-full h-full flex flex-col p-3 rounded-xl bg-emphasis">
<div class="flex items-center justify-between gap-2">
<div class="font-medium text-color p-2">Customer Satisfaction Score</div>
</div>
<div class="flex-1 py-4 mt-2 flex items-center justify-center rounded-lg bg-surface-0 dark:bg-surface-900 shadow-sm">
<Knob v-model="customerSatisfaction" :size="150" :strokeWidth="8" valueTemplate="{value}%" class="pointer-events-none" />
</div>
</div>
<div class="w-full h-full flex flex-col p-3 rounded-xl bg-emphasis">
<div class="flex items-center justify-between gap-2">
<div class="font-medium text-color p-2">Estimated Lifetime Value</div>
</div>
<div class="flex-1 flex items-center gap-2 justify-center mt-2 p-2 rounded-lg bg-surface-0 dark:bg-surface-900 shadow-sm">
<div class="font-semibold text-lg leading-none text-color border border-surface py-3.5 px-2 rounded-lg">$</div>
<div class="font-semibold text-lg leading-none text-color border border-surface py-3.5 px-2 rounded-lg">272</div>
<div class="font-semibold text-lg leading-none text-color border border-surface py-3.5 px-2 rounded-lg">123</div>
<div class="font-semibold text-lg leading-none text-color border border-surface py-3.5 px-2 rounded-lg">000</div>
</div>
</div>
<div class="w-full h-full flex flex-col p-3 rounded-xl bg-emphasis">
<div class="flex items-center justify-between gap-2">
<div class="font-medium text-color p-2">Product Usage</div>
</div>
<div class="flex-1 mt-2 py-4 rounded-lg bg-surface-0 dark:bg-surface-900 shadow-sm">
<Chart type="line" :data="lineChartData" :options="lineChartOptions" class="min-h-44 w-full" />
</div>
</div>
<div class="w-full h-full flex flex-col p-3 rounded-xl bg-emphasis">
<div class="font-medium text-color p-2">Churn Risk</div>
<div class="flex-1 py-4 mt-2 flex items-center justify-center rounded-lg bg-surface-0 dark:bg-surface-900 shadow-sm">
<Knob v-model="churnRisk" :size="150" :strokeWidth="8" valueTemplate="{value}%" class="pointer-events-none" />
</div>
</div>
</div>
<div class="mt-4 w-full flex flex-col p-3 rounded-xl bg-emphasis">
<div class="font-medium text-color p-2">Total Purchases</div>
<div class="flex-1 py-4 px-2 w-full mt-2 flex items-center justify-center rounded-lg bg-surface-0 dark:bg-surface-900 shadow-sm">
<Chart type="bar" :data="chartData" :options="chartOptions" class="h-60 w-full" />
</div>
</div>
</div>
</div>
</template>
</Drawer>
</template>
<script>
import EventBus from '@/layouts/AppEventBus';
export default {
name: 'Inbox',
redrawListener: null,
data() {
return {
search: '',
lineChartData: {},
lineChartOptions: {},
chartData: {},
chartOptions: {},
tableData: [
{
id: 1,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar2.png',
active: true,
name: 'Brook Simmons',
title: 'Sales Executive ',
company: { name: 'Mistranet', logo: 'mistranet' },
email: 'hi@brooksmmns.co',
lead: 'Linkedin',
status: 'Active'
},
{
id: 2,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar9.jpg',
active: true,
name: 'Dianne Russell',
title: 'CEO',
company: { name: 'BriteMank', logo: 'britemank' },
email: 'hi@diannerussell.com',
lead: 'Website',
status: 'Inactive'
},
{
id: 3,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg',
active: undefined,
name: 'Amy Elsner',
title: 'Product Manager',
company: { name: 'ZenTrailMs', logo: 'zentrailms' },
email: 'hi@amyelsner.com',
lead: 'Cold Call',
status: 'Prospect'
},
{
id: 4,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg',
active: true,
name: 'Jacob Jones',
title: 'Manager',
company: { name: 'Streamlinz', logo: 'streamlinz' },
email: 'jacobjones@gmail.com',
lead: 'Partner',
status: 'Prospect'
},
{ id: 5, image: '', active: false, name: 'Cameron Watson', capName: 'CW', title: 'Product Manager', company: { name: 'BriteMank', logo: 'britemank' }, email: 'hi@cameronwilliamson', lead: 'Social Media', status: 'Active' },
{ id: 6, image: '', active: true, name: 'Wade Warren', capName: 'WW', title: 'Director', company: { name: 'Streamlinz', logo: 'streamlinz' }, email: 'hi@annetteblack.com', lead: 'Cold Call', status: 'Inactive' },
{
id: 7,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar7.png',
active: true,
name: 'Guy Hawkins',
title: 'Director',
company: { name: 'Wavelength', logo: 'wavelength' },
email: 'hi@darrellsteward.com',
lead: 'Linkedin',
status: 'Active'
},
{
id: 8,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar8.png',
active: true,
name: 'Annette Black',
title: 'Manager',
company: { name: 'Wavelength', logo: 'wavelength' },
email: 'jeromebell@gmail.com',
lead: 'Website',
status: 'Inactive'
},
{
id: 9,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar10.jpg',
active: undefined,
name: 'Darrell Steward',
title: 'Product Manager',
company: { name: 'ZenTrailMs', logo: 'zentrailms' },
email: 'hi@onyamalimba.co',
lead: 'Website',
status: 'Active'
},
{ id: 10, image: '', active: true, name: 'Jerome Bell', capName: 'JB', title: 'Marketing Manager', company: { name: 'Mistranet', logo: 'mistranet' }, email: 'hi@courtneyhenryo', lead: 'Social Media', status: 'Active' },
{
id: 11,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar12.jpg',
active: undefined,
name: 'Onyama Limba',
title: 'Sales Executive ',
company: { name: 'BriteMank', logo: 'britemank' },
email: 'hi@arlenemccoy.com',
lead: 'Social Media',
status: 'Active'
}
],
companyLogos: {
mistranet: `
<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19" fill="none">
<path class="fill-surface-600 dark:fill-surface-400" fill-rule="evenodd" clip-rule="evenodd" d="M6.82207 0.728516C5.83146 0.728516 4.88145 1.12203 4.18099 1.82249L1.89501 4.10846C1.19454 4.80892 0.801025 5.75895 0.801025 6.74956C0.801025 7.8426 1.27054 8.82597 2.01888 9.509C1.27054 10.192 0.801025 11.1754 0.801025 12.2684C0.801025 13.2591 1.19454 14.2091 1.89501 14.9095L4.18099 17.1955C4.88145 17.896 5.83146 18.2895 6.82207 18.2895C7.91511 18.2895 8.89848 17.82 9.58152 17.0716C10.2646 17.82 11.2479 18.2895 12.341 18.2895C13.3316 18.2895 14.2816 17.896 14.982 17.1955L17.268 14.9095C17.9685 14.2091 18.362 13.2591 18.362 12.2684C18.362 11.1754 17.8925 10.192 17.1442 9.509C17.8925 8.82597 18.362 7.8426 18.362 6.74956C18.362 5.75895 17.9685 4.80892 17.268 4.10846L14.982 1.82249C14.2816 1.12203 13.3316 0.728516 12.341 0.728516C11.2479 0.728516 10.2646 1.19802 9.58152 1.94637C8.89848 1.19802 7.91511 0.728516 6.82207 0.728516ZM11.9859 9.62736C12.0509 9.56231 12.0509 9.45569 11.9859 9.39064L11.4907 8.89547C10.4363 7.84105 8.72674 7.84105 7.67233 8.89547L7.17716 9.39064C7.11211 9.45569 7.11211 9.56231 7.17716 9.62736L7.67233 10.1225C8.72674 11.177 10.4363 11.177 11.4907 10.1225L11.9859 9.62736ZM11.0796 13.2931C10.7451 13.6276 10.5571 14.0814 10.5571 14.5544C10.5571 15.5396 11.3558 16.3383 12.341 16.3383C12.8141 16.3383 13.2678 16.1503 13.6023 15.8158L15.8883 13.5298C16.2229 13.1953 16.4108 12.7415 16.4108 12.2684C16.4108 11.2833 15.6121 10.4846 14.627 10.4846C14.1539 10.4846 13.7001 10.6725 13.3656 11.0071L11.0796 13.2931ZM8.60592 14.5544C8.60592 14.0814 8.41798 13.6276 8.08345 13.2931L5.79743 11.0071C5.4629 10.6725 5.00918 10.4846 4.53608 10.4846C3.5509 10.4846 2.75224 11.2833 2.75224 12.2684C2.75224 12.7415 2.94018 13.1953 3.27471 13.5298L5.56071 15.8158C5.89525 16.1503 6.34898 16.3383 6.82207 16.3383C7.80724 16.3383 8.60592 15.5396 8.60592 14.5544ZM8.60592 4.46357C8.60592 4.93666 8.41798 5.39037 8.08346 5.72489L5.79743 8.01092C5.4629 8.34545 5.00918 8.5334 4.53608 8.5334C3.5509 8.5334 2.75224 7.73473 2.75224 6.74956C2.75224 6.27646 2.94018 5.82274 3.27471 5.48821L5.56071 3.20221C5.89525 2.86767 6.34898 2.67974 6.82207 2.67974C7.80724 2.67974 8.60592 3.47838 8.60592 4.46357ZM13.3656 8.01092L11.0796 5.72489C10.7451 5.39037 10.5571 4.93666 10.5571 4.46357C10.5571 3.47838 11.3558 2.67974 12.341 2.67974C12.8141 2.67974 13.2678 2.86767 13.6023 3.20221L15.8883 5.48821C16.2229 5.82274 16.4108 6.27646 16.4108 6.74956C16.4108 7.73473 15.6121 8.5334 14.627 8.5334C14.1539 8.5334 13.7001 8.34545 13.3656 8.01092Z"/>
</svg>
`,
britemank: `
<svg class="fill-surface-600 dark:fill-surface-400" xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19" fill="none">
<g clip-path="url(#clip0_536_12504)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.3011 5.75643C12.1897 5.68201 12.0754 5.6128 11.9585 5.54894C10.8679 4.95318 9.80103 3.99069 9.80103 2.74805V0.498047C11.581 0.498047 13.3211 1.02589 14.8012 2.01482C16.2812 3.00375 17.4347 4.40936 18.1159 6.05388C18.7971 7.69841 18.9754 9.50804 18.6281 11.2539C18.2808 12.9997 17.4237 14.6033 16.165 15.862C14.9063 17.1207 13.3027 17.9778 11.5568 18.3251C9.81102 18.6724 8.00139 18.4941 6.35686 17.813C4.71234 17.1318 3.30673 15.9782 2.3178 14.4982C1.32887 13.0181 0.801025 11.2781 0.801025 9.49805H3.05103C4.29367 9.49805 5.25615 10.565 5.85191 11.6555C5.91578 11.7724 5.98498 11.8867 6.05941 11.9981C6.55387 12.7381 7.25668 13.3149 8.07897 13.6555C8.90121 13.9961 9.80602 14.0852 10.6789 13.9116C11.5518 13.7379 12.3537 13.3094 12.983 12.68C13.6123 12.0507 14.0409 11.2489 14.2145 10.376C14.3882 9.50304 14.2991 8.59823 13.9585 7.77599C13.6179 6.9537 13.0411 6.25089 12.3011 5.75643Z" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.75102 0.498049C5.50249 0.498049 5.30335 0.700016 5.27854 0.947303C5.23471 1.38414 5.12711 1.81303 4.95848 2.22012C4.73234 2.76609 4.40087 3.26216 3.983 3.68003C3.56514 4.0979 3.06907 4.42936 2.5231 4.65551C2.116 4.82413 1.68711 4.93174 1.25028 4.97557C1.00299 5.00038 0.801026 5.19952 0.801026 5.44805L0.801025 9.49805C1.98292 9.49805 3.15324 9.26526 4.24518 8.81297C5.33711 8.36067 6.32927 7.69773 7.16497 6.86199C8.00071 6.0263 8.66365 5.03414 9.11594 3.9422C9.56824 2.85027 9.80102 1.67994 9.80102 0.498047L5.75102 0.498049Z"/>
</g>
<defs>
<clipPath id="clip0_536_12504">
<rect width="18" height="18" fill="white" transform="translate(0.800049 0.5)"/>
</clipPath>
</defs>
</svg>
`,
zentrailms: `
<svg class="fill-surface-600 dark:fill-surface-400" xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.79908 18.5C14.7696 18.5 18.7991 14.4705 18.7991 9.49998C18.7991 4.52944 14.7696 0.5 9.79908 0.5C4.8285 0.5 0.799072 4.52944 0.799072 9.49998C0.799072 14.4705 4.8285 18.5 9.79908 18.5ZM12.6068 4.69258C12.7434 4.20712 12.2723 3.92006 11.8421 4.22658L5.83597 8.5053C5.36937 8.83772 5.44276 9.49998 5.94622 9.49998H7.52779V9.48774H10.6102L8.09862 10.3739L6.99139 14.3074C6.85473 14.7929 7.32579 15.0799 7.75608 14.7734L13.7622 10.4947C14.2288 10.1623 14.1553 9.49998 13.6519 9.49998H11.2535L12.6068 4.69258Z" />
</svg>
`,
streamlinz: `<svg class="fill-surface-600 dark:fill-surface-400" xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19" fill="none">
<path d="M9.79907 0.498047C8.61719 0.498047 7.44683 0.730864 6.3549 1.18313C5.26297 1.63544 4.27086 2.29835 3.43509 3.13407C2.59938 3.96983 1.93647 4.96194 1.48415 6.05387C1.03189 7.1458 0.799072 8.31616 0.799072 9.49804C0.799072 10.6799 1.03189 11.8503 1.48415 12.9422C1.93647 14.0341 2.59938 15.0262 3.43509 15.862C4.27086 16.6977 5.26297 17.3606 6.3549 17.813C7.44683 18.2652 8.61719 18.498 9.79907 18.498V13.998C9.2081 13.998 8.62295 13.8817 8.07698 13.6555C7.53102 13.4293 7.03494 13.0979 6.61708 12.68C6.19922 12.2622 5.86777 11.7661 5.64164 11.2201C5.41545 10.6742 5.29907 10.089 5.29907 9.49804C5.29907 8.90708 5.41545 8.32192 5.64164 7.77596C5.86777 7.22999 6.19922 6.73391 6.61708 6.31606C7.03494 5.8982 7.53102 5.56674 8.07698 5.34061C8.62295 5.11443 9.2081 4.99804 9.79907 4.99804V0.498047Z" />
<path d="M9.79905 12.5019C11.4559 12.5019 12.799 11.1588 12.799 9.50193C12.799 7.84506 11.4559 6.50195 9.79905 6.50195C8.14218 6.50195 6.79907 7.84506 6.79907 9.50193C6.79907 11.1588 8.14218 12.5019 9.79905 12.5019Z"/>
<path d="M0.799072 9.49805C0.799072 10.6799 1.03189 11.8503 1.48415 12.9422C1.93647 14.0341 2.59938 15.0263 3.43509 15.862C4.27086 16.6977 5.26297 17.3606 6.3549 17.813C7.44683 18.2652 8.61719 18.498 9.79907 18.498C10.9809 18.498 12.1513 18.2652 13.2432 17.813C14.3352 17.3606 15.3273 16.6977 16.163 15.862C16.9988 15.0263 17.6617 14.0341 18.114 12.9422C18.5662 11.8503 18.7991 10.6799 18.7991 9.49805H14.2991C14.2991 10.089 14.1827 10.6742 13.9565 11.2201C13.7304 11.7661 13.3989 12.2622 12.9811 12.68C12.5632 13.0979 12.0671 13.4293 11.5212 13.6555C10.9752 13.8817 10.39 13.998 9.79907 13.998C9.2081 13.998 8.62295 13.8817 8.07698 13.6555C7.53102 13.4293 7.03494 13.0979 6.61708 12.68C6.19922 12.2622 5.86777 11.7661 5.64164 11.2201C5.41545 10.6742 5.29907 10.089 5.29907 9.49805H0.799072Z" />
<path d="M12.7991 9.50199C12.7991 8.70634 12.483 7.94329 11.9204 7.38066C11.3578 6.81803 10.5948 6.50195 9.7991 6.50195C9.00345 6.50195 8.24041 6.81803 7.67778 7.38066C7.11515 7.94329 6.79907 8.70634 6.79907 9.50199H9.7991H12.7991Z" />
</svg>`,
wavelength: `<svg class="fill-surface-600 dark:fill-surface-400" xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19" fill="none">
<path d="M9.79907 0.5C4.82851 0.5 0.799072 4.52943 0.799072 9.5C5.76963 9.5 9.79907 5.47056 9.79907 0.5Z" />
<path d="M9.79907 18.5C14.7696 18.5 18.7991 14.4706 18.7991 9.5C13.8285 9.5 9.79907 13.5294 9.79907 18.5Z" />
<path d="M9.79907 0.5C14.7696 0.5 18.7991 4.52943 18.7991 9.5C13.8285 9.5 9.79907 5.47056 9.79907 0.5Z" />
<path d="M9.79907 18.5C4.82851 18.5 0.799072 14.4706 0.799072 9.5C5.76963 9.5 9.79907 13.5294 9.79907 18.5Z" />
</svg>`
},
selectedRows: [],
visibleRight: false,
selectedSidebarOption: 'Statistics',
sidebarOptions: ['Interaction Logs', 'Preferences', 'Statistics', 'Opportunities'],
callLogs: [
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar6.png', name: 'Brook Simmons', time: '02.02.2024 | 45 min' },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar12.jpg', name: 'Jacob Jones', time: '02.02.2024 | 45 min' },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg', name: 'Annette Black', time: '02.03.2024 | 13 min' },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar9.jpg', name: 'Arlene McCoy', time: '02.03.2024 | 14 min' },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar10.jpg', name: 'Arlene Simmons', time: '02.03.2024 | 14 min' },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg', name: 'Michael Brown', time: '02.04.2024 | 20 min' }
],
emailRecords: [
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar2.png',
name: 'Brook Simmons',
time: '3:24 PM',
title: 'Unleash Business Potential',
text: 'Automate, analyze, and accelerate with our SaaS platform. Unshackle from mundane tasks and focus on scaling your business. Contact us for a demo today!'
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar7.png',
name: 'Jacob Jones',
time: '12.23.2023',
title: 'Optimized Workflow Revolution ',
text: "Experience a workflow revolution with our intuitive SaaS tool. With enhanced features and optimized processes, it's efficiency like never before. Let's get in touch for a brief demo!"
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar8.png',
name: 'Annette Black',
time: '12.17.2023',
title: 'Innovation at Fingertips',
text: 'With our SaaS solution, innovation is only a click away. Shape your future with pioneering features and minimalist design. Join us for your solution walk-through today!'
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg',
name: 'Arlene McCoy',
time: '06.17.2023',
title: 'Seamless Integration',
text: 'Integrate effortlessly with our user-friendly SaaS tools. Streamline your operations and boost productivity. Discover more in our demo session.'
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg',
name: 'Arlene Simmons',
time: '04.17.2023',
title: 'Transform Your Business',
text: 'Empower your team with our innovative SaaS solutions. Achieve unparalleled efficiency and drive growth. Book a demo to explore the possibilities.'
},
{
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar2.png',
name: 'Michael Brown',
time: '01.05.2024',
title: 'Next-Gen Collaboration',
text: 'Experience the future of collaboration with our cutting-edge SaaS platform. Enhance teamwork and streamline communication. Contact us for a demo today!'
}
],
preferences: [
{
title: 'Email',
prefs: [
{ icon: 'pi pi-bell', title: 'Notification', checked: true },
{ icon: 'pi pi-inbox', title: 'Newsletter', checked: false },
{ icon: 'pi pi-sync', title: 'Product Updates', checked: false }
]
},
{
title: 'Telephone',
prefs: [
{ icon: 'pi pi-mobile', title: 'Phone Call', checked: true },
{ icon: 'pi pi-volume-down', title: 'Voicemail', checked: false },
{ icon: 'pi pi-comments', title: 'SMS text', checked: false }
]
},
{
title: 'Social Media',
prefs: [
{ icon: 'pi pi-clock', title: 'Automated Post', checked: true },
{ icon: 'pi pi-user', title: 'Direct Message', checked: false }
]
},
{
title: 'Data Privacy',
prefs: [
{ icon: 'pi pi-box', title: 'Share Data with 3rd Parties', checked: true },
{ icon: 'pi pi-file', title: 'Cookies', checked: false }
]
}
],
opportunities: [
{
title: 'Apollo',
link: 'https://primevue.org/templates/apollo/',
image: 'https://primefaces.org/cdn/primevue/images/layouts/apollo-vue.jpg',
text: 'Keep your application fresh with Apollo, the newest and most modern template available.'
},
{
title: 'Ultima',
link: 'https://primevue.org/templates/ultima/',
image: 'https://primefaces.org/cdn/primevue/images/layouts/ultima-vue.jpg',
text: "Elevate your application's intuitiveness with Ultima's premium Material Design interface."
},
{
title: 'Diamond',
link: 'https://primevue.org/templates/diamond/',
image: 'https://primefaces.org/cdn/primevue/images/layouts/diamond-vue.jpg',
text: "Handle complex operations with elegance with Diamond's robust and powerful premium design."
},
{
title: 'Atlantis',
link: 'https://primevue.org/templates/atlantis/',
image: 'https://primefaces.org/cdn/primevue/images/layouts/atlantis-vue.jpg',
text: "Boost your application's capabilities, customization with the Atlantis template."
},
{
title: 'Verona',
link: 'https://primevue.org/templates/verona/',
image: 'https://primefaces.org/cdn/primevue/images/layouts/verona-vue.jpg',
text: "Achieve sophistication and subtlety with Verona's minimalistic, content-focused design."
},
{
title: 'Freya',
link: 'https://primevue.org/templates/freya/',
image: 'https://primefaces.org/cdn/primevue/images/layouts/freya-vue.png',
text: "Give your application a sleek, updated look with Freya's chic and modern premium template."
}
],
customerSatisfaction: 56,
churnRisk: 24
};
},
beforeUnmount() {
EventBus.off('dark-mode-toggle-complete', this.redrawListener);
EventBus.off('theme-palette-change', this.redrawListener);
},
mounted() {
this.chartData = this.setChartData();
this.chartOptions = this.setChartOptions();
this.lineChartData = this.setLineChartData();
this.lineChartOptions = this.setLineChartOptions();
this.redrawListener = () => {
this.chartOptions = this.setChartOptions();
this.chartData = this.setChartData();
this.lineChartData = this.setLineChartData();
this.lineChartOptions = this.setLineChartOptions();
};
EventBus.on('theme-palette-change', this.redrawListener);
EventBus.on('dark-mode-toggle-complete', this.redrawListener);
},
methods: {
toggle(event) {
this.$refs.menu.toggle(event);
},
setChartData() {
const documentStyle = getComputedStyle(document.documentElement);
const darkMode = document.documentElement.classList.contains('p-dark');
return {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
type: 'bar',
label: 'Investment Wallet',
backgroundColor: 'color-mix(in srgb, ' + documentStyle.getPropertyValue(darkMode ? '--p-surface-700' : '--p-surface-200') + ' 100%, transparent)',
data: [100, 201, 404, 300, 140, 220, 314, 520, 145, 234, 325, 147],
borderRadius: {
topLeft: 4,
topRight: 4
},
borderSkipped: true,
barThickness: 20,
hoverBackgroundColor: 'color-mix(in srgb, ' + documentStyle.getPropertyValue(darkMode ? '--p-surface-0' : '--p-surface-800') + ' 100%, transparent)',
hoverTransition: '1s ease all'
}
]
};
},
setChartOptions() {
const darkMode = document.documentElement.classList.contains('p-dark');
const documentStyle = getComputedStyle(document.documentElement);
const backgroundColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-900' : '--p-surface-0');
const textColor = documentStyle.getPropertyValue('--p-text-color');
const borderColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-800' : '--p-surface-100');
const textMutedColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-500' : '--p-surface-400');
const getOrCreateTooltip = (chart) => {
let tooltipEl = chart.canvas.parentNode.querySelector('div.chartjs-tooltip');
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.classList.add('chartjs-tooltip');
tooltipEl.style.backgroundColor = backgroundColor;
tooltipEl.style.boxShadow =
' 0px 33.12px 9.399px 0px rgba(0, 0, 0, 0.00), 0px 21.036px 8.504px 0px rgba(0, 0, 0, 0.01), 0px 12.084px 7.161px 0px rgba(0, 0, 0, 0.05), 0px 5.371px 5.371px 0px rgba(0, 0, 0, 0.09), 0px 1.343px 2.685px 0px rgba(0, 0, 0, 0.10)';
tooltipEl.style.borderRadius = '7px';
tooltipEl.style.color = textColor;
tooltipEl.style.opacity = 1;
tooltipEl.style.padding = '14.5px';
tooltipEl.style.pointerEvents = 'none';
tooltipEl.style.position = 'absolute';
tooltipEl.style.transform = 'translate(-50%, 0)';
tooltipEl.style.transition = 'all .2s ease';
chart.canvas.parentNode.appendChild(tooltipEl);
}
return tooltipEl;
};
return {
maintainAspectRatio: false,
aspectRatio: 0.8,
plugins: {
chartAreaBorder: {
borderColor: 'red',
borderWidth: 2,
borderDash: [5, 5],
borderDashOffset: 2
},
tooltip: {
enabled: false,
padding: 5,
position: 'nearest',
external: function (context) {
// Tooltip Element
const { chart, tooltip } = context;
const tooltipEl = getOrCreateTooltip(chart);
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
if (tooltip.body) {
const bodyLines = tooltip.body.map((b) => {
const strArr = b.lines[0].split(':');
const data = {
text: strArr[0].trim(),
value: strArr[1].trim()
};
return data;
});
// Clear old content
tooltipEl.innerHTML = '';
bodyLines.forEach((body, i) => {
const text = document.createElement('div');
text.appendChild(document.createTextNode('$' + body.value + 'K'));
text.style.fontWeight = '500';
text.style.lineHeight = '21px';
text.style.fontSize = '14px';
tooltipEl.appendChild(text);
});
}
const { offsetLeft: positionX, offsetTop: positionY } = chart.canvas;
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = positionX + tooltip.caretX + 'px';
tooltipEl.style.top = positionY + tooltip.caretY + 'px';
tooltipEl.style.font = tooltip.options.bodyFont.string;
tooltipEl.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px';
}
},
legend: {
display: false
}
},
scales: {
x: {
stacked: true,
ticks: {
color: textMutedColor,
font: {
weight: 'lighter'
}
},
grid: {
color: 'transparent',
borderColor: 'transparent'
}
},
y: {
border: {
display: false
},
stacked: true,
ticks: {
color: textMutedColor,
font: {
weight: 'lighter'
}
},
grid: {
color: borderColor,
borderColor: 'transparent'
}
}
}
};
},
setLineChartData() {
const darkMode = document.documentElement.classList.contains('p-dark');
return {
labels: ['31', '1', '2', '3', '4', '5', '6', '7', '8'],
datasets: [
{
label: 'My First Dataset',
data: [60, 64, 57, 52, 58, 70, 75, 70, 60],
fill: true,
borderColor: '#16A34A',
tension: 0.4,
borderWidth: 1.5,
pointBackgroundColor: '#16A34A',
pointBorderColor: darkMode ? '#09090B' : '#FFF',
pointBorderWidth: 3,
hideInLegendAndTooltip: false,
pointStyle: function (context) {
let index = context.dataIndex;
if (index == 6) {
return 'circle';
} else {
return 'line';
}
},
pointRadius: function (context) {
let index = context.dataIndex;
if (index == 6) {
return 6;
} else {
return 0.1;
}
},
backgroundColor: (context) => {
const bgColor = ['rgba(22,163,74,0.16)', 'rgba(22,163,74,0)'];
if (!context.chart.chartArea) {
return;
}
const {
ctx,
data,
chartArea: { top, bottom }
} = context.chart;
const gradientBg = ctx.createLinearGradient(0, top, 0, bottom);
const colorTranches = 1 / (bgColor.length - 1);
for (let i = 0; i < bgColor.length; i++) {
gradientBg.addColorStop(0 + i * colorTranches, bgColor[i]);
}
return gradientBg;
}
}
],
options: {
responsive: true,
plugins: {
legend: {
position: 'top'
},
title: {
display: true,
text: 'Chart.js Line Chart'
}
}
}
};
},
setLineChartOptions() {
const darkMode = document.documentElement.classList.contains('p-dark');
const documentStyle = getComputedStyle(document.documentElement);
const backgroundColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-900' : '--p-surface-0');
const textColor = documentStyle.getPropertyValue('--p-text-color');
const borderColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-800' : '--p-surface-100');
const textMutedColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-500' : '--p-surface-400');
const getOrCreateTooltip = (chart) => {
let tooltipEl = chart.canvas.parentNode.querySelector('div.chartjs-tooltip');
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.classList.add('chartjs-tooltip');
tooltipEl.style.backgroundColor = backgroundColor;
tooltipEl.style.boxShadow =
' 0px 33.12px 9.399px 0px rgba(0, 0, 0, 0.00), 0px 21.036px 8.504px 0px rgba(0, 0, 0, 0.01), 0px 12.084px 7.161px 0px rgba(0, 0, 0, 0.05), 0px 5.371px 5.371px 0px rgba(0, 0, 0, 0.09), 0px 1.343px 2.685px 0px rgba(0, 0, 0, 0.10)';
tooltipEl.style.borderRadius = '7px';
tooltipEl.style.color = textColor;
tooltipEl.style.opacity = 1;
tooltipEl.style.padding = '2px';
tooltipEl.style.pointerEvents = 'none';
tooltipEl.style.position = 'absolute';
tooltipEl.style.transform = 'translate(-50%, 0)';
tooltipEl.style.transition = 'all .2s ease';
chart.canvas.parentNode.appendChild(tooltipEl);
}
return tooltipEl;
};
return {
maintainAspectRatio: false,
aspectRatio: 0.8,
plugins: {
chartAreaBorder: {
borderColor: 'red',
borderWidth: 2,
borderDash: [5, 5],
borderDashOffset: 2
},
tooltip: {
enabled: false,
padding: 8,
position: 'nearest',
external: function (context) {
// Tooltip Element
const { chart, tooltip } = context;
const tooltipEl = getOrCreateTooltip(chart);
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
if (tooltip.body) {
const bodyLines = tooltip.body.map((b) => {
const strArr = b.lines[0].split(':');
const data = {
text: strArr[0].trim(),
value: strArr[1].trim()
};
return data;
});
// Clear old content
tooltipEl.innerHTML = '';
bodyLines.forEach((body, i) => {
const text = document.createElement('div');
text.appendChild(document.createTextNode(body.value + '.000'));
text.style.fontWeight = '500';
text.style.lineHeight = '21px';
text.style.fontSize = '14px';
tooltipEl.appendChild(text);
});
}
const { offsetLeft: positionX, offsetTop: positionY } = chart.canvas;
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = positionX + tooltip.caretX + 'px';
tooltipEl.style.top = positionY + tooltip.caretY - 40 + 'px';
tooltipEl.style.font = tooltip.options.bodyFont.string;
tooltipEl.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px';
}
},
legend: {
display: false
}
},
scales: {
x: {
stacked: true,
ticks: {
color: textMutedColor,
font: {
weight: 'lighter'
}
},
grid: {
color: 'transparent',
borderColor: 'transparent'
}
},
y: {
display: false,
grace: 14
}
}
};
}
},
components: {}
};
</script>

View File

@ -0,0 +1,349 @@
<template>
<div class="flex gap-4 h-full flex-1 w-full overflow-auto">
<div class="w-64 h-full overflow-hidden border border-surface rounded-2xl flex flex-col">
<div class="flex items-center justify-between gap-2 p-4 border-b border-surface">
<div class="text-xl font-medium leading-7 text-color">Mails</div>
<Button icon="pi pi-plus" class="w-8 h-8" />
</div>
<div class="flex-1 flex flex-col overflow-auto justify-between gap-4 pt-4 pb-4 px-4">
<div class="flex-1 overflow-auto flex flex-col gap-2">
<div v-for="(navData, i) of inboxNavs" :key="i" class="flex flex-col gap-2">
<div class="text-sm font-medium leading-5 text-surface-400 dark:text-surface-500">{{ navData.title }}</div>
<button
v-for="(nav, j) of navData.navs"
:key="j"
@click="activeInboxNav = nav.name"
:class="activeInboxNav === nav.name ? 'text-color bg-emphasis' : 'text-muted-color bg-transparent'"
class="px-4 py-2 rounded-lg flex items-center gap-2 cursor-pointer hover:bg-emphasis transition-all"
>
<i :class="nav.icon"></i>
<span class="font-medium">{{ nav.name }}</span>
</button>
</div>
</div>
<div>
<div class="border border-surface rounded-border px-4 pb-4 pt-3 mb-4">
<div class="font-medium text-color mb-4">Free Version</div>
<ProgressBar
:value="75"
:pt="{
value: {
class: 'bg-red-600'
}
}"
>
<span class="w-full text-center text-sm font-normal text-surface-0 leading-5 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">4 days left</span>
</ProgressBar>
</div>
<Button label="Upgrade to PRO 🚀" outlined class="w-full" />
</div>
</div>
</div>
<div class="flex-1 h-full overflow-hidden flex border border-surface rounded-2xl">
<DataTable
v-model:selection="selectedRows"
scrollable
selectionMode="multiple"
:value="tableData"
:rows="10"
:pt="{
root: {
class: 'w-full flex-1 overflow-x-auto'
},
thead: {
class: 'hidden'
},
header: {
class: 'sticky top-0 z-10'
},
column: {
bodyCell: {
class: '!border-transparent'
}
}
}"
>
<template #header>
<div class="flex xl:items-center justify-between gap-2 flex-col xl:flex-row">
<div class="flex items-center gap-2">
<Checkbox :binary="true" class="mr-1" />
<Button icon="pi pi-envelope" outlined severity="secondary" />
<Button icon="pi pi-exclamation-circle" outlined severity="secondary" />
<Button icon="pi pi-tag" outlined severity="secondary" />
<Button icon="pi pi-inbox" label="Archive" outlined severity="secondary" />
<Button icon="pi pi-trash" label="Trash" outlined severity="secondary" />
</div>
<div class="flex items-center gap-2">
<IconField iconPosition="left" class="w-6/12 xl:max-w-36">
<InputIcon class="pi pi-search"> </InputIcon>
<InputText v-model="search" placeholder="Search" class="w-full" />
</IconField>
<Button icon="pi pi-filter" outlined severity="secondary" />
<Divider layout="vertical" class="m-0" />
<Button icon="pi pi-refresh" outlined severity="secondary" />
<Button label="1 of 15" class="!whitespace-nowrap" outlined severity="secondary" />
<Button icon="pi pi-chevron-left" outlined severity="secondary" />
<Button icon="pi pi-chevron-right" outlined severity="secondary" />
</div>
</div>
</template>
<template #empty>Inbox is empty.</template>
<Column selectionMode="multiple" headerStyle="width: 1rem" style="width: 1rem"></Column>
<Column field="bookmarked" header="" headerStyle="width: 1rem" style="width: 1rem; padding: 0.5rem">
<template #body="{ data }">
<div @click="data.bookmarked = !data.bookmarked" @click.stop>
<i :class="data.bookmarked ? 'pi pi-bookmark-fill' : 'pi pi-bookmark'"></i>
</div>
</template>
</Column>
<Column field="name" header="">
<template #body="{ data }">
<div class="flex items-center">
<OverlayBadge severity="danger" class="w-fit">
<Avatar
v-bind="data.image ? { image: data.image } : { label: data.capName }"
:class="{
'bg-violet-100 text-violet-950 text-xs font-medium': !data.image
}"
class="rounded-md overflow-hidden flex"
/>
</OverlayBadge>
<div class="ml-4 leading-6 text-color font-medium">{{ data.name }}</div>
</div>
</template>
</Column>
<Column field="title" header="" style="min-width: 14rem; max-width: 20rem">
<template #body="{ data }">
<div class="truncate">
<span class="text-color leading-6 mr-2">{{ data.title }}</span>
<span class="text-muted-color leading-5 text-sm">{{ data.message }}</span>
</div>
</template>
</Column>
<Column field="type" header="" style="width: 4rem">
<template #body="{ data }">
<Tag v-if="data.type" severity="secondary" :value="data.type" class="font-medium"></Tag>
</template>
</Column>
<Column field="time" header="" style="width: 4rem">
<template #body="{ data }">
<div class="text-right text-sm leading-5 text-muted-color">{{ data.time }}</div>
</template>
</Column>
</DataTable>
</div>
</div>
</template>
<script>
export default {
name: 'Inbox',
redrawListener: null,
data() {
return {
search: '',
activeInboxNav: 'Inbox',
inboxNavs: [
{
title: 'Navigation',
navs: [
{ name: 'Inbox', icon: 'pi pi-inbox' },
{ name: 'Starry', icon: 'pi pi-star' },
{ name: 'Drafts', icon: 'pi pi-file-o' },
{ name: 'Important', icon: 'pi pi-file-import' },
{ name: 'Sent', icon: 'pi pi-send' },
{ name: 'Archive', icon: 'pi pi-inbox' },
{ name: 'Spam', icon: 'pi pi-info-circle' },
{ name: 'Trash', icon: 'pi pi-trash' }
]
},
{
title: 'Other',
navs: [
{ name: 'Security', icon: 'pi pi-tag' },
{ name: 'Update', icon: 'pi pi-tag' },
{ name: 'Marketing', icon: 'pi pi-tag' },
{ name: 'HR', icon: 'pi pi-tag' }
]
}
],
tableData: [
{
id: 1,
bookmarked: false,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar12.jpg',
active: false,
name: 'Brook Simmons',
type: 'Security',
time: '3:24 PM',
title: 'Important Account Update',
message: "Dear customer, we've made updates to enhance your account security. Please log in to review and complete the necessary steps. Thank you for choosing ABC Corporation."
},
{
id: 2,
bookmarked: false,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar2.png',
active: false,
name: 'Dianne Russell',
type: 'Update',
time: '11:24 AM',
title: 'Weekly Project Update',
message: 'Hi team, attached is the weekly project update. Kindly review the progress and come prepared for our discussion in the upcoming meeting on [Date and Time].'
},
{
id: 3,
bookmarked: true,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar13.jpg',
active: false,
name: 'Amy Elsner',
type: 'Security',
time: '9:24 AM',
title: 'Urgent: Security Alert - Account Compromise',
message: 'Dear user, we detected unauthorized access to your account. Take immediate action to secure your account. Follow the provided link to reset your password. Thank you.'
},
{
id: 4,
bookmarked: false,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/main-avatar.png',
active: false,
name: 'Jacob Jones',
type: 'Marketing',
time: 'Jan 21',
title: 'Exclusive Offer Inside - Limited Time Only',
message: "Greetings, check out our exclusive offer! Don't miss this limited-time deal. Details enclosed in the attached flyer. Act fast; the offer expires on [Date]."
},
{
id: 5,
bookmarked: false,
image: '',
active: false,
name: 'Cameron Watson',
capName: 'CW',
type: 'HR',
time: 'Jan 15',
title: 'Employee Appreciation Event - Save the Date',
message: 'Hello team, mark your calendars for our upcoming Employee Appreciation Event on [Date]. Stay tuned for more details and get ready for a day of celebration!'
},
{
id: 6,
bookmarked: true,
image: '',
active: false,
name: 'Wade Warren',
capName: 'WW',
type: 'Invoice',
time: 'Jan 12',
title: 'Your Recent Purchase - Order Confirmation',
message: 'Hi Wade Warren, secure your spot at the XYZ Conference 2024 with early bird registration. Enjoy discounted rates until [Date].'
},
{
id: 7,
bookmarked: false,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar7.png',
active: false,
name: 'Guy Hawkins',
type: 'Events',
time: 'Jan 11',
title: 'Early Bird Registration Open - XYZ Conference 2024',
message: ' Attention users, we have scheduled system maintenance on Jan 17. Expect minimal service disruption during this period. Thank you for your understanding.'
},
{
id: 8,
bookmarked: false,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar8.png',
active: false,
name: 'Annette Black',
type: '',
time: 'Jan 8',
title: 'Upcoming System Maintenance Notice',
message: "Dear valued customer, as a token of appreciation, we're offering exclusive discounts for VIP customers. Explore the savings in the attached catalog. Expires [Date]."
},
{
id: 9,
bookmarked: true,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar10.jpg',
active: false,
name: 'Darrell Steward',
type: 'Discount',
time: 'Jan 4',
title: 'Special Discounts for VIP Customers',
message: 'Hello Darrell Steward, stay updated with our latest news and highlights in the January edition of our newsletter. Enjoy the read!'
},
{
id: 10,
bookmarked: true,
image: '',
active: false,
name: 'Jerome Bell',
capName: 'JB',
type: 'Newsletter',
time: 'Jan 2',
title: 'Monthly Newsletter - January Edition',
message: "Dear user, we've updated our Terms of Service. Please review the changes to ensure compliance. Your continued use of our services implies acceptance. Thank you."
},
{
id: 11,
bookmarked: false,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg',
active: false,
name: 'Onyama Limba',
type: '',
time: 'Jan 2',
title: 'Exclusive Travel Packages for You',
message: 'Greetings traveler, explore our exclusive travel packages tailored just for you. Plan your next adventure with XYZ Travel. Offers valid until [Date].'
},
{
id: 12,
bookmarked: false,
image: '',
active: false,
name: 'Robert Fox',
capName: 'RF',
type: 'Invitation',
time: '12.12.2023',
title: 'Invitation to Amsterdam',
message: "Hello Robert Fox, you're invited to our upcoming webinar on Amsterdam. Join us on [Date and Time] for an insightful session. Reserve your spot now!"
},
{
id: 13,
bookmarked: true,
image: '',
active: false,
name: 'Courtney Henry',
capName: 'CH',
type: '',
time: '12.09.2023',
title: 'New Arrivals - Check Out the Latest Books',
message: 'Book enthusiasts, discover our latest arrivals! Explore the attached catalog and dive into the world of new releases. Available for purchase starting [Date].'
},
{
id: 14,
bookmarked: true,
image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar9.jpg',
active: false,
name: 'Arlene McCoy',
type: '',
time: '12.04.2023',
title: 'New Product Demo',
message: 'Exclusive demo of our latest product on Thursday.'
},
{
id: 15,
bookmarked: false,
image: '',
active: false,
name: 'Jerome Bell',
capName: 'JB',
type: 'Newsletter',
time: '10.01.2023',
title: 'Monthly Newsletter - January Edition',
message: "Dear user, we've updated our Terms of Service. Please review the changes to ensure compliance. Your continued use of our services implies acceptance. Thank you."
}
],
selectedRows: []
};
},
methods: {},
components: {}
};
</script>

View File

@ -0,0 +1,160 @@
<template>
<div class="flex-1 flex flex-col gap-6 p-6 h-full overflow-y-auto overflow-x-clip overflow-hidden border border-surface rounded-2xl">
<div class="flex flex-wrap gap-4 items-center justify-between">
<SelectButton v-model="value" :options="options" aria-labelledby="basic" />
<div class="flex gap-2.5 items-center">
<IconField iconPosition="left">
<InputIcon class="pi pi-search"> </InputIcon>
<InputText v-model="search" placeholder="Search" />
</IconField>
<Button severity="secondary" outlined>
<OverlayBadge
severity="danger"
size="small"
:pt="{
pcbadge: {
root: {
class: '!min-w-0 !w-2.5 !h-2.5'
}
}
}"
>
<i class="pi pi-bell" />
</OverlayBadge>
</Button>
<Avatar image="https://www.primefaces.org/cdn/primevue/images/landing/apps/avatar11.jpg" shape="circle" class="w-9 h-9 cursor-pointer" />
</div>
</div>
<div class="">
<div class="flex items-center justify-between gap-2 mb-6">
<div class="text-color text-xl font-medium leading-7">Keep watching</div>
<div class="xl:flex hidden items-center gap-2">
<Button :disabled="page === 0" @click="page -= 1" icon="pi pi-chevron-left" severity="secondary" outlined />
<Button :disabled="page === carouselData.length - page" @click="page += 1" icon="pi pi-chevron-right" severity="secondary" outlined />
</div>
<div class="xl:hidden flex items-center gap-2">
<Button :disabled="page === 0" @click="page -= 1" icon="pi pi-chevron-left" severity="secondary" outlined />
<Button :disabled="page === carouselData.length - 3" @click="page += 1" icon="pi pi-chevron-right" severity="secondary" outlined />
</div>
</div>
<Carousel :value="carouselData" :page="page" :numVisible="5" :numScroll="1" :responsiveOptions="responsiveOptions" :showIndicators="false" :showNavigators="false">
<template #item="slotProps">
<div class="p-2 rounded-xl hover:bg-emphasis transition-colors cursor-pointer">
<div class="relative w-full aspect-[195/118.5] rounded-lg overflow-hidden">
<img :src="slotProps.data.image" class="w-full h-full object-cover" alt="Carousel Movie Image" />
<div class="absolute z-10 top-2 right-2 px-2 py-1 text-sm font-medium leading-tight bg-surface-0 dark:bg-surface-950 border border-surface rounded-md">
{{ slotProps.data.point }}
</div>
<div class="absolute z-10 bottom-2 inset-x-2">
<ProgressBar
:value="slotProps.data.watchedPercent"
:showValue="false"
:pt="{
root: {
class: 'h-1.5 bg-surface-950 dark:bg-surface-50 rounded-full'
},
value: {
class: 'bg-surface-0 dark:bg-surface-950 rounded-full'
}
}"
></ProgressBar>
</div>
</div>
<div class="mt-2 flex items-start justify-between gap-1">
<div class="px-2 flex-1">
<div class="font-medium text-color leading-6 line-clamp-1">{{ slotProps.data.name }}</div>
<div class="mt-1 text-muted-color text-sm leading-5">{{ slotProps.data.categories.join(', ') }}</div>
</div>
<Button v-if="slotProps.data.bookmarked" icon="pi pi-bookmark-fill" severity="contrast" text rounded />
</div>
</div>
</template>
</Carousel>
</div>
<div>
<div class="mb-6 flex items-center gap-4 justify-between">
<div class="flex items-center gap-2">
<Button label="Popular" severity="secondary" />
<Button label="New Releases" text severity="secondary" />
<Button label="Recently Added" text severity="secondary" />
<Button label="For you" text severity="secondary" />
</div>
<Button label="Show All" severity="secondary" outlined />
</div>
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-x-4 gap-y-6">
<div v-for="(movie, index) of popularMovies" :key="index" class="cursor-pointer">
<div class="relative aspect-[259/174.5] rounded-lg overflow-hidden">
<img class="w-full h-full object-cover" :src="movie.image" alt="Popular Movie Cover" />
<div class="absolute z-10 top-2 right-2 px-2 py-1 text-sm font-medium leading-tight bg-surface-0 dark:bg-surface-950 border border-surface rounded-md">
{{ movie.point }}
</div>
</div>
<div class="mt-2 flex items-start justify-between gap-1">
<div class="px-2 flex-1">
<div class="font-medium text-color leading-6 line-clamp-1">{{ movie.name }}</div>
<div class="mt-1 text-muted-color text-sm leading-5">{{ movie.categories.join(', ') }}</div>
</div>
<Button v-if="movie.bookmarked" icon="pi pi-bookmark-fill" severity="contrast" text rounded />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Movies',
redrawListener: null,
data() {
return {
search: '',
page: 0,
value: 'Home',
options: ['Home', 'Movies', 'TV Shows', 'Recently Added', 'My List'],
responsiveOptions: [
{
breakpoint: '1199px',
numVisible: 3,
numScroll: 1
},
{
breakpoint: '767px',
numVisible: 2,
numScroll: 1
},
{
breakpoint: '575px',
numVisible: 1,
numScroll: 1
}
],
carouselData: [
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover1.png', name: 'Heat', bookmarked: true, point: '4.7', watchedPercent: 80, categories: ['Action', 'Crime', 'Drama'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover2.png', name: 'Batman Begins', bookmarked: false, point: '4.8', watchedPercent: 45, categories: ['Action', 'Crime', 'Drama'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover3.png', name: 'Leon: The Professional', bookmarked: false, point: '4.3', watchedPercent: 10, categories: ['Action', 'Crime', 'Drama'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover4.png', name: 'Matrix', bookmarked: false, point: '4.9', watchedPercent: 50, categories: ['Action', 'Sci-Fi'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover5.png', name: 'Fight Club', bookmarked: false, point: '4.4', watchedPercent: 30, categories: ['Drama'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover6.png', name: 'The Big Lebowski', bookmarked: false, point: '4.7', watchedPercent: 40, categories: ['Comedy', 'Drama'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover7.png', name: 'Twelve Angry Men', bookmarked: false, point: '4.7', watchedPercent: 50, categories: ['Crime', 'Drama'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover8.png', name: 'Saving Private Ryan', bookmarked: true, point: '4.7', watchedPercent: 80, categories: ['Drama', 'War'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover9.png', name: 'Seven', bookmarked: false, point: '4.7', watchedPercent: 20, categories: ['Crime', 'Drama', 'Mystery'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover10.png', name: 'Shutter Island', bookmarked: false, point: '4.7', watchedPercent: 70, categories: ['Mystery', 'Thriller'] }
],
popularMovies: [
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover7.png', name: 'Twelve Angry Men', bookmarked: false, point: '4.7', categories: ['Crime', 'Drama'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover8.png', name: 'Saving Private Ryan', bookmarked: true, point: '4.7', categories: ['Drama', 'War'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover9.png', name: 'Seven', bookmarked: false, point: '4.7', categories: ['Crime', 'Drama', 'Mystery'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover10.png', name: 'Shutter Island', bookmarked: false, point: '4.7', categories: ['Mystery', 'Thriller'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover11.png', name: 'Basic Instinct', bookmarked: true, point: '4.7', categories: ['Drama', 'Mystery', 'Thriller'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover12.png', name: 'Big Hero 6', bookmarked: false, point: '4.7', categories: ['Animation', 'Action', 'Adventure'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover13.png', name: 'The Lord Of The Rings: Fellowship of the ring', bookmarked: true, point: '4.7', categories: ['Action', 'Adventure', 'Drama'] },
{ image: 'https://www.primefaces.org/cdn/primevue/images/landing/apps/movie-cover14.png', name: 'Kill Bill', bookmarked: true, point: '4.7', categories: ['Action', 'Crime', 'Thriller'] }
]
};
},
methods: {},
components: {}
};
</script>

View File

@ -0,0 +1,429 @@
<template>
<div class="flex-1 h-full overflow-y-auto pb-0.5">
<div class="flex flex-wrap gap-4 items-start justify-between">
<div class="flex-1">
<div class="text-muted-color font-medium leading-normal">Overview</div>
<div class="text-color text-3xl font-semibold leading-normal">Good Morning, Robin 👋</div>
</div>
<div class="flex gap-2 whitespace-nowrap flex-nowrap">
<IconField iconPosition="left">
<InputIcon class="pi pi-search"> </InputIcon>
<InputText placeholder="Search" />
</IconField>
<Button severity="secondary" outlined>
<OverlayBadge
severity="danger"
:pt="{
pcbadge: {
root: {
class: '!min-w-0 !w-2.5 !h-2.5'
}
}
}"
>
<i class="pi pi-bell" />
</OverlayBadge>
</Button>
</div>
</div>
<div class="mt-4 flex flex-wrap gap-6 items-start justify-between">
<SelectButton v-model="selectedTime" :options="timeOptions" aria-labelledby="basic" />
<div class="flex items-center gap-2">
<Button label="Download" icon="pi pi-download" iconPos="right" />
<DatePicker v-model="dates" selectionMode="range" :manualInput="false" showIcon iconDisplay="input" placeholder="06/11/2024 - 06/22/2024" />
</div>
</div>
<div class="flex flex-col gap-6 mt-6">
<div class="w-full border border-surface rounded-2xl py-5 px-7 flex flex-col justify-between">
<div class="flex items-center gap-6 mb-6">
<div class="flex-1 text-color font-semibold leading-6">Crypto Analytics</div>
<div class="flex items-center gap-5">
<div v-for="(item, index) in chartData?.datasets" :key="index" class="flex items-center gap-2">
<div class="p-1 rounded-full border border-surface flex items-center justify-center">
<div class="w-2 h-2 rounded-full" :style="{ backgroundColor: item.backgroundColor }"></div>
</div>
<span class="font-medium text-color leading-6">{{ item.label }}</span>
</div>
</div>
</div>
<Chart type="bar" :data="chartData" :options="chartOptions" class="h-80" />
</div>
<div class="flex gap-6 xl:flex-row flex-col">
<div class="flex-1 border border-surface rounded-2xl py-5 px-7">
<div class="flex items-center gap-6 mb-4">
<div class="flex-1 text-color font-semibold leading-6">Transactions</div>
<Button type="button" icon="pi pi-ellipsis-h" severity="secondary" text @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" />
<Menu ref="menu" id="overlay_menu" :model="menuItems" :popup="true" />
</div>
<DataTable
:value="sampleAppsTableDatas"
paginator
:rows="5"
dataKey="id"
tableClass="overflow-x-auto dark:bg-surface-950"
paginatorTemplate="PrevPageLink PageLinks NextPageLink CurrentPageReport RowsPerPageDropdown"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
:pt="{}"
>
<Column header="Id" class="w-1/12">
<template #body="slotProps">
<div class="text-muted-color">{{ slotProps.data.id }}</div>
</template>
</Column>
<Column header="Name" class="w-1/4">
<template #body="slotProps">
<div class="flex items-center">
<Avatar :label="slotProps.data.name.label" class="mr-2 text-xs font-medium" style="background-color: #ece9fc; color: #2a1261" shape="circle" />
<div class="leading-6 text-muted-color flex-1">{{ slotProps.data.name.text }}</div>
</div>
</template>
</Column>
<Column header="Coin" class="w-1/6">
<template #body="slotProps">
<div class="flex items-center">
<i
:class="[
{
'pi pi-bitcoin text-yellow-500 text-3xl': slotProps.data.coin !== 'btc',
'pi pi-ethereum bg-surface-950 text-surface-0 dark:bg-surface-0 dark:text-surface-950 w-7 h-7 rounded-full flex items-center justify-center': slotProps.data.coin !== 'eth'
}
]"
></i>
</div>
</template>
</Column>
<Column header="Date" class="w-1/6">
<template #body="slotProps">
<div class="text-muted-color">{{ slotProps.data.date }}</div>
</template>
</Column>
<Column header="Process" class="w-1/6">
<template #body="slotProps">
<Tag :severity="slotProps.data.process.type" :value="slotProps.data.process.value" class="font-medium"></Tag>
</template>
</Column>
<Column header="Amount" class="w-1/6">
<template #body="slotProps">
<div class="text-muted-color text-right">{{ slotProps.data.amount }}</div>
</template>
</Column>
</DataTable>
</div>
<div class="xl:w-96 border border-surface rounded-2xl py-5 px-7 flex flex-col justify-between">
<div>
<div class="flex items-center gap-6 mb-6">
<div class="flex-1 text-color font-semibold leading-6">My Wallet</div>
<Button type="button" icon="pi pi-ellipsis-h" severity="secondary" text @click="toggle" aria-haspopup="true" aria-controls="overlay_menu" />
<Menu ref="menu" id="overlay_menu" :model="menuItems" :popup="true" />
</div>
<MeterGroup :value="metersData" labelPosition="end">
<template #label="{ value }">
<div class="flex flex-col gap-6 mt-4">
<template v-for="val of value" :key="val.label">
<div class="flex items-center gap-2">
<div class="w-2 h-2 rounded-full" :style="{ backgroundColor: val.color }"></div>
<div class="text-color uppercase font-medium leading-6 flex-1">
{{ val.label }}
<span class="text-muted-color">({{ val.value }}%)</span>
</div>
<div class="leading-6 font-medium text-color">{{ val.text }}</div>
</div>
</template>
</div>
</template>
</MeterGroup>
</div>
<Button label="Show All" outlined />
</div>
</div>
</div>
</div>
</template>
<script>
import EventBus from '@/layouts/AppEventBus';
export default {
name: 'Overview',
redrawListener: null,
data() {
return {
chartData: {},
chartOptions: {},
chartPlugins: [],
dates: [],
selectedTime: 'Monthly',
timeOptions: ['Monthly', 'Weekly', 'Yearly'],
menuItems: [
{
label: 'Refresh',
icon: 'pi pi-refresh'
},
{
label: 'Export',
icon: 'pi pi-upload'
}
],
sampleAppsTableDatas: [
{ id: '#1254', name: { text: 'Amy Yelsner', label: 'AY', color: 'blue' }, coin: 'btc', date: 'May 5th', process: { type: 'success', value: 'Buy' }, amount: '3.005 BTC' },
{ id: '#2355', name: { text: 'Anna Fali', label: 'AF', color: '#ECFCCB' }, coin: 'eth', date: 'Mar 17th', process: { type: 'success', value: 'Buy' }, amount: '0.050 ETH' },
{ id: '#1235', name: { text: 'Stepen Shaw', label: 'SS', color: '#ECFCCB' }, coin: 'btc', date: 'May 24th', process: { type: 'danger', value: 'Sell' }, amount: '3.050 BTC' },
{ id: '#2355', name: { text: 'Anna Fali', label: 'AF', color: '#ECFCCB' }, coin: 'eth', date: 'Mar 17th', process: { type: 'danger', value: 'Sell' }, amount: '0.050 ETH' },
{ id: '#2355', name: { text: 'Anna Fali', label: 'AF', color: '#ECFCCB' }, coin: 'eth', date: 'Mar 17th', process: { type: 'danger', value: 'Sell' }, amount: '0.050 ETH' },
{ id: '#7896', name: { text: 'John Doe', label: 'JD', color: 'green' }, coin: 'btc', date: 'Jun 12th', process: { type: 'success', value: 'Buy' }, amount: '2.500 BTC' },
{ id: '#5648', name: { text: 'Jane Smith', label: 'JS', color: '#FFDDC1' }, coin: 'eth', date: 'Feb 23rd', process: { type: 'success', value: 'Buy' }, amount: '1.200 ETH' },
{ id: '#3265', name: { text: 'Michael Johnson', label: 'MJ', color: '#FFD700' }, coin: 'btc', date: 'Apr 30th', process: { type: 'danger', value: 'Sell' }, amount: '4.000 BTC' },
{ id: '#1423', name: { text: 'Emily Davis', label: 'ED', color: '#FFCCCB' }, coin: 'btc', date: 'Jan 15th', process: { type: 'danger', value: 'Sell' }, amount: '5.050 LTC' },
{ id: '#6854', name: { text: 'Robert Brown', label: 'RB', color: '#C0C0C0' }, coin: 'eth', date: 'Dec 2nd', process: { type: 'success', value: 'Buy' }, amount: '0.300 ETH' }
],
metersData: [
{ label: 'BTC', color: '#F59E0B', value: 15, text: '27.215' },
{ label: 'ETH', color: '#717179', value: 5, text: '4.367' },
{ label: 'GBP', color: '#22C55E', value: 25, text: '£ 147.562,32' },
{ label: 'EUR', color: '#84CC16', value: 11, text: '€ 137.457,25' },
{ label: 'USD', color: '#14B8A6', value: 29, text: '$ 133.364,12' },
{ label: 'XAU', color: '#EAB308', value: 29, text: '200 g' }
]
};
},
beforeUnmount() {
EventBus.off('dark-mode-toggle-complete', this.redrawListener);
EventBus.off('theme-palette-change', this.redrawListener);
},
mounted() {
this.chartData = this.setChartData();
this.chartOptions = this.setChartOptions();
this.chartPlugings = this.setChartPlugins();
this.redrawListener = () => {
console.log('sss');
this.chartData = this.setChartData();
this.chartOptions = this.setChartOptions();
};
EventBus.on('dark-mode-toggle-complete', this.redrawListener);
EventBus.on('theme-palette-change', this.redrawListener);
},
methods: {
toggle(event) {
this.$refs.menu.toggle(event);
},
setChartData() {
const documentStyle = getComputedStyle(document.documentElement);
return {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
type: 'bar',
label: 'Personal Wallet',
backgroundColor: 'color-mix(in srgb, ' + documentStyle.getPropertyValue('--p-primary-400') + ' 100%, #fff)',
data: [4000, 10000, 15000, 4000, 16000, 8000, 12000, 14000, 17000, 5000, 12000, 6000],
barThickness: 32
},
{
type: 'bar',
label: 'Corporate Wallet',
backgroundColor: 'color-mix(in srgb, ' + documentStyle.getPropertyValue('--p-primary-300') + ' 100%, transparent)',
data: [2100, 8400, 2400, 7500, 3700, 6500, 7400, 8000, 4800, 9000, 7600, 4200],
barThickness: 32
},
{
type: 'bar',
label: 'Investment Wallet',
backgroundColor: 'color-mix(in srgb, ' + documentStyle.getPropertyValue('--p-primary-200') + ' 100%, transparent)',
data: [4100, 5200, 2400, 7400, 2300, 4100, 7200, 8000, 4800, 9000, 7600, 4200],
borderRadius: {
topLeft: 8,
topRight: 8
},
borderSkipped: true,
barThickness: 32
}
]
};
},
setChartOptions() {
const darkMode = document.documentElement.classList.contains('p-dark');
const documentStyle = getComputedStyle(document.documentElement);
const backgroundColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-900' : '--p-surface-0');
const textColor = documentStyle.getPropertyValue('--p-text-color');
const borderColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-800' : '--p-surface-100');
const textMutedColor = documentStyle.getPropertyValue(darkMode ? '--p-surface-500' : '--p-surface-400');
const getOrCreateTooltip = (chart) => {
let tooltipEl = chart.canvas.parentNode.querySelector('div.chartjs-tooltip');
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.classList.add('chartjs-tooltip');
tooltipEl.style.backgroundColor = backgroundColor;
tooltipEl.style.boxShadow = '0px 25px 20px -5px rgba(0, 0, 0, 0.10), 0px 10px 8px -6px rgba(0, 0, 0, 0.10)';
tooltipEl.style.borderRadius = '7px';
tooltipEl.style.color = textColor;
tooltipEl.style.opacity = 1;
tooltipEl.style.width = '232px';
tooltipEl.style.padding = '14.5px';
tooltipEl.style.pointerEvents = 'none';
tooltipEl.style.position = 'absolute';
tooltipEl.style.transform = 'translate(-50%, 0)';
tooltipEl.style.transition = 'all .2s ease';
tooltipEl.style.display = 'flex';
tooltipEl.style.flexDirection = 'column';
tooltipEl.style.gap = '14px';
chart.canvas.parentNode.appendChild(tooltipEl);
}
return tooltipEl;
};
return {
maintainAspectRatio: false,
aspectRatio: 0.8,
plugins: {
chartAreaBorder: {
borderColor: 'red',
borderWidth: 2,
borderDash: [5, 5],
borderDashOffset: 2
},
tooltip: {
enabled: false,
padding: 10,
position: 'nearest',
external: function (context) {
// Tooltip Element
const { chart, tooltip } = context;
const tooltipEl = getOrCreateTooltip(chart);
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
if (tooltip.body) {
const bodyLines = tooltip.body.map((b) => {
const strArr = b.lines[0].split(':');
const data = {
text: strArr[0].trim(),
value: strArr[1].trim()
};
return data;
});
// Clear old content
tooltipEl.innerHTML = '';
bodyLines.forEach((body, i) => {
const colors = tooltip.labelColors[i];
const bodyDiv = document.createElement('div');
bodyDiv.style.display = 'flex';
bodyDiv.style.alignItems = 'center';
bodyDiv.style.justifyContent = 'space-between';
const bodyDivLeft = document.createElement('div');
bodyDivLeft.style.display = 'flex';
bodyDivLeft.style.alignItems = 'center';
bodyDivLeft.style.gap = '4px';
const innerSpan = document.createElement('span');
innerSpan.style.background = colors.backgroundColor;
innerSpan.style.borderColor = colors.borderColor;
innerSpan.style.height = '7px';
innerSpan.style.width = '7px';
innerSpan.style.borderRadius = '99px';
innerSpan.style.display = 'inline-block';
const span = document.createElement('span');
span.style.display = 'inline-flex';
span.style.alignItems = 'center';
span.style.justifyContent = 'center';
span.style.marginRight = '3px';
span.style.padding = '3px';
span.style.border = '1px solid ' + borderColor + '';
span.style.borderRadius = '99px';
span.appendChild(innerSpan);
const text = document.createElement('span');
text.appendChild(document.createTextNode(body.text));
text.style.fontWeight = '500';
text.style.lineHeight = '21px';
bodyDivLeft.appendChild(span);
bodyDivLeft.appendChild(text);
const bodyDivRight = document.createElement('div');
bodyDivRight.appendChild(document.createTextNode(body.value));
bodyDivRight.style.fontWeight = '500';
bodyDivRight.style.lineHeight = '21px';
bodyDiv.appendChild(bodyDivLeft);
bodyDiv.appendChild(bodyDivRight);
tooltipEl.appendChild(bodyDiv);
});
}
const { offsetLeft: positionX, offsetTop: positionY } = chart.canvas;
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = positionX + tooltip.caretX + 'px';
tooltipEl.style.top = positionY + tooltip.caretY + 'px';
tooltipEl.style.font = tooltip.options.bodyFont.string;
tooltipEl.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px';
}
},
legend: {
display: false
}
},
scales: {
x: {
stacked: true,
ticks: {
color: textMutedColor,
font: {
weight: 'lighter'
}
},
grid: {
color: 'transparent',
borderColor: 'transparent'
}
},
y: {
border: {
display: false
},
stacked: true,
ticks: {
color: textMutedColor,
font: {
weight: 'lighter'
}
},
grid: {
color: borderColor,
borderColor: 'transparent'
}
}
}
};
},
setChartPlugins() {
return ['chartAreaBorder'];
}
},
components: {}
};
</script>

View File

@ -6,13 +6,10 @@ const baseUrl = '/';
export default defineNuxtConfig({ export default defineNuxtConfig({
typescript: false, typescript: false,
modules: ['nuxt-gtag', '@primevue/nuxt-module'], modules: ['nuxt-gtag', '@primevue/nuxt-module'],
components: [ components: {
'~/components', path: '~/components',
{ pathPrefix: false
path: '~/components/layout', },
prefetch: false
}
],
vite: { vite: {
resolve: { resolve: {
optimizeDeps: { optimizeDeps: {