mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 15:58:38 +01:00
rewrite litlyx
This commit is contained in:
6
TODO
6
TODO
@@ -1,8 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
- Refactor UI Data analyst
|
||||||
|
|
||||||
- Reactivity on project delete (update dropdown) + test guest
|
- Reactivity on project delete (update dropdown) + test guest
|
||||||
|
|
||||||
- Event funnel / metadata analyzer / user flow
|
- Event funnel / metadata analyzer / user flow
|
||||||
- Refactor UI Data analyst
|
|
||||||
- Remove Top Events from web analytics and move to custom events (with raw data access)
|
|
||||||
- Fix email on plan upgrade and resub
|
|
||||||
@@ -19,6 +19,18 @@
|
|||||||
src: url("../fonts/GeistVF.ttf");
|
src: url("../fonts/GeistVF.ttf");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.actionable-visits-color-checkbox {
|
||||||
|
color: #5655d7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actionable-sessions-color-checkbox {
|
||||||
|
color: #4abde8;
|
||||||
|
}
|
||||||
|
.actionable-events-color-checkbox {
|
||||||
|
color: #fbbf24;
|
||||||
|
}
|
||||||
|
|
||||||
.geist {
|
.geist {
|
||||||
font-family: "Geist";
|
font-family: "Geist";
|
||||||
}
|
}
|
||||||
@@ -72,10 +84,14 @@
|
|||||||
|
|
||||||
|
|
||||||
.hide-scrollbars {
|
.hide-scrollbars {
|
||||||
-ms-overflow-style: none; /* IE and Edge */
|
-ms-overflow-style: none;
|
||||||
scrollbar-width: none; /* Firefox */
|
/* IE and Edge */
|
||||||
|
scrollbar-width: none;
|
||||||
|
|
||||||
|
/* Firefox */
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
display: none; /* Chrome, Safari and Opera */
|
display: none;
|
||||||
|
/* Chrome, Safari and Opera */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,11 +68,14 @@ function openExternalLink(link: string) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="rawButton" class="hidden lg:flex">
|
<div v-if="rawButton" class="hidden lg:flex">
|
||||||
<div @click="$emit('showRawData')"
|
|
||||||
class="cursor-pointer flex gap-1 items-center justify-center font-semibold poppins rounded-lg text-[#5680f8] hover:text-[#5681f8ce]">
|
<LyxUiButton @click="$emit('showRawData')" type="primary" class="h-fit">
|
||||||
<div> Raw data </div>
|
<div class="flex gap-1 items-center justify-center ">
|
||||||
<div class="flex items-center"> <i class="fas fa-arrow-up-right"></i> </div>
|
<div> Show raw data </div>
|
||||||
</div>
|
<div class="flex items-center"> <i class="fas fa-arrow-up-right"></i> </div>
|
||||||
|
</div>
|
||||||
|
</LyxUiButton>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ function goToView() {
|
|||||||
<div class="flex flex-col gap-2 h-full">
|
<div class="flex flex-col gap-2 h-full">
|
||||||
<BarCardBase :hideShowMore="true" @showGeneral="showGeneral()" @showRawData="goToView()"
|
<BarCardBase :hideShowMore="true" @showGeneral="showGeneral()" @showRawData="goToView()"
|
||||||
@dataReload="currentData.refresh()" @showDetails="showDetails" :data="currentData.data.value || []"
|
@dataReload="currentData.refresh()" @showDetails="showDetails" :data="currentData.data.value || []"
|
||||||
:loading="currentData.pending.value" :label="isPagesView ? 'Top pages' : 'Top Websites'"
|
:loading="currentData.pending.value" :label="isPagesView ? 'Top pages' : 'Top Domains'"
|
||||||
:sub-label="isPagesView ? 'Page' : 'Website'"
|
:sub-label="isPagesView ? 'Page' : 'Domains'"
|
||||||
:desc="isPagesView ? 'Most visited pages' : 'Most visited website in this project'"
|
:desc="isPagesView ? 'Most visited pages' : 'Most visited domains in this project'"
|
||||||
:interactive="!isPagesView" :rawButton="!isLiveDemo()" :isDetailView="isPagesView">
|
:interactive="!isPagesView" :rawButton="!isLiveDemo()" :isDetailView="isPagesView">
|
||||||
</BarCardBase>
|
</BarCardBase>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ const selectLabels: { label: string, value: Slice }[] = [
|
|||||||
{ label: 'Month', value: 'month' },
|
{ label: 'Month', value: 'month' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const selectedSlice = computed(()=>selectLabels[selectedLabelIndex.value].value);
|
const selectedSlice = computed(() => selectLabels[selectedLabelIndex.value].value);
|
||||||
|
|
||||||
const selectedLabelIndex = ref<number>(1);
|
const selectedLabelIndex = ref<number>(1);
|
||||||
const allDatesFull = ref<string[]>([]);
|
const allDatesFull = ref<string[]>([]);
|
||||||
@@ -233,7 +233,13 @@ function onLegendChange(dataset: any, index: number, checked: any) {
|
|||||||
dataset.hidden = !checked;
|
dataset.hidden = !checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
const legendColors = ['#5655d7', '#4abde8', '#fbbf24']
|
const legendColors = ref<string[]>(['#5655d7', '#4abde8', '#fbbf24'])
|
||||||
|
const legendClasses = ref<string[]>([
|
||||||
|
'actionable-visits-color-checkbox',
|
||||||
|
'actionable-sessions-color-checkbox',
|
||||||
|
'actionable-events-color-checkbox'
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
const inLiveDemo = isLiveDemo();
|
const inLiveDemo = isLiveDemo();
|
||||||
|
|
||||||
@@ -256,9 +262,11 @@ const inLiveDemo = isLiveDemo();
|
|||||||
</LyxUiButton>
|
</LyxUiButton>
|
||||||
<div class="flex gap-6">
|
<div class="flex gap-6">
|
||||||
<div v-for="(dataset, index) of chartData.datasets" class="flex gap-2 items-center text-[.9rem]">
|
<div v-for="(dataset, index) of chartData.datasets" class="flex gap-2 items-center text-[.9rem]">
|
||||||
|
|
||||||
<UCheckbox :ui="{
|
<UCheckbox :ui="{
|
||||||
color: `text-[${legendColors[index]}]`
|
color: legendClasses[index]
|
||||||
}" :model-value="true" @change="onLegendChange(dataset, index, $event)"></UCheckbox>
|
}" :model-value="true" @change="onLegendChange(dataset, index, $event)"></UCheckbox>
|
||||||
|
|
||||||
<label class="mt-[2px]"> {{ dataset.label }} </label>
|
<label class="mt-[2px]"> {{ dataset.label }} </label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,18 +30,20 @@ const uTooltipText = computed(() => {
|
|||||||
<LyxUiCard class="flex !p-0 flex-col overflow-hidden relative max-h-[12rem] aspect-[2/1] w-full">
|
<LyxUiCard class="flex !p-0 flex-col overflow-hidden relative max-h-[12rem] aspect-[2/1] w-full">
|
||||||
<div v-if="ready" class="flex p-4 items-start">
|
<div v-if="ready" class="flex p-4 items-start">
|
||||||
<div class="flex items-center mt-2 mr-4">
|
<div class="flex items-center mt-2 mr-4">
|
||||||
<i :style="`color: ${props.color}`" :class="icon" class="text-[1.6rem] 2xl:text-[2rem]"></i>
|
<i :style="`color: ${props.color}`" :class="icon" class="text-[1.3rem] 2xl:text-[1.5rem]"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col grow">
|
<div class="flex flex-col grow">
|
||||||
<div class="flex items-end gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div class="brockmann text-text-dirty text-[1.6rem] 2xl:text-[1.9rem]"> {{ value }} </div>
|
<div class="brockmann text-text-dirty text-[1.2rem] 2xl:text-[1.4rem]">
|
||||||
<div class="poppins text-text-sub text-[.7rem] 2xl:text-[.85rem] mb-2"> {{ avg }} </div>
|
{{ value }}
|
||||||
|
</div>
|
||||||
|
<div class="poppins text-text-sub text-[.65rem] 2xl:text-[.8rem]"> {{ avg }} </div>
|
||||||
</div>
|
</div>
|
||||||
<div class="poppins text-text-sub text-[.9rem] 2xl:text-base"> {{ 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">
|
<div v-if="trend" class="flex flex-col items-center gap-1">
|
||||||
<UTooltip :text="uTooltipText">
|
<UTooltip :text="uTooltipText">
|
||||||
<div class="flex items-center gap-3 rounded-xl px-2 py-1"
|
<div class="flex items-center gap-3 rounded-md px-2 py-1"
|
||||||
:style="`background-color: ${props.color}33`">
|
:style="`background-color: ${props.color}33`">
|
||||||
<i :class="trend > 0 ? 'fa-arrow-trend-up' : 'fa-arrow-trend-down'"
|
<i :class="trend > 0 ? 'fa-arrow-trend-up' : 'fa-arrow-trend-down'"
|
||||||
class="far text-[.9rem] 2xl:text-[1rem]" :style="`color: ${props.color}`"></i>
|
class="far text-[.9rem] 2xl:text-[1rem]" :style="`color: ${props.color}`"></i>
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ const eventsData = await useFetch(`/api/data/count`, { headers: useComputedHeade
|
|||||||
</div>
|
</div>
|
||||||
</LyxUiCard>
|
</LyxUiCard>
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<BarCardEvents :key="refreshKey"></BarCardEvents>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-6 flex-col xl:flex-row h-full">
|
<div class="flex gap-6 flex-col xl:flex-row h-full">
|
||||||
|
|
||||||
<CardTitled :key="refreshKey" class="p-4 flex-[4] w-full h-full" title="Events"
|
<CardTitled :key="refreshKey" class="p-4 flex-[4] w-full h-full" title="Events"
|
||||||
|
|||||||
@@ -42,39 +42,29 @@ const showDashboard = computed(() => project.value && firstInteraction.data.valu
|
|||||||
<BarCardWebsites :key="refreshKey"></BarCardWebsites>
|
<BarCardWebsites :key="refreshKey"></BarCardWebsites>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<BarCardEvents :key="refreshKey"></BarCardEvents>
|
<BarCardReferrers :key="refreshKey"></BarCardReferrers>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex w-full justify-center mt-6 px-6">
|
<div class="flex w-full justify-center mt-6 px-6">
|
||||||
<div class="flex w-full gap-6 flex-col xl:flex-row">
|
<div class="flex w-full gap-6 flex-col xl:flex-row">
|
||||||
<div class="flex-1">
|
|
||||||
<BarCardReferrers :key="refreshKey"></BarCardReferrers>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<BarCardBrowsers :key="refreshKey"></BarCardBrowsers>
|
<BarCardBrowsers :key="refreshKey"></BarCardBrowsers>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex w-full justify-center mt-6 px-6">
|
|
||||||
<div class="flex w-full gap-6 flex-col xl:flex-row">
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<BarCardOperatingSystems :key="refreshKey"></BarCardOperatingSystems>
|
<BarCardOperatingSystems :key="refreshKey"></BarCardOperatingSystems>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
|
||||||
<BarCardGeolocations :key="refreshKey"></BarCardGeolocations>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex w-full justify-center mt-6 px-6">
|
<div class="flex w-full justify-center mt-6 px-6">
|
||||||
<div class="flex w-full gap-6 flex-col xl:flex-row">
|
<div class="flex w-full gap-6 flex-col xl:flex-row">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<BarCardDevices :key="refreshKey"></BarCardDevices>
|
<BarCardGeolocations :key="refreshKey"></BarCardGeolocations>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
|
<BarCardDevices :key="refreshKey"></BarCardDevices>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -114,6 +114,8 @@ async function onPaymentSuccess(event: Event.InvoicePaidEvent) {
|
|||||||
|
|
||||||
const subscription_id = event.data.object.subscription as string;
|
const subscription_id = event.data.object.subscription as string;
|
||||||
|
|
||||||
|
const isNewSubscription = project.subscription_id != subscription_id;
|
||||||
|
|
||||||
const allSubscriptions = await StripeService.getAllSubscriptions(customer_id);
|
const allSubscriptions = await StripeService.getAllSubscriptions(customer_id);
|
||||||
if (!allSubscriptions) return;
|
if (!allSubscriptions) return;
|
||||||
|
|
||||||
@@ -140,7 +142,7 @@ async function onPaymentSuccess(event: Event.InvoicePaidEvent) {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (PLAN.ID == 0) return;
|
if (PLAN.ID == 0) return;
|
||||||
EmailService.sendPurchaseEmail(user.email, project.name);
|
if (isNewSubscription) EmailService.sendPurchaseEmail(user.email, project.name);
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user