fix cards index

This commit is contained in:
Emily
2024-12-20 15:56:06 +01:00
parent 7009a0ad02
commit 39c42e7bd5
5 changed files with 53 additions and 60 deletions

View File

@@ -5,24 +5,18 @@ const props = defineProps<{
value: string,
text: string,
avg?: string,
trend?: number,
color: string,
data?: number[],
labels?: string[],
ready?: boolean,
slow?: boolean,
todayIndex: number
todayIndex: number,
tooltipText: string
}>();
const { snapshotDuration } = useSnapshot()
const uTooltipText = computed(() => {
const duration = snapshotDuration.value;
if (!duration) return '';
if (duration > 25) return 'Monthly trend';
if (duration > 7) return 'Weekly trend';
return 'Daily trend';
})
const { showDrawer } = useDrawer();
</script>
@@ -42,25 +36,18 @@ const uTooltipText = computed(() => {
</div>
<div class="poppins text-text-sub text-[.9rem] 2xl:text-[1rem]"> {{ text }} </div>
</div>
<div v-if="trend" class="flex flex-col items-center gap-1">
<UTooltip :text="uTooltipText">
<div class="flex items-center gap-3 rounded-md px-2 py-1"
:style="`background-color: ${props.color}33`">
<i :class="trend > 0 ? 'fa-arrow-trend-up' : 'fa-arrow-trend-down'"
class="far text-[.9rem] 2xl:text-[1rem]" :style="`color: ${props.color}`"></i>
<div :style="`color: ${props.color}`" class="font-semibold text-[.75rem] 2xl:text-[.875rem]">
{{ trend.toFixed(0) }} %
</div>
</div>
<div class="flex flex-col items-center gap-1">
<UTooltip :text="props.tooltipText">
<i class="far fa-info-circle text-lyx-text-darker text-[1rem]"></i>
</UTooltip>
<!-- <div class="poppins text-text-sub text-[.7rem]"> Trend </div> -->
</div>
</div>
<div class="absolute bottom-0 left-0 w-full h-[50%] flex items-end"
v-if="((props.data?.length || 0) > 0) && ready">
<DashboardEmbedChartCard v-if="ready" :todayIndex="todayIndex" :data="props.data || []" :labels="props.labels || []"
:color="props.color">
<DashboardEmbedChartCard v-if="ready" :todayIndex="todayIndex" :data="props.data || []"
:labels="props.labels || []" :color="props.color">
</DashboardEmbedChartCard>
</div>
<div v-if="!ready" class="flex justify-center items-center w-full h-full flex-col gap-2">

View File

@@ -13,24 +13,19 @@ const chartSlice = computed(() => {
});
function findFirstZeroOrNullIndex(arr: (number | null)[]) {
for (let i = 0; i < arr.length; i++) {
if (arr.slice(i).every(val => val === 0 || val === null)) return i;
}
return -1;
}
function transformResponse(input: { _id: string, count: number }[]) {
const data = input.map(e => e.count || 0);
const labels = input.map(e => DateService.getChartLabelFromISO(e._id, new Date().getTimezoneOffset(), chartSlice.value));
const pool = [...input.map(e => e.count || 0)];
const avg = pool.reduce((a, e) => a + e, 0) / pool.length;
const targets = input.slice(Math.floor(input.length / 4 * 3));
const targetAvg = targets.reduce((a, e) => a + e.count, 0) / targets.length;
const diffPercent: number = (100 / avg * (targetAvg)) - 100;
const trend = Math.max(Math.min(diffPercent, 99), -99);
return { data, labels, trend, input }
return { data, labels, input }
}
@@ -91,7 +86,7 @@ const avgSessionDuration = computed(() => {
return `${hours > 0 ? hours + 'h ' : ''}${minutes}m ${seconds.toFixed()}s`
});
const todayIndex = computed(()=>{
const todayIndex = computed(() => {
if (!visitsData.data.value) return -1;
return visitsData.data.value.input.findIndex(e => new Date(e._id).getTime() > (Date.now() - new Date().getTimezoneOffset() * 1000 * 60));
})
@@ -103,29 +98,33 @@ const todayIndex = computed(()=>{
<template>
<div class="gap-6 px-6 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-2 m-cards-wrap:grid-cols-4">
<DashboardCountCard :todayIndex="todayIndex" :ready="!visitsData.pending.value" icon="far fa-earth" text="Total visits"
:value="formatNumberK(visitsData.data.value?.data.reduce((a, e) => a + e, 0) || '...')"
:avg="formatNumberK(avgVisitDay) + '/day'" :trend="visitsData.data.value?.trend"
:data="visitsData.data.value?.data" :labels="visitsData.data.value?.labels" color="#5655d7">
<DashboardCountCard :todayIndex="todayIndex" :ready="!visitsData.pending.value" icon="far fa-earth"
text="Total visits" :value="formatNumberK(visitsData.data.value?.data.reduce((a, e) => a + e, 0) || '...')"
:avg="formatNumberK(avgVisitDay) + '/day'" :data="visitsData.data.value?.data"
tooltipText="Sum of all page views on your website."
:labels="visitsData.data.value?.labels" color="#5655d7">
</DashboardCountCard>
<DashboardCountCard :todayIndex="todayIndex" :ready="!bouncingRateData.pending.value" icon="far fa-chart-user" text="Bouncing rate"
:value="avgBouncingRate" :trend="bouncingRateData.data.value?.trend" :slow="true"
:data="bouncingRateData.data.value?.data" :labels="bouncingRateData.data.value?.labels" color="#1e9b86">
<DashboardCountCard :todayIndex="todayIndex" :ready="!bouncingRateData.pending.value" icon="far fa-chart-user"
text="Bouncing rate" :value="avgBouncingRate" :slow="true" :data="bouncingRateData.data.value?.data"
tooltipText="Percentage of users who leave quickly (lower is better)."
:labels="bouncingRateData.data.value?.labels" color="#1e9b86">
</DashboardCountCard>
<DashboardCountCard :todayIndex="todayIndex" :ready="!sessionsData.pending.value" icon="far fa-user" text="Unique visitors"
<DashboardCountCard :todayIndex="todayIndex" :ready="!sessionsData.pending.value" icon="far fa-user"
text="Unique visitors"
:value="formatNumberK(sessionsData.data.value?.data.reduce((a, e) => a + e, 0) || '...')"
:avg="formatNumberK(avgSessionsDay) + '/day'" :trend="sessionsData.data.value?.trend"
:data="sessionsData.data.value?.data" :labels="sessionsData.data.value?.labels" color="#4abde8">
tooltipText="Count of distinct users visiting your website."
:avg="formatNumberK(avgSessionsDay) + '/day'" :data="sessionsData.data.value?.data"
:labels="sessionsData.data.value?.labels" color="#4abde8">
</DashboardCountCard>
<DashboardCountCard :todayIndex="todayIndex" :ready="!sessionsDurationData.pending.value" icon="far fa-timer" text="Visit duration"
:value="avgSessionDuration" :trend="sessionsDurationData.data.value?.trend"
:data="sessionsDurationData.data.value?.data" :labels="sessionsDurationData.data.value?.labels"
color="#f56523">
<DashboardCountCard :todayIndex="todayIndex" :ready="!sessionsDurationData.pending.value" icon="far fa-timer"
text="Visit duration" :value="avgSessionDuration" :data="sessionsDurationData.data.value?.data"
tooltipText="Average time users spend on your website."
:labels="sessionsDurationData.data.value?.labels" color="#f56523">
</DashboardCountCard>
</div>

View File

@@ -201,10 +201,10 @@ function onKeyDown(e: KeyboardEvent) {
const menuOpen = ref<boolean>(false);
const defaultPrompts = [
"Create a line chart with this data: \n[100, 200, 30, 300, 500, 40]",
"Create a chart with Events (bar) and Visits (line) data from last week.",
"What can you do and how can you help me ?",
"Show me an example line chart with random data",
"How many visits did I get last week?",
"Create a line chart of last week's visits."
"Create a line chart of last week's visits"
]
async function deleteChat(chat_id: string) {
@@ -232,6 +232,15 @@ async function clearAllChats() {
headers: useComputedHeaders({ useSnapshotDates: false }).value
});
await reloadChatsList();
menuOpen.value = false;
typer.stop();
canSend.value = true;
currentChatMessages.value = [];
currentChatMessageDelta.value = '';
currentChatId.value = '';
}

View File

@@ -33,16 +33,12 @@ const showDashboard = computed(() => project.value && firstInteraction.data.valu
const selfhosted = useSelfhosted();
const { showDrawer } = useDrawer();
</script>
<template>
<div class="dashboard w-full h-full overflow-y-auto overflow-x-hidden pb-[7rem] md:pt-4 lg:pt-0">
<div @click="showDrawer('DOCS','!w-[30vw] !min-w-[30vw]')">
test
</div>
<div v-if="showDashboard">

View File

@@ -1,6 +1,5 @@
<script setup lang="ts">
definePageMeta({ layout: 'dashboard' });
const projectName = ref<string>("");
const creating = ref<boolean>(false);
@@ -8,15 +7,18 @@ const creating = ref<boolean>(false);
const router = useRouter();
const { projectList, actions } = useProject();
const isFirstProject = computed(() => { return projectList.value?.length == 0; })
definePageMeta({ layout: 'none' });
import { Lit } from 'litlyx-js';
const route = useRoute();
onMounted(() => {
if (route.query.just_logged) return location.href = '/project_creation';
setPageLayout(isFirstProject.value ? 'none' : 'dashboard');
})