mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 07:48:37 +01:00
update UI
This commit is contained in:
@@ -52,15 +52,6 @@ const { safeSnapshotDates } = useSnapshot();
|
|||||||
Docs
|
Docs
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<UTooltip :text="isDark ? 'Toggle light mode' : 'Toggle dark mode'">
|
|
||||||
<i @click="isDark = !isDark"
|
|
||||||
class="cursor-pointer hover:text-lyx-lightmode-text text-lyx-lightmode-text-dark dark:hover:text-lyx-text dark:text-lyx-text-dark"
|
|
||||||
:class="isDark ? 'far fa-moon' : 'far fa-sun'"></i>
|
|
||||||
</UTooltip>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
145
dashboard/components/layout/VerticalBottomMenu.vue
Normal file
145
dashboard/components/layout/VerticalBottomMenu.vue
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
import { DialogConfirmLogout } from '#components';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { user, isAdmin, setLoggedUser } = useLoggedUser();
|
||||||
|
const { setToken } = useAccessToken();
|
||||||
|
const selfhosted = useSelfhosted();
|
||||||
|
|
||||||
|
const modal = useModal();
|
||||||
|
|
||||||
|
|
||||||
|
function onLogout() {
|
||||||
|
modal.open(DialogConfirmLogout, {
|
||||||
|
onSuccess() {
|
||||||
|
modal.close();
|
||||||
|
console.log('LOGOUT');
|
||||||
|
setToken('');
|
||||||
|
setLoggedUser(undefined);
|
||||||
|
router.push('/login');
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
modal.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorMode = useColorMode()
|
||||||
|
const isDark = computed({
|
||||||
|
get() {
|
||||||
|
return colorMode.value === 'dark'
|
||||||
|
},
|
||||||
|
set() {
|
||||||
|
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const items = computed(() => {
|
||||||
|
|
||||||
|
const slots: any = [];
|
||||||
|
|
||||||
|
if (selfhosted === true) {
|
||||||
|
slots.push([
|
||||||
|
{
|
||||||
|
label: 'Account',
|
||||||
|
icon: 'far fa-user',
|
||||||
|
to: '/account'
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
slots.push([
|
||||||
|
{
|
||||||
|
label: 'Account',
|
||||||
|
icon: 'far fa-user',
|
||||||
|
to: '/account'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Billing',
|
||||||
|
icon: 'far fa-wallet',
|
||||||
|
to: '/billing'
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
slots.push([
|
||||||
|
{
|
||||||
|
label: 'Switch theme',
|
||||||
|
icon: isDark.value ? 'far fa-sun' : 'far fa-moon',
|
||||||
|
click: () => {
|
||||||
|
isDark.value = !isDark.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isAdmin.value === true) {
|
||||||
|
slots.push([
|
||||||
|
{
|
||||||
|
label: 'Admin',
|
||||||
|
icon: 'far fa-cat',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Logout',
|
||||||
|
icon: 'far fa-arrow-right-from-bracket scale-x-[-100%]',
|
||||||
|
click: () => onLogout()
|
||||||
|
}
|
||||||
|
])
|
||||||
|
} else {
|
||||||
|
slots.push([
|
||||||
|
{
|
||||||
|
label: 'Logout',
|
||||||
|
icon: 'far fa-arrow-right-from-bracket scale-x-[-100%]',
|
||||||
|
click: () => onLogout()
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
return slots;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UDropdown :popper="{ placement: 'top' }" class="w-full" :items="items" :ui="{
|
||||||
|
width: 'w-[14rem]',
|
||||||
|
strategy: 'override',
|
||||||
|
background: 'dark:bg-lyx-background bg-lyx-lightmode-background',
|
||||||
|
ring: 'ring-1 dark:ring-lyx-widget-lighter ring-lyx-lightmode-widget',
|
||||||
|
item: {
|
||||||
|
active: 'dark:text-lyx-text text-lyx-lightmode-text dark:bg-lyx-background-lighter bg-lyx-lightmode-background-light'
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
<div class="dark:hover:bg-lyx-widget-light hover:bg-lyx-lightmode-widget cursor-pointer px-1 py-1 rounded-lg text-lyx-lightmode-text-dark dark:text-lyx-text-dark flex items-center gap-2 w-full"
|
||||||
|
v-if="user && user.logged && user.user">
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<div
|
||||||
|
class="flex shrink-0 items-center justify-center h-6 w-6 rounded-full border-solid border-[2px] border-lyx-lightmode-widget dark:border-lyx-widget-lighter">
|
||||||
|
<div class="text-[.8rem] font-medium translate-y-[1px]">
|
||||||
|
{{ user.user.name.substring(0, 1).toUpperCase() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-[.9rem] font-medium poppins overflow-hidden text-ellipsis grow">
|
||||||
|
{{ user.user.email }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-[2rem] text-right pr-1">
|
||||||
|
<i class="fas fa-ellipsis-h brightness-75"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #item="e">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<i class="text-lyx-text-darker" :class="e.item.icon"></i>
|
||||||
|
<div>{{ e.item.label }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</UDropdown>
|
||||||
|
</template>
|
||||||
@@ -32,7 +32,7 @@ const { data: pendingInvites, refresh: refreshInvites } = useFetch('/api/project
|
|||||||
headers: useComputedHeaders({})
|
headers: useComputedHeaders({})
|
||||||
});
|
});
|
||||||
|
|
||||||
const { userRoles, setLoggedUser } = useLoggedUser();
|
const { userRoles } = useLoggedUser();
|
||||||
const { projectList } = useProject();
|
const { projectList } = useProject();
|
||||||
|
|
||||||
const debugMode = process.dev;
|
const debugMode = process.dev;
|
||||||
@@ -92,29 +92,11 @@ async function generatePDF() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { setToken } = useAccessToken();
|
|
||||||
const router = useRouter();
|
|
||||||
const { actions } = useProject();
|
const { actions } = useProject();
|
||||||
|
|
||||||
|
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
|
||||||
|
|
||||||
function onLogout() {
|
|
||||||
modal.open(DialogConfirmLogout, {
|
|
||||||
onSuccess() {
|
|
||||||
modal.close();
|
|
||||||
console.log('LOGOUT');
|
|
||||||
setToken('');
|
|
||||||
setLoggedUser(undefined);
|
|
||||||
router.push('/login');
|
|
||||||
},
|
|
||||||
onCancel() {
|
|
||||||
modal.close();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data: maxProjects } = useFetch("/api/user/max_projects", {
|
const { data: maxProjects } = useFetch("/api/user/max_projects", {
|
||||||
headers: computed(() => {
|
headers: computed(() => {
|
||||||
return {
|
return {
|
||||||
@@ -149,12 +131,12 @@ function openPendingInvites() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="CVerticalNavigation border-solid border-[#D9D9E0] dark:border-[#202020] border-r-[1px] h-full w-[20rem] bg-lyx-lightmode-background dark:bg-lyx-background flex shadow-[1px_0_10px_#000000]"
|
<div class="CVerticalNavigation border-solid border-[#D9D9E0] dark:border-[#202020] border-r-[1px] h-full w-[16rem] bg-lyx-lightmode-background dark:bg-lyx-background flex shadow-[1px_0_10px_#000000]"
|
||||||
:class="{
|
:class="{
|
||||||
'absolute top-0 w-full md:w-[20rem] z-[45] open': isOpen,
|
'absolute top-0 w-full md:w-[20rem] z-[45] open': isOpen,
|
||||||
'hidden lg:flex': !isOpen
|
'hidden lg:flex': !isOpen
|
||||||
}">
|
}">
|
||||||
<div class="py-4 px-2 gap-6 flex flex-col w-full">
|
<div class="py-4 pb-2 px-2 gap-6 flex flex-col w-full">
|
||||||
|
|
||||||
<!-- <div class="flex px-2" v-if="!isPremium">
|
<!-- <div class="flex px-2" v-if="!isPremium">
|
||||||
<LyxUiButton type="primary" class="w-full text-center text-[.8rem] font-medium" @click="pricingDrawer.visible.value = true;">
|
<LyxUiButton type="primary" class="w-full text-center text-[.8rem] font-medium" @click="pricingDrawer.visible.value = true;">
|
||||||
@@ -334,24 +316,12 @@ function openPendingInvites() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-lyx-lightmode-widget dark:bg-[#202020] h-[1px] w-full px-4 mb-3"></div>
|
<LyxUiSeparator class="px-4 mb-2"></LyxUiSeparator>
|
||||||
|
|
||||||
<div class="flex justify-end px-2">
|
<div class="flex px-1 w-full">
|
||||||
|
|
||||||
<div class="grow flex gap-3">
|
<LayoutVerticalBottomMenu></LayoutVerticalBottomMenu>
|
||||||
|
|
||||||
<NuxtLink to="/admin" v-if="userRoles.isAdmin.value"
|
|
||||||
class="cursor-pointer hover:text-lyx-lightmode-text text-lyx-lightmode-text-dark dark:hover:text-lyx-text dark:text-lyx-text-dark">
|
|
||||||
<i class="far fa-cat"></i>
|
|
||||||
</NuxtLink>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<UTooltip text="Logout" :popper="{ arrow: true, placement: 'top' }">
|
|
||||||
<div @click="onLogout()"
|
|
||||||
class="cursor-pointer hover:text-lyx-lightmode-text text-lyx-lightmode-text-dark dark:hover:text-lyx-text dark:text-lyx-text-dark">
|
|
||||||
<i class="far fa-arrow-right-from-bracket scale-x-[-100%]"></i>
|
|
||||||
</div>
|
|
||||||
</UTooltip>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const sections: Section[] = [
|
|||||||
// { label: 'Links (soon)', to: '#', icon: 'fal fa-globe-pointer', disabled: true },
|
// { label: 'Links (soon)', to: '#', icon: 'fal fa-globe-pointer', disabled: true },
|
||||||
// { label: 'Integrations (soon)', to: '/integrations', icon: 'fal fa-cube', disabled: true },
|
// { label: 'Integrations (soon)', to: '/integrations', icon: 'fal fa-cube', disabled: true },
|
||||||
|
|
||||||
{ grow: true, label: 'Settings', to: '/settings', icon: 'fal fa-gear' },
|
{ label: 'Settings', to: '/settings', icon: 'fal fa-gear' },
|
||||||
// {
|
// {
|
||||||
// grow: true,
|
// grow: true,
|
||||||
// label: 'Leave a Feedback', icon: 'fal fa-message',
|
// label: 'Leave a Feedback', icon: 'fal fa-message',
|
||||||
|
|||||||
9
dashboard/pages/account.vue
Normal file
9
dashboard/pages/account.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
definePageMeta({ layout: 'dashboard' });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="p-8">
|
||||||
|
<SettingsAccount></SettingsAccount>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
9
dashboard/pages/billing.vue
Normal file
9
dashboard/pages/billing.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
definePageMeta({ layout: 'dashboard' });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="p-8">
|
||||||
|
<SettingsBilling></SettingsBilling>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -6,10 +6,7 @@ const selfhosted = useSelfhosted();
|
|||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
{ label: 'General', slot: 'general', tab: 'general' },
|
{ label: 'General', slot: 'general', tab: 'general' },
|
||||||
{ label: 'Domains', slot: 'domains', tab: 'domains' },
|
{ label: 'Domains', slot: 'domains', tab: 'domains' }
|
||||||
{ label: 'Billing', slot: 'billing', tab: 'billing' },
|
|
||||||
{ label: 'Codes', slot: 'codes', tab: 'codes' },
|
|
||||||
{ label: 'Account', slot: 'account', tab: 'account' }
|
|
||||||
]
|
]
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -26,14 +23,14 @@ const items = [
|
|||||||
<template #domains>
|
<template #domains>
|
||||||
<SettingsData :key="refreshKey"></SettingsData>
|
<SettingsData :key="refreshKey"></SettingsData>
|
||||||
</template>
|
</template>
|
||||||
<template #billing>
|
<!-- <template #billing>
|
||||||
<SettingsBilling v-if="!selfhosted" :key="refreshKey"></SettingsBilling>
|
<SettingsBilling v-if="!selfhosted" :key="refreshKey"></SettingsBilling>
|
||||||
<div class="flex popping text-[1.2rem] font-semibold justify-center mt-[20vh] text-lyx-lightmode-text dark:text-lyx-text"
|
<div class="flex popping text-[1.2rem] font-semibold justify-center mt-[20vh] text-lyx-lightmode-text dark:text-lyx-text"
|
||||||
v-if="selfhosted">
|
v-if="selfhosted">
|
||||||
Billing disabled in self-host mode
|
Billing disabled in self-host mode
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template> -->
|
||||||
<template #codes>
|
<!-- <template #codes>
|
||||||
<SettingsCodes v-if="!selfhosted" :key="refreshKey"></SettingsCodes>
|
<SettingsCodes v-if="!selfhosted" :key="refreshKey"></SettingsCodes>
|
||||||
<div class="flex popping text-[1.2rem] font-semibold justify-center mt-[20vh] text-lyx-lightmode-text dark:text-lyx-text"
|
<div class="flex popping text-[1.2rem] font-semibold justify-center mt-[20vh] text-lyx-lightmode-text dark:text-lyx-text"
|
||||||
v-if="selfhosted">
|
v-if="selfhosted">
|
||||||
@@ -42,7 +39,7 @@ const items = [
|
|||||||
</template>
|
</template>
|
||||||
<template #account>
|
<template #account>
|
||||||
<SettingsAccount :key="refreshKey"></SettingsAccount>
|
<SettingsAccount :key="refreshKey"></SettingsAccount>
|
||||||
</template>
|
</template> -->
|
||||||
</CustomTab>
|
</CustomTab>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user