mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-10-23 13:05:23 +00:00
more commits.
This commit is contained in:
@@ -61,7 +61,7 @@ const navLinks = [
|
||||
title: 'Account',
|
||||
component: 'account',
|
||||
label: '',
|
||||
icon: 'lucide:circle-user-round',
|
||||
icon: 'lucide:settings',
|
||||
},
|
||||
]
|
||||
const userStore = useUserStore()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
|
||||
.tab-container-default {
|
||||
padding: 15px 15px;
|
||||
padding: 2rem 2rem;
|
||||
}
|
||||
|
||||
.bg-success {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import SidebarNav from '@/components/account/SidebarNav.vue'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
|
||||
const props = defineProps({
|
||||
page: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const currentPage = computed(() => {
|
||||
return props.page
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="md:hidden">
|
||||
<VPImage alt="Forms" width="1280" height="1214" class="block" :image="{
|
||||
dark: '/examples/forms-dark.png',
|
||||
light: '/examples/forms-light.png',
|
||||
}" />
|
||||
</div>
|
||||
<div class="hidden space-y-6 md:block tab-container-default">
|
||||
<div class="space-y-0.5">
|
||||
<h2 class="text-2xl font-bold tracking-tight">
|
||||
Profile settings
|
||||
</h2>
|
||||
<p class="text-muted-foreground">
|
||||
Manage your account settings and set e-mail preferences.
|
||||
</p>
|
||||
</div>
|
||||
<Separator class="my-6" />
|
||||
<div class="flex flex-col space-y-8 lg:flex-row lg:space-x-12 lg:space-y-0">
|
||||
<aside class="-mx-4 lg:w-1/5">
|
||||
<SidebarNav :current-page="currentPage" />
|
||||
</aside>
|
||||
<div class="flex-1 lg:max-w-2xl">
|
||||
<div class="space-y-6">
|
||||
<slot :page="currentPage" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
defineProps({
|
||||
currentPage: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const sidebarNavItems = [
|
||||
{
|
||||
title: 'Profile',
|
||||
href: '/account/profile',
|
||||
},
|
||||
{
|
||||
title: 'Account',
|
||||
href: '/account/account',
|
||||
},
|
||||
{
|
||||
title: 'Appearance',
|
||||
href: '/account/appearance',
|
||||
},
|
||||
{
|
||||
title: 'Notifications',
|
||||
href: '/account/notifications',
|
||||
},
|
||||
{
|
||||
title: 'Display',
|
||||
href: '/account/display',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav class="flex space-x-2 lg:flex-col lg:space-x-0 lg:space-y-1">
|
||||
<router-link v-for="item in sidebarNavItems" :key="item.title" :to="item.href" custom>
|
||||
<template v-slot="{ navigate, isActive }">
|
||||
<Button as="a" :href="item.href" variant="ghost" :class="cn(
|
||||
'w-full text-left justify-start',
|
||||
isActive && 'bg-muted hover:bg-muted'
|
||||
)" @click="navigate">
|
||||
{{ item.title }}
|
||||
</Button>
|
||||
</template>
|
||||
</router-link>
|
||||
</nav>
|
||||
</template>
|
||||
@@ -5,33 +5,6 @@
|
||||
<h3 class="scroll-m-20 text-2xl font-medium flex gap-x-2">
|
||||
Conversations
|
||||
</h3>
|
||||
<div class="w-[8rem]">
|
||||
<Select @update:modelValue="handleFilterChange" v-model="predefinedFilter">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a filter" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<!-- <SelectLabel>Status</SelectLabel> -->
|
||||
<SelectItem value="status_all">
|
||||
All
|
||||
</SelectItem>
|
||||
<SelectItem value="status_open">
|
||||
Open
|
||||
</SelectItem>
|
||||
<SelectItem value="status_processing">
|
||||
Processing
|
||||
</SelectItem>
|
||||
<SelectItem value="status_spam">
|
||||
Spam
|
||||
</SelectItem>
|
||||
<SelectItem value="status_resolved">
|
||||
Resolved
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search -->
|
||||
@@ -58,16 +31,33 @@
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
<div class="space-x-2">
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<button>
|
||||
<ListFilter :size="30" class="p-2 bg-slate-100 rounded-sm" :stroke-width="1.9" />
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="flex flex-col gap-3 w-full">
|
||||
Work in progress.
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<div class="w-[8rem]">
|
||||
<Select @update:modelValue="handleFilterChange" v-model="predefinedFilter">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a filter" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<!-- <SelectLabel>Status</SelectLabel> -->
|
||||
<SelectItem value="status_all">
|
||||
All
|
||||
</SelectItem>
|
||||
<SelectItem value="status_open">
|
||||
Open
|
||||
</SelectItem>
|
||||
<SelectItem value="status_processing">
|
||||
Processing
|
||||
</SelectItem>
|
||||
<SelectItem value="status_spam">
|
||||
Spam
|
||||
</SelectItem>
|
||||
<SelectItem value="status_resolved">
|
||||
Resolved
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -88,13 +78,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex justify-center items-center mt-6 relative"
|
||||
v-if="conversationStore.conversations.hasMore && !hasErrored && hasConversations">
|
||||
<Button variant="link" @click="loadNextPage">
|
||||
<Spinner v-if="conversationStore.conversations.loading" />
|
||||
<p v-else>Load more...</p>
|
||||
</Button>
|
||||
<div class="flex justify-center items-center mt-5 relative">
|
||||
<div v-if="conversationStore.conversations.hasMore && !hasErrored && hasConversations">
|
||||
<Button variant="link" @click="loadNextPage">
|
||||
<Spinner v-if="conversationStore.conversations.loading" />
|
||||
<p v-else>Load more...</p>
|
||||
</Button>
|
||||
</div>
|
||||
<div v-else-if="everythingLoaded">
|
||||
All conversations loaded 😎
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,18 +101,11 @@ import { CONVERSATION_LIST_TYPE, CONVERSATION_PRE_DEFINED_FILTERS } from '@/cons
|
||||
|
||||
import { Error } from '@/components/ui/error'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Search, ListFilter } from 'lucide-vue-next'
|
||||
import {
|
||||
Tabs,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from '@/components/ui/tabs'
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
Select,
|
||||
@@ -179,6 +165,11 @@ const hasErrored = computed(() => {
|
||||
return conversationStore.conversations.errorMessage ? true : false
|
||||
})
|
||||
|
||||
const everythingLoaded = computed(() => {
|
||||
return !conversationStore.conversations.errorMessage && !emptyConversations.value
|
||||
})
|
||||
|
||||
|
||||
const conversationsLoading = computed(() => {
|
||||
return conversationStore.conversations.loading
|
||||
})
|
||||
|
||||
@@ -26,10 +26,11 @@ const routes = [
|
||||
component: UserLoginView
|
||||
},
|
||||
{
|
||||
path: '/account',
|
||||
name: "account",
|
||||
component: AccountView
|
||||
},
|
||||
path: '/account/:page?',
|
||||
name: 'account',
|
||||
component: AccountView,
|
||||
props: true,
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
import { format } from 'date-fns'
|
||||
import { format, differenceInMinutes, differenceInHours, differenceInDays } from 'date-fns';
|
||||
|
||||
export function formatTime (t) {
|
||||
export function formatTime(t) {
|
||||
try {
|
||||
return format(t, 'h:mm a')
|
||||
const now = new Date();
|
||||
const minutesDifference = differenceInMinutes(now, t);
|
||||
const hoursDifference = differenceInHours(now, t);
|
||||
const daysDifference = differenceInDays(now, t);
|
||||
|
||||
if (minutesDifference < 60) {
|
||||
return `${minutesDifference} minutes ago`;
|
||||
} else if (hoursDifference < 24) {
|
||||
return `${hoursDifference} hours ago`;
|
||||
} else if (daysDifference < 7) {
|
||||
return `${daysDifference} days ago`;
|
||||
} else {
|
||||
return format(t, 'MMMM d, yyyy h:mm a');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("error parsing time", error)
|
||||
console.error("error parsing time", error, "time", t)
|
||||
return ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="tab-container-default">
|
||||
<h1>Work in progress.</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
import Account from '@/components/account/Account.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Account>
|
||||
yo
|
||||
</Account>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<!-- Resizable panel last resize value is stored in the localstorage -->
|
||||
<ResizablePanelGroup direction="horizontal" auto-save-id="conversation.vue.resizable.panel">
|
||||
<ResizablePanel :min-size="18" :default-size="23" :max-size="23">
|
||||
<ResizablePanel :min-size="20" :default-size="23" :max-size="23">
|
||||
<ConversationList></ConversationList>
|
||||
</ResizablePanel>
|
||||
<ResizableHandle />
|
||||
|
||||
Reference in New Issue
Block a user