mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 07:48:37 +01:00
updating ui
This commit is contained in:
@@ -120,7 +120,14 @@ watch(selected, () => {
|
|||||||
|
|
||||||
<!-- <div class="font-bold text-[1.4rem] text-gray-300"> Litlyx </div> -->
|
<!-- <div class="font-bold text-[1.4rem] text-gray-300"> Litlyx </div> -->
|
||||||
|
|
||||||
<USelectMenu class="w-full" v-if="projects" v-model="selected" :options="projects">
|
<USelectMenu :uiMenu="{
|
||||||
|
select: '!bg-lyx-widget-light !shadow-none focus:!ring-lyx-widget-lighter !ring-lyx-widget-lighter',
|
||||||
|
base: '!bg-lyx-widget',
|
||||||
|
option: {
|
||||||
|
base: 'hover:!bg-lyx-widget-lighter cursor-pointer',
|
||||||
|
active: '!bg-lyx-widget-lighter'
|
||||||
|
}
|
||||||
|
}" class="w-full" v-if="projects" v-model="selected" :options="projects">
|
||||||
|
|
||||||
<template #option="{ option, active, selected }">
|
<template #option="{ option, active, selected }">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
@@ -152,7 +159,7 @@ watch(selected, () => {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="px-4 w-full flex-col">
|
<div class="px-2 w-full flex-col">
|
||||||
|
|
||||||
<div class="flex mb-2 px-2 items-center justify-between">
|
<div class="flex mb-2 px-2 items-center justify-between">
|
||||||
<div class="poppins text-[.8rem]">
|
<div class="poppins text-[.8rem]">
|
||||||
@@ -165,7 +172,14 @@ watch(selected, () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<USelectMenu class="w-full" v-model="snapshot" :options="snapshotsItems">
|
<USelectMenu :uiMenu="{
|
||||||
|
select: '!bg-lyx-widget-light !shadow-none focus:!ring-lyx-widget-lighter !ring-lyx-widget-lighter',
|
||||||
|
base: '!bg-lyx-widget',
|
||||||
|
option: {
|
||||||
|
base: 'hover:!bg-lyx-widget-lighter cursor-pointer',
|
||||||
|
active: '!bg-lyx-widget-lighter'
|
||||||
|
}
|
||||||
|
}" class="w-full" v-model="snapshot" :options="snapshotsItems">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div :style="'background-color:' + snapshot?.color" class="w-2 h-2 rounded-full">
|
<div :style="'background-color:' + snapshot?.color" class="w-2 h-2 rounded-full">
|
||||||
@@ -194,7 +208,7 @@ watch(selected, () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<LyxUiButton @click="generatePDF()" type="primary" class="w-full text-center mt-4">
|
<LyxUiButton @click="generatePDF()" type="secondary" class="w-full text-center mt-4">
|
||||||
Download report
|
Download report
|
||||||
</LyxUiButton>
|
</LyxUiButton>
|
||||||
|
|
||||||
@@ -236,7 +250,7 @@ watch(selected, () => {
|
|||||||
}">
|
}">
|
||||||
|
|
||||||
<NuxtLink @click="close() && entry.action?.()" :target="entry.external ? '_blank' : ''"
|
<NuxtLink @click="close() && entry.action?.()" :target="entry.external ? '_blank' : ''"
|
||||||
tag="div" class="flex items-center" :to="entry.to || '/'">
|
tag="div" class="w-full flex items-center" :to="entry.to || '/'">
|
||||||
<div class="flex items-center w-[1.4rem] mr-2 text-[1.1rem] justify-center">
|
<div class="flex items-center w-[1.4rem] mr-2 text-[1.1rem] justify-center">
|
||||||
<i :class="entry.icon"></i>
|
<i :class="entry.icon"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -267,6 +281,18 @@ watch(selected, () => {
|
|||||||
class="cursor-pointer hover:text-lyx-text text-lyx-text-dark">
|
class="cursor-pointer hover:text-lyx-text text-lyx-text-dark">
|
||||||
<i class="fab fa-discord"></i>
|
<i class="fab fa-discord"></i>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
<NuxtLink to="https://x.com/litlyx" target="_blank"
|
||||||
|
class="cursor-pointer hover:text-lyx-text text-lyx-text-dark">
|
||||||
|
<i class="fab fa-x-twitter"></i>
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="https://dev.to/litlyx-org" target="_blank"
|
||||||
|
class="cursor-pointer hover:text-lyx-text text-lyx-text-dark">
|
||||||
|
<i class="fab fa-dev"></i>
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="/admin" v-if="isAdmin"
|
||||||
|
class="cursor-pointer hover:text-lyx-text text-lyx-text-dark">
|
||||||
|
<i class="fas fa-cat"></i>
|
||||||
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UTooltip text="Logout" :popper="{ arrow: true, placement: 'top' }">
|
<UTooltip text="Logout" :popper="{ arrow: true, placement: 'top' }">
|
||||||
|
|||||||
28
dashboard/components/CustomTab.vue
Normal file
28
dashboard/components/CustomTab.vue
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
type CItem = { label: string, slot: string }
|
||||||
|
const props = defineProps<{ items: CItem[] }>();
|
||||||
|
|
||||||
|
const activeTabIndex = ref<number>(0);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="flex">
|
||||||
|
<div v-for="(tab, index) of items" @click="activeTabIndex = index"
|
||||||
|
class="px-6 pb-3 poppins font-medium text-lyx-text-darker border-b-[1px] border-lyx-text-darker" :class="{
|
||||||
|
'!border-[#88A7FF] text-[#88A7FF]': activeTabIndex === index,
|
||||||
|
'hover:border-lyx-text-dark hover:text-lyx-text-dark cursor-pointer': activeTabIndex !== index
|
||||||
|
}">
|
||||||
|
{{ tab.label }}
|
||||||
|
</div>
|
||||||
|
<div class="border-b-[1px] border-lyx-text-darker w-full">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<slot :name="props.items[activeTabIndex].slot"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
|
|
||||||
export type ButtonType = 'primary' | 'secondary' | 'outline' | 'danger';
|
|
||||||
|
|
||||||
const props = defineProps<{ type: ButtonType, disabled?: boolean }>();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="poppins w-fit cursor-pointer px-4 py-1 rounded-md outline outline-[1px] text-text" :class="{
|
|
||||||
'bg-lyx-primary-dark outline-lyx-primary hover:bg-lyx-primary-hover': type === 'primary',
|
|
||||||
'bg-lyx-widget-lighter outline-lyx-widget-lighter hover:bg-lyx-widget-light': type === 'secondary',
|
|
||||||
'bg-lyx-transparent outline-lyx-widget-lighter hover:bg-lyx-widget-light': type === 'outline',
|
|
||||||
'bg-lyx-danger-dark outline-lyx-danger hover:bg-lyx-danger': type === 'danger',
|
|
||||||
'bg-lyx-widget-lighter outline-lyx-widget-lighter hover:bg-lyx-widget-lighter !cursor-not-allowed !text-lyx-text-darker': disabled === true
|
|
||||||
}">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="w-fit h-fit rounded-md bg-lyx-widget p-4 outline outline-[1px] outline-lyx-background-lighter">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
|
|
||||||
const props = defineProps<{ icon: string }>();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<span class="material-symbols-outlined">
|
|
||||||
{{ props.icon }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<LyxUiCard>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="grow">
|
|
||||||
PROJECT_NAME
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Active
|
|
||||||
</div>
|
|
||||||
<LyxUiIcon icon="drag_indicator"></LyxUiIcon>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<LyxUiButton type="primary">
|
|
||||||
CURRENT_SUBSCRIPTION
|
|
||||||
</LyxUiButton>
|
|
||||||
<div class="poppins font-light text-lyx-text-dark">
|
|
||||||
next billing: NEXT_BILLING_DATE
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</LyxUiCard>
|
|
||||||
</template>
|
|
||||||
39
dashboard/components/settings/Account.vue
Normal file
39
dashboard/components/settings/Account.vue
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { SettingsTemplateEntry } from './Template.vue';
|
||||||
|
|
||||||
|
const entries: SettingsTemplateEntry[] = [
|
||||||
|
{ id: 'delete', title: 'Delete account', text: 'Delete your account' },
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
const { setToken } = useAccessToken();
|
||||||
|
|
||||||
|
async function deleteAccount() {
|
||||||
|
const sure = confirm("Are you sure you want to delete this account ?");
|
||||||
|
if (!sure) return;
|
||||||
|
await $fetch("/api/user/delete_account", {
|
||||||
|
...signHeaders(),
|
||||||
|
method: "DELETE"
|
||||||
|
})
|
||||||
|
|
||||||
|
setToken('');
|
||||||
|
location.href = "/login"
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SettingsTemplate :entries="entries">
|
||||||
|
<template #delete>
|
||||||
|
<div
|
||||||
|
class="outline rounded-lg w-full px-8 py-4 flex flex-col gap-4 outline-[1px] outline-[#541c15] bg-[#1e1412]">
|
||||||
|
<div class="poppins font-semibold"> Deleting this account will also remove its projects </div>
|
||||||
|
<div @click="deleteAccount()"
|
||||||
|
class="text-[#e95b61] poppins font-semibold cursor-pointer hover:text-black hover:bg-red-700 outline rounded-lg w-fit px-8 py-2 outline-[1px] outline-[#532b26] bg-[#291415]">
|
||||||
|
Delete account
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</SettingsTemplate>
|
||||||
|
</template>
|
||||||
57
dashboard/components/settings/General.vue
Normal file
57
dashboard/components/settings/General.vue
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { SettingsTemplateEntry } from './Template.vue';
|
||||||
|
|
||||||
|
|
||||||
|
const entries: SettingsTemplateEntry[] = [
|
||||||
|
{ id: 'pname', title: 'Name', text: 'Project name' },
|
||||||
|
{ id: 'pid', title: 'Id', text: 'Project id' },
|
||||||
|
{ id: 'pscript', title: 'Script', text: 'Universal javascript integration' },
|
||||||
|
{ id: 'pdelete', title: 'Delete', text: 'Delete current project' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const activeProject = useActiveProject();
|
||||||
|
const projectNameInputVal = ref<string>(activeProject.value?.name || '');
|
||||||
|
|
||||||
|
const canChange = computed(() => {
|
||||||
|
if (activeProject.value?.name == projectNameInputVal.value) return false;
|
||||||
|
if (projectNameInputVal.value.length === 0) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SettingsTemplate :entries="entries">
|
||||||
|
<template #pname>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<LyxUiInput class="w-full px-4 py-2" v-model="projectNameInputVal"></LyxUiInput>
|
||||||
|
<LyxUiButton :disabled="!canChange" type="primary"> Change </LyxUiButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #pid>
|
||||||
|
<LyxUiCard class="w-full flex items-center">
|
||||||
|
<div class="grow">{{ activeProject?._id.toString() }}</div>
|
||||||
|
<div><i class="far fa-copy"></i></div>
|
||||||
|
</LyxUiCard>
|
||||||
|
</template>
|
||||||
|
<template #pscript>
|
||||||
|
<LyxUiCard class="w-full flex items-center">
|
||||||
|
<div class="grow">
|
||||||
|
{{ `
|
||||||
|
<script defer data-project="${activeProject?._id}"
|
||||||
|
src="https://cdn.jsdelivr.net/gh/litlyx/litlyx-js/browser/litlyx.js"></script>` }}
|
||||||
|
</div>
|
||||||
|
<div><i class="far fa-copy"></i></div>
|
||||||
|
</LyxUiCard>
|
||||||
|
</template>
|
||||||
|
<template #pdelete>
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<LyxUiButton type="danger">
|
||||||
|
Delete project
|
||||||
|
</LyxUiButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</SettingsTemplate>
|
||||||
|
</template>
|
||||||
37
dashboard/components/settings/Template.vue
Normal file
37
dashboard/components/settings/Template.vue
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
export type SettingsTemplateEntry = {
|
||||||
|
title: string,
|
||||||
|
text: string,
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SettingsTemplateProp = {
|
||||||
|
entries: SettingsTemplateEntry[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<SettingsTemplateProp>();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="mt-10 px-4">
|
||||||
|
<div v-for="(entry, index) of props.entries" class="flex flex-col">
|
||||||
|
<div class="flex">
|
||||||
|
<div class="flex-[2]">
|
||||||
|
<div class="poppins font-medium text-lyx-text">
|
||||||
|
{{ entry.title }}
|
||||||
|
</div>
|
||||||
|
<div class="poppins font-regular text-lyx-text-dark">
|
||||||
|
{{ entry.text }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-[3]">
|
||||||
|
<slot :name="entry.id"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="index < props.entries.length - 1" class="h-[2px] bg-lyx-widget-lighter w-full my-10"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import type { SettingsTemplateEntry } from './Template.vue';
|
||||||
|
|
||||||
const activeProject = useActiveProject();
|
const activeProject = useActiveProject();
|
||||||
|
|
||||||
@@ -56,11 +57,18 @@ function getPremiumName(type: number) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const entries: SettingsTemplateEntry[] = [
|
||||||
|
{ id: 'plan', title: 'Current plan', text: 'Manage current plat for this project' },
|
||||||
|
{ id: 'usage', title: 'Usage', text: 'Show usage of current project' },
|
||||||
|
{ id: 'invoices', title: 'Invoices', text: 'Manage invoices of current project' },
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<div class="relative">
|
||||||
<div class="w-full h-full p-8 overflow-y-auto pb-40 lg:pb-0 relative overflow-x-hidden">
|
|
||||||
|
|
||||||
<Transition name="pdrawer">
|
<Transition name="pdrawer">
|
||||||
<PricingDrawer @onCloseClick="showPricingDrawer = false" :currentSub="planData?.premium_type || 0"
|
<PricingDrawer @onCloseClick="showPricingDrawer = false" :currentSub="planData?.premium_type || 0"
|
||||||
@@ -69,136 +77,123 @@ function getPremiumName(type: number) {
|
|||||||
</PricingDrawer>
|
</PricingDrawer>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
||||||
<div @click="showPricingDrawer = false" v-if="showPricingDrawer"
|
<SettingsTemplate :entries="entries">
|
||||||
class="barrier absolute left-0 top-0 w-full h-full z-[19] bg-black/40 backdrop-blur-[1px]">
|
<template #plan>
|
||||||
</div>
|
<LyxUiCard v-if="planData" class="flex flex-col w-full">
|
||||||
|
<div class="flex flex-col gap-6 px-8 grow">
|
||||||
<div class="poppins font-semibold text-[1.8rem]">
|
<div class="flex justify-between flex-col sm:flex-row">
|
||||||
Billing
|
<div class="flex flex-col">
|
||||||
</div>
|
<div class="flex gap-3 items-center">
|
||||||
|
<div class="poppins font-semibold text-[1.1rem]">
|
||||||
<div class="poppins text-[1.3rem] text-text-sub">
|
{{ planData.premium ? 'Premium plan' : 'Basic plan' }}
|
||||||
Manage your billing cycle for the project
|
</div>
|
||||||
<span class="font-bold">
|
<div
|
||||||
{{ activeProject?.name || '' }}
|
class="flex lato text-[.7rem] bg-accent/25 border-accent/40 border-[1px] px-[.6rem] rounded-lg">
|
||||||
</span>
|
{{ planData.premium ? getPremiumName(planData.premium_type) : 'FREE' }}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="my-4 mb-10 w-full bg-gray-400/30 h-[1px]">
|
<div class="poppins text-text-sub text-[.9rem]">
|
||||||
</div>
|
Our free plan for testing the product.
|
||||||
|
</div>
|
||||||
<div class="flex flex-wrap justify-start gap-8">
|
</div>
|
||||||
<Card v-if="planData" class="px-0 pt-6 pb-4 w-[35rem] flex flex-col">
|
<div class="flex items-center gap-1">
|
||||||
<div class="flex flex-col gap-6 px-8 grow">
|
<div class="poppins font-semibold text-[2rem]"> $0 </div>
|
||||||
<div class="flex justify-between flex-col sm:flex-row">
|
<div class="poppins text-text-sub mt-2"> per month </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="flex gap-3 items-center">
|
<div class="poppins"> Billing period:</div>
|
||||||
|
<div class="flex items-center gap-2 md:gap-4 flex-col pt-4 md:pt-0 md:flex-row">
|
||||||
|
<div class="grow w-full md:w-auto">
|
||||||
|
<UProgress color="green" :min="0" :max="100" :value="leftPercent"></UProgress>
|
||||||
|
</div>
|
||||||
|
<div class="poppins"> {{ daysLeft }} days left </div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center">
|
||||||
|
Subscription: {{ planData.subscription_status }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="my-4 w-full bg-gray-400/30 h-[1px]">
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between px-8 flex-col sm:flex-row">
|
||||||
|
<div class="flex gap-2 text-text-sub text-[.9rem]">
|
||||||
|
<div class="poppins"> Expire date:</div>
|
||||||
|
<div> {{ prettyExpireDate }}</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="!isGuest" @click="onPlanUpgradeClick()"
|
||||||
|
class="cursor-pointer flex items-center gap-2 text-[.9rem] text-white font-semibold bg-accent px-4 py-1 rounded-lg drop-shadow-[0_0_8px_#000000]">
|
||||||
|
<div class="poppins"> Upgrade plan </div>
|
||||||
|
<i class="fas fa-arrow-up-right"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</LyxUiCard>
|
||||||
|
</template>
|
||||||
|
<template #usage>
|
||||||
|
<LyxUiCard v-if="planData" class="flex flex-col w-full">
|
||||||
|
<div class="flex flex-col gap-6 px-8">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<div class="flex flex-col">
|
||||||
<div class="poppins font-semibold text-[1.1rem]">
|
<div class="poppins font-semibold text-[1.1rem]">
|
||||||
{{ planData.premium ? 'Premium plan' : 'Basic plan' }}
|
Usage
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="poppins text-text-sub text-[.9rem]">
|
||||||
class="flex lato text-[.7rem] bg-accent/25 border-accent/40 border-[1px] px-[.6rem] rounded-lg">
|
Check the usage limits of your project.
|
||||||
{{ planData.premium ? getPremiumName(planData.premium_type) : 'FREE' }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="poppins text-text-sub text-[.9rem]">
|
|
||||||
Our free plan for testing the product.
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<div class="poppins font-semibold text-[2rem]"> $0 </div>
|
|
||||||
<div class="poppins text-text-sub mt-2"> per month </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="poppins"> Billing period:</div>
|
|
||||||
<div class="flex items-center gap-2 md:gap-4 flex-col pt-4 md:pt-0 md:flex-row">
|
|
||||||
<div class="grow w-full md:w-auto">
|
|
||||||
<UProgress color="green" :min="0" :max="100" :value="leftPercent"></UProgress>
|
|
||||||
</div>
|
|
||||||
<div class="poppins"> {{ daysLeft }} days left </div>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-center">
|
|
||||||
Subscription: {{ planData.subscription_status }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="my-4 w-full bg-gray-400/30 h-[1px]">
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-between px-8 flex-col sm:flex-row">
|
|
||||||
<div class="flex gap-2 text-text-sub text-[.9rem]">
|
|
||||||
<div class="poppins"> Expire date:</div>
|
|
||||||
<div> {{ prettyExpireDate }}</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="!isGuest" @click="onPlanUpgradeClick()"
|
|
||||||
class="cursor-pointer flex items-center gap-2 text-[.9rem] text-white font-semibold bg-accent px-4 py-1 rounded-lg drop-shadow-[0_0_8px_#000000]">
|
|
||||||
<div class="poppins"> Upgrade plan </div>
|
|
||||||
<i class="fas fa-arrow-up-right"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card v-if="planData" class="px-0 pt-6 pb-4 w-[35rem] flex flex-col">
|
|
||||||
<div class="flex flex-col gap-6 px-8">
|
|
||||||
<div class="flex justify-between">
|
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="poppins font-semibold text-[1.1rem]">
|
<div class="poppins"> Usage:</div>
|
||||||
Usage
|
<div class="flex items-center gap-2 md:gap-4 flex-col pt-4 md:pt-0 md:flex-row">
|
||||||
|
<div class="grow w-full md:w-auto">
|
||||||
|
<UProgress :color="color" :min="0" :max="planData.limit" :value="planData.count">
|
||||||
|
</UProgress>
|
||||||
|
</div>
|
||||||
|
<div class="poppins"> {{ percent }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="poppins text-text-sub text-[.9rem]">
|
<div class="flex justify-center">
|
||||||
Check the usage limits of your project.
|
{{ formatNumberK(planData.count) }} / {{ formatNumberK(planData.limit) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col">
|
</LyxUiCard>
|
||||||
<div class="poppins"> Usage:</div>
|
</template>
|
||||||
<div class="flex items-center gap-2 md:gap-4 flex-col pt-4 md:pt-0 md:flex-row">
|
<template #invoices>
|
||||||
<div class="grow w-full md:w-auto">
|
|
||||||
<UProgress :color="color" :min="0" :max="planData.limit" :value="planData.count">
|
<CardTitled v-if="!isGuest" title="Invoices"
|
||||||
</UProgress>
|
:sub="(invoices && invoices.length == 0) ? 'No invoices yet' : ''" class="p-4 mt-8 w-full">
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center bg-[#161616] p-4 rounded-lg"
|
||||||
|
v-for="invoice of invoices">
|
||||||
|
|
||||||
|
<div> <i class="fal fa-file-invoice"></i> </div>
|
||||||
|
|
||||||
|
<div class="flex flex-col md:flex-row md:justify-around md:grow items-center gap-2">
|
||||||
|
<div> {{ new Date(invoice.date).toLocaleString() }} </div>
|
||||||
|
<div> € {{ invoice.cost / 100 }} </div>
|
||||||
|
<div> {{ invoice.id }} </div>
|
||||||
|
<div
|
||||||
|
class="flex items-center lato text-[.8rem] bg-accent/25 border-accent/40 border-[1px] px-[.6rem] rounded-lg">
|
||||||
|
{{ invoice.status }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<i @click="openInvoice(invoice.link)"
|
||||||
|
class="far fa-download cursor-pointer hover:text-white/80"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="poppins"> {{ percent }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
|
||||||
{{ formatNumberK(planData.count) }} / {{ formatNumberK(planData.limit) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<CardTitled v-if="!isGuest" title="Invoices" :sub="(invoices && invoices.length == 0) ? 'No invoices yet' : ''"
|
|
||||||
class="p-4 mt-8 max-w-[72rem]">
|
|
||||||
|
|
||||||
<div class="flex flex-col gap-2">
|
|
||||||
|
|
||||||
<div class="flex justify-between items-center bg-[#161616] p-4 rounded-lg" v-for="invoice of invoices">
|
|
||||||
|
|
||||||
<div> <i class="fal fa-file-invoice"></i> </div>
|
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row md:justify-around md:grow items-center gap-2">
|
|
||||||
<div> {{ new Date(invoice.date).toLocaleString() }} </div>
|
|
||||||
<div> € {{ invoice.cost / 100 }} </div>
|
|
||||||
<div> {{ invoice.id }} </div>
|
|
||||||
<div
|
|
||||||
class="flex items-center lato text-[.8rem] bg-accent/25 border-accent/40 border-[1px] px-[.6rem] rounded-lg">
|
|
||||||
{{ invoice.status }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
</CardTitled>
|
||||||
<i @click="openInvoice(invoice.link)"
|
</template>
|
||||||
class="far fa-download cursor-pointer hover:text-white/80"></i>
|
</SettingsTemplate>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</CardTitled>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { SettingsTemplateEntry } from './Template.vue';
|
||||||
|
|
||||||
|
|
||||||
definePageMeta({ layout: 'dashboard' });
|
definePageMeta({ layout: 'dashboard' });
|
||||||
|
|
||||||
const activeProject = useActiveProject();
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ key: 'me', label: '' },
|
{ key: 'me', label: '' },
|
||||||
@@ -67,32 +68,31 @@ async function addMember() {
|
|||||||
} catch (ex: any) { }
|
} catch (ex: any) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const entries: SettingsTemplateEntry[] = [
|
||||||
|
{ id: 'add', title: 'Add member', text: 'Add new member to project' },
|
||||||
|
{ id: 'members', title: 'Members', text: 'Manage members of current project' },
|
||||||
|
]
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="home w-full h-full px-10 lg:px-6 overflow-y-auto pb-[12rem] md:pb-0 py-2">
|
<SettingsTemplate :entries="entries">
|
||||||
|
<template #add>
|
||||||
|
<div v-if="!isGuest" class="flex flex-col">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex gap-4 items-center">
|
||||||
|
<LyxUiInput class="px-4 py-1 w-full" placeholder="User email" v-model="addMemberEmail"></LyxUiInput>
|
||||||
<div v-if="!isGuest" @click="showAddMember = !showAddMember;"
|
<LyxUiButton @click="addMember" type="secondary"> Add </LyxUiButton>
|
||||||
class="flex items-center gap-2 bg-menu w-fit px-3 py-2 rounded-lg hover:bg-menu/80 cursor-pointer">
|
</div>
|
||||||
<i class="fas fa-plus"></i>
|
<div class="poppins text-[.8rem] mt-2 text-lyx-text-darker">
|
||||||
<div> Add member </div>
|
User should have been registered to Litlyx
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="showAddMember" class="flex gap-4 items-center">
|
|
||||||
<input v-model="addMemberEmail" class="focus:outline-none bg-menu px-4 py-1 rounded-lg" type="text"
|
|
||||||
placeholder="user email">
|
|
||||||
<div @click="addMember" class="bg-menu w-fit py-1 px-4 rounded-lg hover:bg-menu/80 cursor-pointer">
|
|
||||||
Add
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #members>
|
||||||
|
|
||||||
|
|
||||||
<UTable :rows="members || []" :columns="columns">
|
<UTable :rows="members || []" :columns="columns">
|
||||||
<template #me-data="e">
|
<template #me-data="e">
|
||||||
@@ -108,9 +108,7 @@ async function addMember() {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
</UTable>
|
</UTable>
|
||||||
|
</template>
|
||||||
</div>
|
</SettingsTemplate>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -11,31 +11,32 @@ const sections: Section[] = [
|
|||||||
{
|
{
|
||||||
title: 'General',
|
title: 'General',
|
||||||
entries: [
|
entries: [
|
||||||
{ label: 'Projects', icon: 'far fa-table-layout', to: '/project_selector' },
|
// { label: 'Projects', icon: 'far fa-table-layout', to: '/project_selector' },
|
||||||
// { label: 'Members', icon: 'far fa-users', to: '/members' },
|
// { label: 'Members', icon: 'far fa-users', to: '/members' },
|
||||||
{ label: 'Admin', icon: 'fas fa-cat', adminOnly: true, to: '/admin' },
|
// { label: 'Admin', icon: 'fas fa-cat', adminOnly: true, to: '/admin' },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Project',
|
title: 'Project',
|
||||||
entries: [
|
entries: [
|
||||||
{ label: 'Dashboard', to: '/', icon: 'far fa-table-layout' },
|
{ label: 'Dashboard', to: '/', icon: 'fal fa-table-layout' },
|
||||||
{ label: 'Events', to: '/events', icon: 'far fa-bolt' },
|
{ label: 'Events', to: '/events', icon: 'fal fa-square-bolt' },
|
||||||
{ label: 'Analyst', to: '/analyst', icon: 'far fa-microchip-ai' },
|
{ label: 'Analyst', to: '/analyst', icon: 'fal fa-microchip-ai' },
|
||||||
{ label: 'Settings', to: '/settings', icon: 'far fa-gear' },
|
{ label: 'Settings', to: '/settings', icon: 'fal fa-gear' },
|
||||||
// { label: 'Report', to: '/report', icon: 'far fa-notes' },
|
// { label: 'Report', to: '/report', icon: 'far fa-notes' },
|
||||||
// { label: 'AI', to: '/dashboard/settings', icon: 'far fa-robot brightness-[.4]' },
|
// { label: 'AI', to: '/dashboard/settings', icon: 'far fa-robot brightness-[.4]' },
|
||||||
// { label: 'Visits', to: '/dashboard/visits', icon: 'far fa-eye' },
|
// { label: 'Visits', to: '/dashboard/visits', icon: 'far fa-eye' },
|
||||||
// { label: 'Events', to: '/dashboard/events', icon: 'far fa-line-chart' },
|
// { label: 'Events', to: '/dashboard/events', icon: 'far fa-line-chart' },
|
||||||
|
{
|
||||||
|
label: 'Docs', to: 'https://docs.litlyx.com', icon: 'fal fa-book', external: true,
|
||||||
|
action() { Lit.event('docs_clicked') },
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Non si vede',
|
title: 'Non si vede',
|
||||||
entries: [
|
entries: [
|
||||||
{
|
|
||||||
label: 'Docs', to: 'https://docs.litlyx.com', icon: 'far fa-book-open', external: true,
|
|
||||||
action() { Lit.event('docs_clicked') },
|
|
||||||
},
|
|
||||||
// {
|
// {
|
||||||
// label: 'Github', to: 'https://github.com/litlyx/litlyx', icon: 'fab fa-github', external: true,
|
// label: 'Github', to: 'https://github.com/litlyx/litlyx', icon: 'fab fa-github', external: true,
|
||||||
// action() { Lit.event('git_clicked') },
|
// action() { Lit.event('git_clicked') },
|
||||||
|
|||||||
@@ -69,6 +69,14 @@ const selectLabels = [
|
|||||||
// { label: 'Month', value: 'month' },
|
// { label: 'Month', value: 'month' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const limitAlertActions: any[] = [
|
||||||
|
{
|
||||||
|
label: 'Upgrade', variant: "outline", color: 'white',
|
||||||
|
trailing: true, action: () => { }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@@ -76,18 +84,33 @@ const selectLabels = [
|
|||||||
|
|
||||||
<div class="dashboard w-full h-full overflow-y-auto pb-20 md:pt-4 lg:pt-0">
|
<div class="dashboard w-full h-full overflow-y-auto pb-20 md:pt-4 lg:pt-0">
|
||||||
|
|
||||||
{{ changingProject }}
|
|
||||||
|
|
||||||
<div :key="'home-' + isLiveDemo()" v-if="projects && activeProject && firstInteraction && !changingProject">
|
<div :key="'home-' + isLiveDemo()" v-if="projects && activeProject && firstInteraction && !changingProject">
|
||||||
|
|
||||||
<div class="w-full px-4 py-2">
|
<div class="w-full px-4 py-2">
|
||||||
<div v-if="limitsInfo && limitsInfo.limited"
|
<!-- <div v-if="limitsInfo && !limitsInfo.limited"
|
||||||
class="bg-orange-600 justify-center flex gap-2 py-2 px-4 font-semibold text-[1.2rem] rounded-lg">
|
class="bg-orange-600 justify-center flex gap-2 py-2 px-4 font-semibold text-[1.2rem] rounded-lg">
|
||||||
<div class="poppins text-text"> Limit reached </div>
|
<div class="poppins text-text"> Limit reached </div>
|
||||||
<NuxtLink to="/plans" class="poppins text-[#393972] underline cursor-pointer">
|
<NuxtLink to="/plans" class="poppins text-[#393972] underline cursor-pointer">
|
||||||
Upgrade project
|
Upgrade project
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
|
||||||
|
<div v-if="limitsInfo && limitsInfo.limited" class="w-full bg-[#fbbf2422] p-4 rounded-lg text-[.9rem] flex items-center">
|
||||||
|
<div class="flex flex-col grow">
|
||||||
|
<div class="poppins font-semibold text-[#fbbf24]">
|
||||||
|
Limit reached
|
||||||
|
</div>
|
||||||
|
<div class="poppins text-[#fbbf24]">
|
||||||
|
Litlyx has stopped to collect yur data. Please upgrade the plan for a minimal data loss.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<LyxUiButton type="outline"> Upgrade </LyxUiButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DashboardTopSection></DashboardTopSection>
|
<DashboardTopSection></DashboardTopSection>
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ const items = [
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="px-10 py-8 h-dvh overflow-y-auto">
|
<div class="px-10 py-8 h-dvh overflow-y-auto hide-scrollbars">
|
||||||
<div class="poppins font-semibold text-[1.3rem]"> Settings </div>
|
<div class="poppins font-semibold text-[1.3rem]"> Settings </div>
|
||||||
|
|
||||||
<UTabs :items="items" class="mt-8">
|
<CustomTab :items="items" class="mt-8">
|
||||||
<template #general>
|
<template #general>
|
||||||
TODO
|
<SettingsGeneral></SettingsGeneral>
|
||||||
</template>
|
</template>
|
||||||
<template #members>
|
<template #members>
|
||||||
<SettingsMembers></SettingsMembers>
|
<SettingsMembers></SettingsMembers>
|
||||||
@@ -27,8 +27,23 @@ const items = [
|
|||||||
<SettingsBilling></SettingsBilling>
|
<SettingsBilling></SettingsBilling>
|
||||||
</template>
|
</template>
|
||||||
<template #account>
|
<template #account>
|
||||||
TODO
|
<SettingsAccount></SettingsAccount>
|
||||||
</template>
|
</template>
|
||||||
</UTabs>
|
</CustomTab>
|
||||||
|
|
||||||
|
<!-- <UTabs :items="items" class="mt-8">
|
||||||
|
<template #general>
|
||||||
|
<SettingsGeneral></SettingsGeneral>
|
||||||
|
</template>
|
||||||
|
<template #members>
|
||||||
|
<SettingsMembers></SettingsMembers>
|
||||||
|
</template>
|
||||||
|
<template #billing>
|
||||||
|
<SettingsBilling></SettingsBilling>
|
||||||
|
</template>
|
||||||
|
<template #account>
|
||||||
|
<SettingsAccount></SettingsAccount>
|
||||||
|
</template>
|
||||||
|
</UTabs> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
Reference in New Issue
Block a user