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, value: string,
text: string, text: string,
avg?: string, avg?: string,
trend?: number,
color: string, color: string,
data?: number[], data?: number[],
labels?: string[], labels?: string[],
ready?: boolean, ready?: boolean,
slow?: boolean, slow?: boolean,
todayIndex: number todayIndex: number,
tooltipText: string
}>(); }>();
const { snapshotDuration } = useSnapshot() const { snapshotDuration } = useSnapshot()
const uTooltipText = computed(() => { const { showDrawer } = useDrawer();
const duration = snapshotDuration.value;
if (!duration) return '';
if (duration > 25) return 'Monthly trend';
if (duration > 7) return 'Weekly trend';
return 'Daily trend';
})
</script> </script>
@@ -42,25 +36,18 @@ const uTooltipText = computed(() => {
</div> </div>
<div class="poppins text-text-sub text-[.9rem] 2xl:text-[1rem]"> {{ text }} </div> <div class="poppins text-text-sub text-[.9rem] 2xl:text-[1rem]"> {{ text }} </div>
</div> </div>
<div v-if="trend" class="flex flex-col items-center gap-1">
<UTooltip :text="uTooltipText"> <div class="flex flex-col items-center gap-1">
<div class="flex items-center gap-3 rounded-md px-2 py-1" <UTooltip :text="props.tooltipText">
:style="`background-color: ${props.color}33`"> <i class="far fa-info-circle text-lyx-text-darker text-[1rem]"></i>
<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>
</UTooltip> </UTooltip>
<!-- <div class="poppins text-text-sub text-[.7rem]"> Trend </div> -->
</div> </div>
</div> </div>
<div class="absolute bottom-0 left-0 w-full h-[50%] flex items-end" <div class="absolute bottom-0 left-0 w-full h-[50%] flex items-end"
v-if="((props.data?.length || 0) > 0) && ready"> v-if="((props.data?.length || 0) > 0) && ready">
<DashboardEmbedChartCard v-if="ready" :todayIndex="todayIndex" :data="props.data || []" :labels="props.labels || []" <DashboardEmbedChartCard v-if="ready" :todayIndex="todayIndex" :data="props.data || []"
:color="props.color"> :labels="props.labels || []" :color="props.color">
</DashboardEmbedChartCard> </DashboardEmbedChartCard>
</div> </div>
<div v-if="!ready" class="flex justify-center items-center w-full h-full flex-col gap-2"> <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 }[]) { function transformResponse(input: { _id: string, count: number }[]) {
const data = input.map(e => e.count || 0); const data = input.map(e => e.count || 0);
const labels = input.map(e => DateService.getChartLabelFromISO(e._id, new Date().getTimezoneOffset(), chartSlice.value));
const labels = input.map(e => DateService.getChartLabelFromISO(e._id, new Date().getTimezoneOffset(), chartSlice.value)); return { data, labels, input }
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 }
} }
@@ -91,7 +86,7 @@ const avgSessionDuration = computed(() => {
return `${hours > 0 ? hours + 'h ' : ''}${minutes}m ${seconds.toFixed()}s` return `${hours > 0 ? hours + 'h ' : ''}${minutes}m ${seconds.toFixed()}s`
}); });
const todayIndex = computed(()=>{ const todayIndex = computed(() => {
if (!visitsData.data.value) return -1; 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)); 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> <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"> <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" <DashboardCountCard :todayIndex="todayIndex" :ready="!visitsData.pending.value" icon="far fa-earth"
:value="formatNumberK(visitsData.data.value?.data.reduce((a, e) => a + e, 0) || '...')" text="Total visits" :value="formatNumberK(visitsData.data.value?.data.reduce((a, e) => a + e, 0) || '...')"
:avg="formatNumberK(avgVisitDay) + '/day'" :trend="visitsData.data.value?.trend" :avg="formatNumberK(avgVisitDay) + '/day'" :data="visitsData.data.value?.data"
:data="visitsData.data.value?.data" :labels="visitsData.data.value?.labels" color="#5655d7"> tooltipText="Sum of all page views on your website."
:labels="visitsData.data.value?.labels" color="#5655d7">
</DashboardCountCard> </DashboardCountCard>
<DashboardCountCard :todayIndex="todayIndex" :ready="!bouncingRateData.pending.value" icon="far fa-chart-user" text="Bouncing rate" <DashboardCountCard :todayIndex="todayIndex" :ready="!bouncingRateData.pending.value" icon="far fa-chart-user"
:value="avgBouncingRate" :trend="bouncingRateData.data.value?.trend" :slow="true" text="Bouncing rate" :value="avgBouncingRate" :slow="true" :data="bouncingRateData.data.value?.data"
:data="bouncingRateData.data.value?.data" :labels="bouncingRateData.data.value?.labels" color="#1e9b86"> tooltipText="Percentage of users who leave quickly (lower is better)."
:labels="bouncingRateData.data.value?.labels" color="#1e9b86">
</DashboardCountCard> </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) || '...')" :value="formatNumberK(sessionsData.data.value?.data.reduce((a, e) => a + e, 0) || '...')"
:avg="formatNumberK(avgSessionsDay) + '/day'" :trend="sessionsData.data.value?.trend" tooltipText="Count of distinct users visiting your website."
:data="sessionsData.data.value?.data" :labels="sessionsData.data.value?.labels" color="#4abde8"> :avg="formatNumberK(avgSessionsDay) + '/day'" :data="sessionsData.data.value?.data"
:labels="sessionsData.data.value?.labels" color="#4abde8">
</DashboardCountCard> </DashboardCountCard>
<DashboardCountCard :todayIndex="todayIndex" :ready="!sessionsDurationData.pending.value" icon="far fa-timer" text="Visit duration" <DashboardCountCard :todayIndex="todayIndex" :ready="!sessionsDurationData.pending.value" icon="far fa-timer"
:value="avgSessionDuration" :trend="sessionsDurationData.data.value?.trend" text="Visit duration" :value="avgSessionDuration" :data="sessionsDurationData.data.value?.data"
:data="sessionsDurationData.data.value?.data" :labels="sessionsDurationData.data.value?.labels" tooltipText="Average time users spend on your website."
color="#f56523"> :labels="sessionsDurationData.data.value?.labels" color="#f56523">
</DashboardCountCard> </DashboardCountCard>
</div> </div>

View File

@@ -201,10 +201,10 @@ function onKeyDown(e: KeyboardEvent) {
const menuOpen = ref<boolean>(false); const menuOpen = ref<boolean>(false);
const defaultPrompts = [ const defaultPrompts = [
"Create a line chart with this data: \n[100, 200, 30, 300, 500, 40]", "What can you do and how can you help me ?",
"Create a chart with Events (bar) and Visits (line) data from last week.", "Show me an example line chart with random data",
"How many visits did I get last week?", "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) { async function deleteChat(chat_id: string) {
@@ -232,6 +232,15 @@ async function clearAllChats() {
headers: useComputedHeaders({ useSnapshotDates: false }).value headers: useComputedHeaders({ useSnapshotDates: false }).value
}); });
await reloadChatsList(); 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 selfhosted = useSelfhosted();
const { showDrawer } = useDrawer();
</script> </script>
<template> <template>
<div class="dashboard w-full h-full overflow-y-auto overflow-x-hidden pb-[7rem] md:pt-4 lg:pt-0"> <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"> <div v-if="showDashboard">

View File

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