mirror of
https://github.com/ChrispyBacon-dev/DockFlare.git
synced 2026-04-28 03:39:32 +00:00
webmail - dark / light mode - UI refinements
This commit is contained in:
parent
652e110d2e
commit
1f31021ae8
27 changed files with 1512 additions and 946 deletions
BIN
webmail/public/logo.gif
Normal file
BIN
webmail/public/logo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 MiB |
|
|
@ -541,7 +541,8 @@ if (__VLS_ctx.store.isComposeOpen && (__VLS_ctx.effectivePanelMode || !__VLS_ctx
|
|||
...{ onBlur: (__VLS_ctx.toHandlers.onBlur) },
|
||||
...{ onPaste: (__VLS_ctx.toHandlers.onPaste) },
|
||||
placeholder: "Add recipient…",
|
||||
...{ class: "flex-1 min-w-[120px] bg-transparent text-sm text-foreground placeholder:text-muted-foreground focus:outline-none py-0.5" },
|
||||
...{ class: "flex-1 min-w-[120px] bg-transparent text-foreground placeholder:text-muted-foreground focus:outline-none py-0.5" },
|
||||
...{ style: {} },
|
||||
});
|
||||
(__VLS_ctx.toInput);
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
|
|
@ -674,7 +675,8 @@ if (__VLS_ctx.store.isComposeOpen && (__VLS_ctx.effectivePanelMode || !__VLS_ctx
|
|||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.select, __VLS_intrinsicElements.select)({
|
||||
value: (__VLS_ctx.fromAddress),
|
||||
...{ class: "flex-1 px-2 py-2 text-sm bg-background text-foreground focus:outline-none" },
|
||||
...{ class: "flex-1 px-2 py-2 bg-transparent text-foreground focus:outline-none" },
|
||||
...{ style: {} },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.option, __VLS_intrinsicElements.option)({
|
||||
value: (__VLS_ctx.store.currentMailbox),
|
||||
|
|
@ -690,7 +692,8 @@ if (__VLS_ctx.store.isComposeOpen && (__VLS_ctx.effectivePanelMode || !__VLS_ctx
|
|||
}
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
|
||||
placeholder: "Subject",
|
||||
...{ class: "w-full px-4 py-2 text-sm bg-background text-foreground placeholder:text-muted-foreground focus:outline-none" },
|
||||
...{ class: "w-full px-4 py-2 bg-transparent text-foreground placeholder:text-muted-foreground focus:outline-none" },
|
||||
...{ style: {} },
|
||||
});
|
||||
(__VLS_ctx.subject);
|
||||
const __VLS_32 = {}.EditorContent;
|
||||
|
|
@ -1332,7 +1335,6 @@ if (__VLS_ctx.store.isComposeOpen && (__VLS_ctx.effectivePanelMode || !__VLS_ctx
|
|||
/** @type {__VLS_StyleScopedClasses['flex-1']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['min-w-[120px]']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['bg-transparent']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-foreground']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['placeholder:text-muted-foreground']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['focus:outline-none']} */ ;
|
||||
|
|
@ -1443,15 +1445,13 @@ if (__VLS_ctx.store.isComposeOpen && (__VLS_ctx.effectivePanelMode || !__VLS_ctx
|
|||
/** @type {__VLS_StyleScopedClasses['flex-1']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['px-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['py-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['bg-background']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['bg-transparent']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-foreground']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['focus:outline-none']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['py-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['bg-background']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['bg-transparent']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-foreground']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['placeholder:text-muted-foreground']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['focus:outline-none']} */ ;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, type Component } from 'vue'
|
||||
import {
|
||||
Inbox, FileText, Send, Trash2, AlertCircle, Archive, Folder,
|
||||
Inbox, FileText, Send, Trash2, AlertCircle, Archive, Folder, FolderOpen,
|
||||
FolderPlus, X,
|
||||
} from 'lucide-vue-next'
|
||||
import { TooltipRoot, TooltipTrigger, TooltipContent, TooltipPortal } from 'radix-vue'
|
||||
|
|
@ -26,7 +26,7 @@ const PALETTE = [
|
|||
'#3b82f6', '#8b5cf6', '#ec4899', '#14b8a6',
|
||||
]
|
||||
|
||||
const getIcon = (name: string): Component => iconMap[name] || Folder
|
||||
const getIcon = (name: string, active = false): Component => iconMap[name] || (active ? FolderOpen : Folder)
|
||||
|
||||
const systemFolders = computed(() => store.folders.filter((f: any) => f.system_folder))
|
||||
const customFolders = computed(() => store.folders.filter((f: any) => !f.system_folder))
|
||||
|
|
@ -142,7 +142,7 @@ const confirmEdit = async () => {
|
|||
)"
|
||||
@click="selectFolder(f.name)"
|
||||
>
|
||||
<component :is="getIcon(f.name)" class="size-4" :style="f.color && store.currentFolder !== f.name ? `color:${f.color}` : ''" />
|
||||
<component :is="getIcon(f.name, store.currentFolder === f.name)" class="size-4" :style="f.color && store.currentFolder !== f.name ? `color:${f.color}` : ''" />
|
||||
<span class="sr-only">{{ f.name }}</span>
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
|
|
@ -203,7 +203,7 @@ const confirmEdit = async () => {
|
|||
class="flex flex-1 items-center gap-3 px-3 py-2 text-left min-w-0"
|
||||
@click="selectFolder(f.name)"
|
||||
>
|
||||
<component :is="getIcon(f.name)" class="size-4 flex-shrink-0" :style="f.color ? `color:${f.color}` : ''" />
|
||||
<component :is="getIcon(f.name, store.currentFolder === f.name)" class="size-4 flex-shrink-0" :style="f.color && store.currentFolder !== f.name ? `color:${f.color}` : ''" />
|
||||
<span class="truncate">{{ f.name }}</span>
|
||||
<span
|
||||
v-if="f.total_count > 0"
|
||||
|
|
@ -246,9 +246,8 @@ const confirmEdit = async () => {
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Section label: Custom (expanded only) -->
|
||||
<!-- Custom folders (expanded only) -->
|
||||
<template v-if="!isCollapsed && customFolders.length">
|
||||
<p class="px-3 pt-3 pb-1 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground/60 select-none">Custom</p>
|
||||
<template v-for="f in customFolders" :key="f.name + '-custom'">
|
||||
<!-- Expanded row — inline edit mode -->
|
||||
<div v-if="editingFolder?.id === f.id" class="rounded-md border bg-muted p-2 flex flex-col gap-2">
|
||||
|
|
@ -271,7 +270,7 @@ const confirmEdit = async () => {
|
|||
)"
|
||||
>
|
||||
<button class="flex flex-1 items-center gap-3 px-3 py-2 text-left min-w-0" @click="selectFolder(f.name)">
|
||||
<component :is="getIcon(f.name)" class="size-4 flex-shrink-0" :style="f.color ? `color:${f.color}` : ''" />
|
||||
<component :is="getIcon(f.name, store.currentFolder === f.name)" class="size-4 flex-shrink-0" :style="f.color && store.currentFolder !== f.name ? `color:${f.color}` : ''" />
|
||||
<span class="truncate">{{ f.name }}</span>
|
||||
<span v-if="f.total_count > 0" :class="cn('ml-auto text-xs flex-shrink-0 flex gap-1', store.currentFolder === f.name ? 'opacity-90' : 'text-muted-foreground')">
|
||||
<span v-if="f.unread_count" class="rounded-full px-1.5 py-0.5 text-[10.5px] font-bold leading-none flex items-center" style="background: rgba(251,166,18,0.12); color: #FBA612;">{{ f.unread_count }}</span>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/// <reference types="../../../node_modules/.vue-global-types/vue_3.5_0_0_0.d.ts" />
|
||||
import { computed, ref } from 'vue';
|
||||
import { Inbox, FileText, Send, Trash2, AlertCircle, Archive, Folder, FolderPlus, } from 'lucide-vue-next';
|
||||
import { Inbox, FileText, Send, Trash2, AlertCircle, Archive, Folder, FolderOpen, FolderPlus, } from 'lucide-vue-next';
|
||||
import { TooltipRoot, TooltipTrigger, TooltipContent, TooltipPortal } from 'radix-vue';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { useMailStore } from '../../stores/mail';
|
||||
|
|
@ -18,7 +18,7 @@ const PALETTE = [
|
|||
'#ef4444', '#f97316', '#eab308', '#22c55e',
|
||||
'#3b82f6', '#8b5cf6', '#ec4899', '#14b8a6',
|
||||
];
|
||||
const getIcon = (name) => iconMap[name] || Folder;
|
||||
const getIcon = (name, active = false) => iconMap[name] || (active ? FolderOpen : Folder);
|
||||
const systemFolders = computed(() => store.folders.filter((f) => f.system_folder));
|
||||
const customFolders = computed(() => store.folders.filter((f) => !f.system_folder));
|
||||
const selectFolder = (name) => {
|
||||
|
|
@ -155,7 +155,7 @@ for (const [f] of __VLS_getVForSourceType(((__VLS_ctx.isCollapsed ? __VLS_ctx.st
|
|||
? 'df-folder-active'
|
||||
: 'text-muted-foreground')) },
|
||||
});
|
||||
const __VLS_8 = ((__VLS_ctx.getIcon(f.name)));
|
||||
const __VLS_8 = ((__VLS_ctx.getIcon(f.name, __VLS_ctx.store.currentFolder === f.name)));
|
||||
// @ts-ignore
|
||||
const __VLS_9 = __VLS_asFunctionalComponent(__VLS_8, new __VLS_8({
|
||||
...{ class: "size-4" },
|
||||
|
|
@ -274,15 +274,15 @@ for (const [f] of __VLS_getVForSourceType(((__VLS_ctx.isCollapsed ? __VLS_ctx.st
|
|||
} },
|
||||
...{ class: "flex flex-1 items-center gap-3 px-3 py-2 text-left min-w-0" },
|
||||
});
|
||||
const __VLS_20 = ((__VLS_ctx.getIcon(f.name)));
|
||||
const __VLS_20 = ((__VLS_ctx.getIcon(f.name, __VLS_ctx.store.currentFolder === f.name)));
|
||||
// @ts-ignore
|
||||
const __VLS_21 = __VLS_asFunctionalComponent(__VLS_20, new __VLS_20({
|
||||
...{ class: "size-4 flex-shrink-0" },
|
||||
...{ style: (f.color ? `color:${f.color}` : '') },
|
||||
...{ style: (f.color && __VLS_ctx.store.currentFolder !== f.name ? `color:${f.color}` : '') },
|
||||
}));
|
||||
const __VLS_22 = __VLS_21({
|
||||
...{ class: "size-4 flex-shrink-0" },
|
||||
...{ style: (f.color ? `color:${f.color}` : '') },
|
||||
...{ style: (f.color && __VLS_ctx.store.currentFolder !== f.name ? `color:${f.color}` : '') },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_21));
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
|
||||
...{ class: "truncate" },
|
||||
|
|
@ -306,7 +306,7 @@ for (const [f] of __VLS_getVForSourceType(((__VLS_ctx.isCollapsed ? __VLS_ctx.st
|
|||
}
|
||||
if (!f.system_folder) {
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: (__VLS_ctx.cn('absolute right-1 flex gap-0.5 opacity-0 group-hover/row:opacity-100 transition-opacity rounded px-0.5', __VLS_ctx.store.currentFolder === f.name ? 'bg-primary' : 'bg-accent')) },
|
||||
...{ class: (__VLS_ctx.cn('absolute right-1 flex gap-0.5 opacity-0 group-hover/row:opacity-100 [@media(hover:none)]:opacity-100 transition-opacity rounded px-0.5', __VLS_ctx.store.currentFolder === f.name ? 'bg-primary' : 'bg-accent')) },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
|
||||
...{ onClick: (...[$event]) => {
|
||||
|
|
@ -360,9 +360,6 @@ for (const [f] of __VLS_getVForSourceType(((__VLS_ctx.isCollapsed ? __VLS_ctx.st
|
|||
}
|
||||
}
|
||||
if (!__VLS_ctx.isCollapsed && __VLS_ctx.customFolders.length) {
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.p, __VLS_intrinsicElements.p)({
|
||||
...{ class: "px-3 pt-3 pb-1 text-[10px] font-semibold uppercase tracking-widest text-muted-foreground/60 select-none" },
|
||||
});
|
||||
for (const [f] of __VLS_getVForSourceType((__VLS_ctx.customFolders))) {
|
||||
(f.name + '-custom');
|
||||
if (__VLS_ctx.editingFolder?.id === f.id) {
|
||||
|
|
@ -431,15 +428,15 @@ if (!__VLS_ctx.isCollapsed && __VLS_ctx.customFolders.length) {
|
|||
} },
|
||||
...{ class: "flex flex-1 items-center gap-3 px-3 py-2 text-left min-w-0" },
|
||||
});
|
||||
const __VLS_28 = ((__VLS_ctx.getIcon(f.name)));
|
||||
const __VLS_28 = ((__VLS_ctx.getIcon(f.name, __VLS_ctx.store.currentFolder === f.name)));
|
||||
// @ts-ignore
|
||||
const __VLS_29 = __VLS_asFunctionalComponent(__VLS_28, new __VLS_28({
|
||||
...{ class: "size-4 flex-shrink-0" },
|
||||
...{ style: (f.color ? `color:${f.color}` : '') },
|
||||
...{ style: (f.color && __VLS_ctx.store.currentFolder !== f.name ? `color:${f.color}` : '') },
|
||||
}));
|
||||
const __VLS_30 = __VLS_29({
|
||||
...{ class: "size-4 flex-shrink-0" },
|
||||
...{ style: (f.color ? `color:${f.color}` : '') },
|
||||
...{ style: (f.color && __VLS_ctx.store.currentFolder !== f.name ? `color:${f.color}` : '') },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_29));
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
|
||||
...{ class: "truncate" },
|
||||
|
|
@ -696,15 +693,6 @@ if (!__VLS_ctx.isCollapsed) {
|
|||
/** @type {__VLS_StyleScopedClasses['rounded']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['hover:text-destructive']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['size-3']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['px-3']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['pt-3']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['pb-1']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-muted-foreground/60']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['select-none']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['rounded-md']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['border']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['bg-muted']} */ ;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -183,36 +183,9 @@ const mobileTitle = computed(() => {
|
|||
<div class="absolute top-0 left-0 right-0 h-px pointer-events-none z-10" style="background: rgba(255,255,255,0.62)" />
|
||||
|
||||
<!-- Header: wordmark + collapse toggle -->
|
||||
<div class="h-[54px] flex items-center px-[14px] flex-shrink-0">
|
||||
<div class="h-[54px] flex items-center justify-center px-[14px] flex-shrink-0">
|
||||
<template v-if="!store.isCollapsed">
|
||||
<span class="font-['Outfit'] font-extrabold text-[17px] tracking-[-0.01em] leading-none select-none whitespace-nowrap">
|
||||
<span class="text-[#194466] dark:text-[#5EB1E5]">Dock</span><span class="text-[#FBA612]">Flare</span>
|
||||
</span>
|
||||
<div class="ml-auto flex items-center gap-1">
|
||||
<TooltipRoot :delay-duration="0">
|
||||
<TooltipTrigger as-child>
|
||||
<button class="inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent/60 transition-colors" @click="store.toggleViewMode()">
|
||||
<Columns2 v-if="store.viewMode === 'full'" class="size-3.5" />
|
||||
<Maximize2 v-else class="size-3.5" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipPortal>
|
||||
<TooltipContent side="bottom" class="z-50 rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md">
|
||||
{{ store.viewMode === 'full' ? 'Split view' : 'Full view' }}
|
||||
</TooltipContent>
|
||||
</TooltipPortal>
|
||||
</TooltipRoot>
|
||||
<TooltipRoot :delay-duration="0">
|
||||
<TooltipTrigger as-child>
|
||||
<button class="inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent/60 transition-colors" @click="store.isCollapsed = true">
|
||||
<PanelLeftClose class="size-3.5" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipPortal>
|
||||
<TooltipContent side="bottom" class="z-50 rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md">Collapse sidebar</TooltipContent>
|
||||
</TooltipPortal>
|
||||
</TooltipRoot>
|
||||
</div>
|
||||
<img src="/logo.gif" alt="DockFlare" class="h-7 w-auto select-none" draggable="false" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="font-['Outfit'] font-extrabold text-[15px] leading-none select-none mx-auto">
|
||||
|
|
@ -221,20 +194,6 @@ const mobileTitle = computed(() => {
|
|||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Expand button — only when collapsed, below DF logo -->
|
||||
<div v-if="store.isCollapsed" class="flex justify-center pb-1 flex-shrink-0">
|
||||
<TooltipRoot :delay-duration="0">
|
||||
<TooltipTrigger as-child>
|
||||
<button class="inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent/60 transition-colors" @click="store.isCollapsed = false">
|
||||
<PanelLeftOpen class="size-3.5" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipPortal>
|
||||
<TooltipContent side="right" class="z-50 rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md">Expand sidebar</TooltipContent>
|
||||
</TooltipPortal>
|
||||
</TooltipRoot>
|
||||
</div>
|
||||
|
||||
<!-- Mailbox selector — only when multiple mailboxes -->
|
||||
<div v-if="store.mailboxes.length > 1 && !store.isCollapsed" class="px-3 pb-2 flex-shrink-0">
|
||||
<MailboxSelector :is-collapsed="false" />
|
||||
|
|
@ -273,9 +232,15 @@ const mobileTitle = computed(() => {
|
|||
:class="store.isCollapsed
|
||||
? 'flex flex-col items-center gap-1 px-2 py-3 flex-shrink-0'
|
||||
: 'px-3 py-3 flex-shrink-0 space-y-0.5'"
|
||||
style="border-top: 1px solid rgba(128,128,128,0.1);"
|
||||
>
|
||||
<template v-if="!store.isCollapsed">
|
||||
<button
|
||||
class="flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm text-muted-foreground hover:bg-accent/60 hover:text-foreground transition-colors"
|
||||
@click="store.isCollapsed = true"
|
||||
>
|
||||
<PanelLeftClose class="size-4" />
|
||||
Collapse sidebar
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm text-muted-foreground hover:bg-accent/60 hover:text-foreground transition-colors"
|
||||
@click="store.toggleTheme()"
|
||||
|
|
@ -300,6 +265,16 @@ const mobileTitle = computed(() => {
|
|||
</button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<TooltipRoot :delay-duration="0">
|
||||
<TooltipTrigger as-child>
|
||||
<button class="inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent transition-colors" @click="store.isCollapsed = false">
|
||||
<PanelLeftOpen class="size-4" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipPortal>
|
||||
<TooltipContent side="right" class="z-50 rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md">Expand sidebar</TooltipContent>
|
||||
</TooltipPortal>
|
||||
</TooltipRoot>
|
||||
<TooltipRoot :delay-duration="0">
|
||||
<TooltipTrigger as-child>
|
||||
<button class="inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent transition-colors" @click="store.toggleTheme()">
|
||||
|
|
@ -347,7 +322,7 @@ const mobileTitle = computed(() => {
|
|||
:default-size="35"
|
||||
:min-size="25"
|
||||
class="flex flex-col overflow-hidden"
|
||||
style="background: var(--df-list-bg); backdrop-filter: var(--df-list-blur); box-shadow: 2px 0 10px rgba(0,0,0,0.035);"
|
||||
style="background: var(--df-list-bg); backdrop-filter: var(--df-list-blur);"
|
||||
>
|
||||
<MessageList />
|
||||
</SplitterPanel>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -541,7 +541,6 @@ const sendInlineReply = async () => {
|
|||
|
||||
<AttachmentBar :attachments="message.attachments" />
|
||||
|
||||
<Separator class="mt-auto print-hide" />
|
||||
|
||||
<div class="p-4 print-hide">
|
||||
<form @submit.prevent="sendInlineReply">
|
||||
|
|
@ -586,12 +585,16 @@ const sendInlineReply = async () => {
|
|||
.df-reply-wrapper :deep(textarea) {
|
||||
background: transparent !important;
|
||||
}
|
||||
:global(.dark) .df-reply-wrapper {
|
||||
.dark .df-reply-wrapper {
|
||||
background: rgba(255, 255, 255, 0.09);
|
||||
border: 1px solid rgba(255, 255, 255, 0.13);
|
||||
}
|
||||
:global(.dark) .df-reply-wrapper :deep(textarea) {
|
||||
.dark .df-reply-wrapper :deep(textarea) {
|
||||
color: hsl(210 40% 92%);
|
||||
caret-color: hsl(210 40% 92%);
|
||||
}
|
||||
.dark .df-reply-wrapper :deep(textarea)::placeholder {
|
||||
color: hsl(210 30% 70%);
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -334,6 +334,11 @@ let __VLS_components;
|
|||
let __VLS_directives;
|
||||
/** @type {__VLS_StyleScopedClasses['df-reply-wrapper']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-reply-wrapper']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-reply-wrapper']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-reply-wrapper']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-reply-wrapper']} */ ;
|
||||
// CSS variable injection
|
||||
// CSS variable injection end
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
|
|
@ -1231,14 +1236,6 @@ if (__VLS_ctx.message) {
|
|||
const __VLS_300 = __VLS_299({
|
||||
attachments: (__VLS_ctx.message.attachments),
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_299));
|
||||
/** @type {[typeof Separator, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_302 = __VLS_asFunctionalComponent(Separator, new Separator({
|
||||
...{ class: "mt-auto print-hide" },
|
||||
}));
|
||||
const __VLS_303 = __VLS_302({
|
||||
...{ class: "mt-auto print-hide" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_302));
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "p-4 print-hide" },
|
||||
});
|
||||
|
|
@ -1253,36 +1250,36 @@ if (__VLS_ctx.message) {
|
|||
});
|
||||
/** @type {[typeof Textarea, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_305 = __VLS_asFunctionalComponent(Textarea, new Textarea({
|
||||
const __VLS_302 = __VLS_asFunctionalComponent(Textarea, new Textarea({
|
||||
modelValue: (__VLS_ctx.replyText),
|
||||
...{ class: "p-2 min-h-[80px] bg-transparent border-0 shadow-none focus-visible:ring-0" },
|
||||
placeholder: (`Reply ${__VLS_ctx.message.from_name || __VLS_ctx.message.from_address}...`),
|
||||
}));
|
||||
const __VLS_306 = __VLS_305({
|
||||
const __VLS_303 = __VLS_302({
|
||||
modelValue: (__VLS_ctx.replyText),
|
||||
...{ class: "p-2 min-h-[80px] bg-transparent border-0 shadow-none focus-visible:ring-0" },
|
||||
placeholder: (`Reply ${__VLS_ctx.message.from_name || __VLS_ctx.message.from_address}...`),
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_305));
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_302));
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "flex items-center" },
|
||||
});
|
||||
/** @type {[typeof Button, typeof Button, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_308 = __VLS_asFunctionalComponent(Button, new Button({
|
||||
const __VLS_305 = __VLS_asFunctionalComponent(Button, new Button({
|
||||
type: "submit",
|
||||
size: "sm",
|
||||
...{ class: "ml-auto" },
|
||||
disabled: (__VLS_ctx.sendingReply || !__VLS_ctx.replyText.trim()),
|
||||
}));
|
||||
const __VLS_309 = __VLS_308({
|
||||
const __VLS_306 = __VLS_305({
|
||||
type: "submit",
|
||||
size: "sm",
|
||||
...{ class: "ml-auto" },
|
||||
disabled: (__VLS_ctx.sendingReply || !__VLS_ctx.replyText.trim()),
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_308));
|
||||
__VLS_310.slots.default;
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_305));
|
||||
__VLS_307.slots.default;
|
||||
(__VLS_ctx.sendingReply ? 'Sending...' : 'Send');
|
||||
var __VLS_310;
|
||||
var __VLS_307;
|
||||
}
|
||||
else {
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
|
|
@ -1515,8 +1512,6 @@ else {
|
|||
/** @type {__VLS_StyleScopedClasses['p-4']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['whitespace-pre-wrap']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['mt-auto']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['print-hide']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['p-4']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['print-hide']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['grid']} */ ;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,16 +1,16 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { ArrowDownUp, Trash2 } from 'lucide-vue-next'
|
||||
|
||||
const props = defineProps({
|
||||
hideTitle: { type: Boolean, default: false },
|
||||
})
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { ArrowDownUp, Trash2, Square, CheckSquare, FolderInput } from 'lucide-vue-next'
|
||||
import {
|
||||
TabsRoot, TabsList, TabsTrigger, TabsContent,
|
||||
} from 'radix-vue'
|
||||
import {
|
||||
ScrollAreaRoot, ScrollAreaViewport, ScrollAreaScrollbar, ScrollAreaThumb,
|
||||
} from 'radix-vue'
|
||||
import {
|
||||
DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuContent,
|
||||
DropdownMenuItem, DropdownMenuPortal,
|
||||
} from 'radix-vue'
|
||||
import { useMailStore } from '../../stores/mail'
|
||||
import { mailApi } from '../../api/mail'
|
||||
import MessageListItem from './MessageListItem.vue'
|
||||
|
|
@ -18,9 +18,17 @@ import SearchBar from './SearchBar.vue'
|
|||
import Dialog from '../ui/Dialog.vue'
|
||||
import Button from '../ui/Button.vue'
|
||||
|
||||
const props = defineProps({
|
||||
hideTitle: { type: Boolean, default: false },
|
||||
})
|
||||
|
||||
const store = useMailStore()
|
||||
const showTrashConfirm = ref(false)
|
||||
|
||||
const bulkSelectMode = ref(false)
|
||||
const selectedIds = ref<Set<string>>(new Set())
|
||||
const isBulkLoading = ref(false)
|
||||
|
||||
const folderColor = computed(() => store.currentFolderObj?.color || '')
|
||||
|
||||
const unreadMessages = computed(() =>
|
||||
|
|
@ -43,11 +51,48 @@ const displayMessages = computed(() => {
|
|||
})
|
||||
})
|
||||
|
||||
const trashFolder = computed(() => store.folders.find((f: any) => f.name === 'Trash'))
|
||||
const otherFolders = computed(() => store.folders.filter((f: any) => f.name !== store.currentFolder))
|
||||
const hasSelection = computed(() => selectedIds.value.size > 0)
|
||||
const allSelected = computed(() =>
|
||||
displayMessages.value.length > 0 && selectedIds.value.size === displayMessages.value.length
|
||||
)
|
||||
|
||||
watch(() => store.activeTab, () => {
|
||||
selectedIds.value = new Set()
|
||||
})
|
||||
|
||||
const toggleSort = () => {
|
||||
store.sortOrder = store.sortOrder === 'desc' ? 'asc' : 'desc'
|
||||
}
|
||||
|
||||
function toggleBulkSelect() {
|
||||
bulkSelectMode.value = !bulkSelectMode.value
|
||||
if (!bulkSelectMode.value) {
|
||||
selectedIds.value = new Set()
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSelectAll() {
|
||||
if (allSelected.value) {
|
||||
selectedIds.value = new Set()
|
||||
} else {
|
||||
selectedIds.value = new Set(displayMessages.value.map((m: any) => m.id))
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMessageSelection(id: string) {
|
||||
const next = new Set(selectedIds.value)
|
||||
if (next.has(id)) next.delete(id)
|
||||
else next.add(id)
|
||||
selectedIds.value = next
|
||||
}
|
||||
|
||||
const selectMessage = (msg: any) => {
|
||||
if (bulkSelectMode.value) {
|
||||
toggleMessageSelection(msg.id)
|
||||
return
|
||||
}
|
||||
if (msg.is_draft) {
|
||||
let parsed = msg.to_addresses
|
||||
if (typeof parsed === 'string') {
|
||||
|
|
@ -86,6 +131,46 @@ const performEmptyTrash = async () => {
|
|||
showTrashConfirm.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function bulkMoveToTrash() {
|
||||
if (!hasSelection.value || !trashFolder.value) return
|
||||
isBulkLoading.value = true
|
||||
try {
|
||||
await mailApi.moveMessages(store.currentMailbox, {
|
||||
message_ids: [...selectedIds.value],
|
||||
folder_id: trashFolder.value.id,
|
||||
})
|
||||
store.messages = (store.messages as any[]).filter((m: any) => !selectedIds.value.has(m.id)) as any
|
||||
selectedIds.value = new Set()
|
||||
const fRes = await mailApi.getFolders(store.currentMailbox)
|
||||
store.folders = fRes.data
|
||||
store.showToast('Messages moved to Trash', 'success')
|
||||
} catch {
|
||||
store.showToast('Failed to move messages to Trash')
|
||||
} finally {
|
||||
isBulkLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function bulkMoveToFolder(folderId: number, folderName: string) {
|
||||
if (!hasSelection.value) return
|
||||
isBulkLoading.value = true
|
||||
try {
|
||||
await mailApi.moveMessages(store.currentMailbox, {
|
||||
message_ids: [...selectedIds.value],
|
||||
folder_id: folderId,
|
||||
})
|
||||
store.messages = (store.messages as any[]).filter((m: any) => !selectedIds.value.has(m.id)) as any
|
||||
selectedIds.value = new Set()
|
||||
const fRes = await mailApi.getFolders(store.currentMailbox)
|
||||
store.folders = fRes.data
|
||||
store.showToast(`Messages moved to ${folderName}`, 'success')
|
||||
} catch {
|
||||
store.showToast('Failed to move messages')
|
||||
} finally {
|
||||
isBulkLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -93,14 +178,95 @@ const performEmptyTrash = async () => {
|
|||
<div class="flex items-center px-4 flex-shrink-0" :class="hideTitle ? 'h-[44px]' : 'h-[52px]'">
|
||||
<h1 v-if="!hideTitle" class="text-xl font-bold">{{ store.currentFolder || 'Inbox' }}</h1>
|
||||
<div class="flex items-center gap-1" :class="hideTitle ? 'w-full justify-between' : 'ml-auto'">
|
||||
|
||||
<!-- Bulk action controls (visible when bulkSelectMode active) -->
|
||||
<template v-if="bulkSelectMode">
|
||||
<!-- Select all -->
|
||||
<button
|
||||
class="inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors"
|
||||
:title="allSelected ? 'Deselect all' : 'Select all'"
|
||||
@click="toggleSelectAll"
|
||||
>
|
||||
<CheckSquare v-if="allSelected" class="size-4" />
|
||||
<Square v-else class="size-4" />
|
||||
</button>
|
||||
|
||||
<!-- Move to trash (hidden when already in Trash) -->
|
||||
<button
|
||||
v-if="store.currentFolder !== 'Trash'"
|
||||
class="inline-flex h-9 w-9 items-center justify-center rounded-md transition-colors"
|
||||
:class="hasSelection && !isBulkLoading
|
||||
? 'text-muted-foreground hover:bg-destructive hover:text-destructive-foreground'
|
||||
: 'text-muted-foreground/30 cursor-not-allowed'"
|
||||
:disabled="!hasSelection || isBulkLoading"
|
||||
title="Move to Trash"
|
||||
@click="bulkMoveToTrash"
|
||||
>
|
||||
<Trash2 class="size-4" />
|
||||
</button>
|
||||
|
||||
<!-- Move to folder dropdown -->
|
||||
<DropdownMenuRoot>
|
||||
<DropdownMenuTrigger as-child>
|
||||
<button
|
||||
class="inline-flex h-9 w-9 items-center justify-center rounded-md transition-colors"
|
||||
:class="hasSelection && !isBulkLoading
|
||||
? 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'
|
||||
: 'text-muted-foreground/30 cursor-not-allowed'"
|
||||
:disabled="!hasSelection || isBulkLoading"
|
||||
title="Move to folder"
|
||||
>
|
||||
<FolderInput class="size-4" />
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuContent
|
||||
align="end"
|
||||
:side-offset="4"
|
||||
class="z-50 min-w-[160px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
|
||||
>
|
||||
<DropdownMenuItem
|
||||
v-for="folder in otherFolders"
|
||||
:key="folder.id"
|
||||
class="relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground"
|
||||
@click="bulkMoveToFolder(folder.id, folder.name)"
|
||||
>
|
||||
<span
|
||||
v-if="folder.color"
|
||||
class="h-2 w-2 rounded-full flex-shrink-0"
|
||||
:style="`background: ${folder.color}`"
|
||||
/>
|
||||
{{ folder.name }}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenuPortal>
|
||||
</DropdownMenuRoot>
|
||||
</template>
|
||||
|
||||
<!-- Empty trash (only outside bulk mode) -->
|
||||
<button
|
||||
v-if="store.currentFolder === 'Trash' && store.messages.length > 0"
|
||||
v-if="store.currentFolder === 'Trash' && store.messages.length > 0 && !bulkSelectMode"
|
||||
class="inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground hover:bg-destructive hover:text-destructive-foreground transition-colors"
|
||||
title="Empty Trash"
|
||||
@click="emptyTrash"
|
||||
>
|
||||
<Trash2 class="size-4" />
|
||||
</button>
|
||||
|
||||
<!-- Checkbox toggle (always visible) -->
|
||||
<button
|
||||
class="inline-flex h-9 w-9 items-center justify-center rounded-md transition-colors"
|
||||
:class="bulkSelectMode
|
||||
? 'bg-accent text-[#FBA612]'
|
||||
: 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'"
|
||||
title="Select messages"
|
||||
@click="toggleBulkSelect"
|
||||
>
|
||||
<CheckSquare v-if="bulkSelectMode" class="size-4" />
|
||||
<Square v-else class="size-4" />
|
||||
</button>
|
||||
|
||||
<!-- Sort -->
|
||||
<button
|
||||
class="inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors"
|
||||
:title="store.sortOrder === 'desc' ? 'Oldest first' : 'Newest first'"
|
||||
|
|
@ -108,6 +274,7 @@ const performEmptyTrash = async () => {
|
|||
>
|
||||
<ArrowDownUp class="size-4" :class="store.sortOrder === 'asc' ? 'rotate-180' : ''" />
|
||||
</button>
|
||||
|
||||
<TabsList class="inline-flex h-9 items-center gap-1 bg-transparent">
|
||||
<TabsTrigger
|
||||
value="all"
|
||||
|
|
@ -146,6 +313,8 @@ const performEmptyTrash = async () => {
|
|||
:message="msg"
|
||||
:selected="store.currentMessage?.id === msg.id"
|
||||
:folder-color="folderColor"
|
||||
:bulk-select-mode="bulkSelectMode"
|
||||
:is-checked="selectedIds.has(msg.id)"
|
||||
@click="selectMessage(msg)"
|
||||
/>
|
||||
</TransitionGroup>
|
||||
|
|
@ -184,6 +353,8 @@ const performEmptyTrash = async () => {
|
|||
:message="msg"
|
||||
:selected="store.currentMessage?.id === msg.id"
|
||||
:folder-color="folderColor"
|
||||
:bulk-select-mode="bulkSelectMode"
|
||||
:is-checked="selectedIds.has(msg.id)"
|
||||
@click="selectMessage(msg)"
|
||||
/>
|
||||
</TransitionGroup>
|
||||
|
|
@ -222,6 +393,8 @@ const performEmptyTrash = async () => {
|
|||
:message="msg"
|
||||
:selected="store.currentMessage?.id === msg.id"
|
||||
:folder-color="folderColor"
|
||||
:bulk-select-mode="bulkSelectMode"
|
||||
:is-checked="selectedIds.has(msg.id)"
|
||||
@click="selectMessage(msg)"
|
||||
/>
|
||||
</TransitionGroup>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { formatDistanceToNow, format } from 'date-fns'
|
||||
import { Paperclip, Star } from 'lucide-vue-next'
|
||||
import { Paperclip, Star, Check } from 'lucide-vue-next'
|
||||
import { TooltipRoot, TooltipTrigger, TooltipContent, TooltipPortal } from 'radix-vue'
|
||||
import { cn } from '../../lib/utils'
|
||||
import Badge from '../ui/Badge.vue'
|
||||
|
|
@ -11,6 +11,8 @@ const props = defineProps({
|
|||
message: { type: Object, required: true },
|
||||
selected: { type: Boolean, default: false },
|
||||
folderColor: { type: String, default: '' },
|
||||
bulkSelectMode: { type: Boolean, default: false },
|
||||
isChecked: { type: Boolean, default: false },
|
||||
})
|
||||
|
||||
const initials = computed(() => {
|
||||
|
|
@ -53,6 +55,15 @@ const recipientLabel = computed(() => {
|
|||
)"
|
||||
:style="folderColor ? `border-left: 3px solid ${folderColor}; border-radius: 12px 0 0 12px;` : ''"
|
||||
>
|
||||
<!-- Bulk select checkbox -->
|
||||
<div
|
||||
v-if="bulkSelectMode"
|
||||
class="flex-shrink-0 h-5 w-5 rounded border-2 flex items-center justify-center mt-2 transition-all"
|
||||
:class="isChecked ? 'bg-[#FBA612] border-[#FBA612]' : 'border-muted-foreground/50'"
|
||||
>
|
||||
<Check v-if="isChecked" class="size-3 text-white" />
|
||||
</div>
|
||||
|
||||
<!-- Avatar -->
|
||||
<div
|
||||
class="flex-shrink-0 h-9 w-9 rounded-full flex items-center justify-center text-[13px] font-semibold text-white select-none mt-0.5"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference types="../../../node_modules/.vue-global-types/vue_3.5_0_0_0.d.ts" />
|
||||
import { computed } from 'vue';
|
||||
import { formatDistanceToNow, format } from 'date-fns';
|
||||
import { Paperclip, Star } from 'lucide-vue-next';
|
||||
import { Paperclip, Star, Check } from 'lucide-vue-next';
|
||||
import { TooltipRoot, TooltipTrigger, TooltipContent, TooltipPortal } from 'radix-vue';
|
||||
import { cn } from '../../lib/utils';
|
||||
import Badge from '../ui/Badge.vue';
|
||||
|
|
@ -10,6 +10,8 @@ const props = defineProps({
|
|||
message: { type: Object, required: true },
|
||||
selected: { type: Boolean, default: false },
|
||||
folderColor: { type: String, default: '' },
|
||||
bulkSelectMode: { type: Boolean, default: false },
|
||||
isChecked: { type: Boolean, default: false },
|
||||
});
|
||||
const initials = computed(() => {
|
||||
const name = props.message.from_name || props.message.from_address || '?';
|
||||
|
|
@ -54,6 +56,23 @@ __VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElement
|
|||
...{ class: (__VLS_ctx.cn('df-msg-item flex items-start gap-3 rounded-xl p-3 text-left text-sm w-full', __VLS_ctx.selected && 'df-msg-selected')) },
|
||||
...{ style: (__VLS_ctx.folderColor ? `border-left: 3px solid ${__VLS_ctx.folderColor}; border-radius: 12px 0 0 12px;` : '') },
|
||||
});
|
||||
if (__VLS_ctx.bulkSelectMode) {
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "flex-shrink-0 h-5 w-5 rounded border-2 flex items-center justify-center mt-2 transition-all" },
|
||||
...{ class: (__VLS_ctx.isChecked ? 'bg-[#FBA612] border-[#FBA612]' : 'border-muted-foreground/50') },
|
||||
});
|
||||
if (__VLS_ctx.isChecked) {
|
||||
const __VLS_0 = {}.Check;
|
||||
/** @type {[typeof __VLS_components.Check, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_1 = __VLS_asFunctionalComponent(__VLS_0, new __VLS_0({
|
||||
...{ class: "size-3 text-white" },
|
||||
}));
|
||||
const __VLS_2 = __VLS_1({
|
||||
...{ class: "size-3 text-white" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_1));
|
||||
}
|
||||
}
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "flex-shrink-0 h-9 w-9 rounded-full flex items-center justify-center text-[13px] font-semibold text-white select-none mt-0.5" },
|
||||
...{ style: {} },
|
||||
|
|
@ -75,62 +94,62 @@ if (!__VLS_ctx.message.is_read) {
|
|||
});
|
||||
}
|
||||
if (__VLS_ctx.message.is_starred) {
|
||||
const __VLS_0 = {}.Star;
|
||||
const __VLS_4 = {}.Star;
|
||||
/** @type {[typeof __VLS_components.Star, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_1 = __VLS_asFunctionalComponent(__VLS_0, new __VLS_0({
|
||||
...{ class: "flex-shrink-0 size-3 fill-yellow-400 text-yellow-400" },
|
||||
}));
|
||||
const __VLS_2 = __VLS_1({
|
||||
...{ class: "flex-shrink-0 size-3 fill-yellow-400 text-yellow-400" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_1));
|
||||
}
|
||||
if (__VLS_ctx.timestamp) {
|
||||
const __VLS_4 = {}.TooltipRoot;
|
||||
/** @type {[typeof __VLS_components.TooltipRoot, typeof __VLS_components.TooltipRoot, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_5 = __VLS_asFunctionalComponent(__VLS_4, new __VLS_4({
|
||||
delayDuration: (300),
|
||||
...{ class: "flex-shrink-0 size-3 fill-yellow-400 text-yellow-400" },
|
||||
}));
|
||||
const __VLS_6 = __VLS_5({
|
||||
delayDuration: (300),
|
||||
...{ class: "flex-shrink-0 size-3 fill-yellow-400 text-yellow-400" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_5));
|
||||
__VLS_7.slots.default;
|
||||
const __VLS_8 = {}.TooltipTrigger;
|
||||
/** @type {[typeof __VLS_components.TooltipTrigger, typeof __VLS_components.TooltipTrigger, ]} */ ;
|
||||
}
|
||||
if (__VLS_ctx.timestamp) {
|
||||
const __VLS_8 = {}.TooltipRoot;
|
||||
/** @type {[typeof __VLS_components.TooltipRoot, typeof __VLS_components.TooltipRoot, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_9 = __VLS_asFunctionalComponent(__VLS_8, new __VLS_8({
|
||||
asChild: true,
|
||||
delayDuration: (300),
|
||||
}));
|
||||
const __VLS_10 = __VLS_9({
|
||||
asChild: true,
|
||||
delayDuration: (300),
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_9));
|
||||
__VLS_11.slots.default;
|
||||
const __VLS_12 = {}.TooltipTrigger;
|
||||
/** @type {[typeof __VLS_components.TooltipTrigger, typeof __VLS_components.TooltipTrigger, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_13 = __VLS_asFunctionalComponent(__VLS_12, new __VLS_12({
|
||||
asChild: true,
|
||||
}));
|
||||
const __VLS_14 = __VLS_13({
|
||||
asChild: true,
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_13));
|
||||
__VLS_15.slots.default;
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: (__VLS_ctx.cn('flex-shrink-0 text-xs cursor-default', __VLS_ctx.selected ? 'text-foreground' : 'text-muted-foreground')) },
|
||||
});
|
||||
(__VLS_ctx.relativeTime);
|
||||
var __VLS_11;
|
||||
const __VLS_12 = {}.TooltipPortal;
|
||||
var __VLS_15;
|
||||
const __VLS_16 = {}.TooltipPortal;
|
||||
/** @type {[typeof __VLS_components.TooltipPortal, typeof __VLS_components.TooltipPortal, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_13 = __VLS_asFunctionalComponent(__VLS_12, new __VLS_12({}));
|
||||
const __VLS_14 = __VLS_13({}, ...__VLS_functionalComponentArgsRest(__VLS_13));
|
||||
__VLS_15.slots.default;
|
||||
const __VLS_16 = {}.TooltipContent;
|
||||
const __VLS_17 = __VLS_asFunctionalComponent(__VLS_16, new __VLS_16({}));
|
||||
const __VLS_18 = __VLS_17({}, ...__VLS_functionalComponentArgsRest(__VLS_17));
|
||||
__VLS_19.slots.default;
|
||||
const __VLS_20 = {}.TooltipContent;
|
||||
/** @type {[typeof __VLS_components.TooltipContent, typeof __VLS_components.TooltipContent, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_17 = __VLS_asFunctionalComponent(__VLS_16, new __VLS_16({
|
||||
const __VLS_21 = __VLS_asFunctionalComponent(__VLS_20, new __VLS_20({
|
||||
...{ class: "z-50 rounded-md border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md" },
|
||||
}));
|
||||
const __VLS_18 = __VLS_17({
|
||||
const __VLS_22 = __VLS_21({
|
||||
...{ class: "z-50 rounded-md border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_17));
|
||||
__VLS_19.slots.default;
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_21));
|
||||
__VLS_23.slots.default;
|
||||
(__VLS_ctx.exactTime);
|
||||
var __VLS_23;
|
||||
var __VLS_19;
|
||||
var __VLS_15;
|
||||
var __VLS_7;
|
||||
var __VLS_11;
|
||||
}
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "text-xs font-medium truncate" },
|
||||
|
|
@ -146,27 +165,39 @@ if (__VLS_ctx.message.has_attachments) {
|
|||
});
|
||||
/** @type {[typeof Badge, typeof Badge, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_20 = __VLS_asFunctionalComponent(Badge, new Badge({
|
||||
const __VLS_24 = __VLS_asFunctionalComponent(Badge, new Badge({
|
||||
variant: "secondary",
|
||||
...{ class: "gap-1" },
|
||||
}));
|
||||
const __VLS_21 = __VLS_20({
|
||||
variant: "secondary",
|
||||
...{ class: "gap-1" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_20));
|
||||
__VLS_22.slots.default;
|
||||
const __VLS_23 = {}.Paperclip;
|
||||
/** @type {[typeof __VLS_components.Paperclip, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_24 = __VLS_asFunctionalComponent(__VLS_23, new __VLS_23({
|
||||
...{ class: "size-3" },
|
||||
}));
|
||||
const __VLS_25 = __VLS_24({
|
||||
...{ class: "size-3" },
|
||||
variant: "secondary",
|
||||
...{ class: "gap-1" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_24));
|
||||
var __VLS_22;
|
||||
__VLS_26.slots.default;
|
||||
const __VLS_27 = {}.Paperclip;
|
||||
/** @type {[typeof __VLS_components.Paperclip, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_28 = __VLS_asFunctionalComponent(__VLS_27, new __VLS_27({
|
||||
...{ class: "size-3" },
|
||||
}));
|
||||
const __VLS_29 = __VLS_28({
|
||||
...{ class: "size-3" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_28));
|
||||
var __VLS_26;
|
||||
}
|
||||
/** @type {__VLS_StyleScopedClasses['flex-shrink-0']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['h-5']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-5']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['rounded']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['border-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['mt-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['transition-all']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['size-3']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-white']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['flex-shrink-0']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['h-9']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-9']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
|
||||
|
|
@ -224,6 +255,7 @@ const __VLS_self = (await import('vue')).defineComponent({
|
|||
return {
|
||||
Paperclip: Paperclip,
|
||||
Star: Star,
|
||||
Check: Check,
|
||||
TooltipRoot: TooltipRoot,
|
||||
TooltipTrigger: TooltipTrigger,
|
||||
TooltipContent: TooltipContent,
|
||||
|
|
@ -241,6 +273,8 @@ const __VLS_self = (await import('vue')).defineComponent({
|
|||
message: { type: Object, required: true },
|
||||
selected: { type: Boolean, default: false },
|
||||
folderColor: { type: String, default: '' },
|
||||
bulkSelectMode: { type: Boolean, default: false },
|
||||
isChecked: { type: Boolean, default: false },
|
||||
},
|
||||
});
|
||||
export default (await import('vue')).defineComponent({
|
||||
|
|
@ -251,6 +285,8 @@ export default (await import('vue')).defineComponent({
|
|||
message: { type: Object, required: true },
|
||||
selected: { type: Boolean, default: false },
|
||||
folderColor: { type: String, default: '' },
|
||||
bulkSelectMode: { type: Boolean, default: false },
|
||||
isChecked: { type: Boolean, default: false },
|
||||
},
|
||||
});
|
||||
; /* PartiallyEnd: #4569/main.vue */
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -23,7 +23,7 @@ const selectResult = (msg: any) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative w-full px-4 py-2 border-b">
|
||||
<div class="relative w-full px-4 py-2">
|
||||
<input v-model="searchVal" type="search" placeholder="Search..." class="w-full rounded-md border border-input bg-background px-3 py-2 text-base focus:outline-none focus:ring-2 focus:ring-ring" style="font-size: 16px;" />
|
||||
<div v-if="searchVal && results.length > 0" class="absolute left-0 right-0 top-full z-10 mt-1 max-h-[300px] overflow-y-auto rounded-md border bg-background p-1 shadow-md">
|
||||
<div v-for="res in results" :key="res.id" @click="selectResult(res)" class="cursor-pointer rounded-sm px-2 py-1 text-sm hover:bg-accent">
|
||||
|
|
|
|||
|
|
@ -22,12 +22,13 @@ const __VLS_ctx = {};
|
|||
let __VLS_components;
|
||||
let __VLS_directives;
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "relative w-full px-4 py-2 border-b" },
|
||||
...{ class: "relative w-full px-4 py-2" },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
|
||||
type: "search",
|
||||
placeholder: "Search...",
|
||||
...{ class: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring" },
|
||||
...{ class: "w-full rounded-md border border-input bg-background px-3 py-2 text-base focus:outline-none focus:ring-2 focus:ring-ring" },
|
||||
...{ style: {} },
|
||||
});
|
||||
(__VLS_ctx.searchVal);
|
||||
if (__VLS_ctx.searchVal && __VLS_ctx.results.length > 0) {
|
||||
|
|
@ -63,7 +64,6 @@ else if (__VLS_ctx.searchVal && !__VLS_ctx.loading) {
|
|||
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['py-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['border-b']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['rounded-md']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['border']} */ ;
|
||||
|
|
@ -71,7 +71,7 @@ else if (__VLS_ctx.searchVal && !__VLS_ctx.loading) {
|
|||
/** @type {__VLS_StyleScopedClasses['bg-background']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['px-3']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['py-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-base']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['focus:outline-none']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['focus:ring-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['focus:ring-ring']} */ ;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"SearchBar.vue.js","sourceRoot":"","sources":["SearchBar.vue"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"SearchBar.vue.js","sourceRoot":"","sources":["SearchBar.vue"],"names":[],"mappings":"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"}
|
||||
|
|
@ -38,7 +38,7 @@ const store = useMailStore()
|
|||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
:global(.dark) .df-settings-dialog {
|
||||
.dark .df-settings-dialog {
|
||||
background: rgba(10, 20, 44, 0.90) !important;
|
||||
border-color: rgba(255,255,255,0.08) !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -611,3 +611,17 @@ function formatDate(iso: string | null) {
|
|||
<p class="text-sm text-muted-foreground">Additional settings are managed in DockFlare Master.</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.dark input,
|
||||
.dark textarea,
|
||||
.dark select {
|
||||
background-color: hsl(var(--muted)) !important;
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
.dark input::placeholder,
|
||||
.dark textarea::placeholder {
|
||||
color: hsl(var(--muted-foreground));
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -268,6 +268,12 @@ debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
|
|||
const __VLS_ctx = {};
|
||||
let __VLS_components;
|
||||
let __VLS_directives;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
// CSS variable injection
|
||||
// CSS variable injection end
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "p-6" },
|
||||
});
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -3,7 +3,6 @@ import { ref, onMounted } from 'vue';
|
|||
import { useRoute } from 'vue-router';
|
||||
import { useAuth } from '../composables/useAuth';
|
||||
import { authApi } from '../api/auth';
|
||||
import Button from '../components/ui/Button.vue';
|
||||
const route = useRoute();
|
||||
const { login } = useAuth();
|
||||
const email = ref('');
|
||||
|
|
@ -54,12 +53,22 @@ debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
|
|||
const __VLS_ctx = {};
|
||||
let __VLS_components;
|
||||
let __VLS_directives;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-card']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-input']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-submit']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-sso']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-sso']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['dark']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-sso']} */ ;
|
||||
// CSS variable injection
|
||||
// CSS variable injection end
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "flex h-screen w-screen items-center justify-center" },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "w-full max-w-sm space-y-6 p-8" },
|
||||
...{ style: {} },
|
||||
...{ class: "df-login-card w-full max-w-sm space-y-6 p-8" },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "flex flex-col space-y-1 text-center" },
|
||||
|
|
@ -84,16 +93,14 @@ __VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
|
|||
type: "email",
|
||||
placeholder: "you@example.com",
|
||||
required: true,
|
||||
...{ class: "w-full rounded-xl px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-[rgba(251,166,18,0.4)]" },
|
||||
...{ style: {} },
|
||||
...{ class: "df-login-input w-full rounded-xl px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-[rgba(251,166,18,0.4)]" },
|
||||
});
|
||||
(__VLS_ctx.email);
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
|
||||
type: "password",
|
||||
placeholder: "Password",
|
||||
required: true,
|
||||
...{ class: "w-full rounded-xl px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-[rgba(251,166,18,0.4)]" },
|
||||
...{ style: {} },
|
||||
...{ class: "df-login-input w-full rounded-xl px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-[rgba(251,166,18,0.4)]" },
|
||||
});
|
||||
(__VLS_ctx.password);
|
||||
if (__VLS_ctx.error) {
|
||||
|
|
@ -102,58 +109,34 @@ if (__VLS_ctx.error) {
|
|||
});
|
||||
(__VLS_ctx.error);
|
||||
}
|
||||
/** @type {[typeof Button, typeof Button, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_0 = __VLS_asFunctionalComponent(Button, new Button({
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
|
||||
type: "submit",
|
||||
...{ class: "w-full" },
|
||||
...{ class: "df-login-submit w-full h-10 rounded-md text-sm font-semibold transition-all disabled:opacity-50" },
|
||||
disabled: (__VLS_ctx.loading),
|
||||
}));
|
||||
const __VLS_1 = __VLS_0({
|
||||
type: "submit",
|
||||
...{ class: "w-full" },
|
||||
disabled: (__VLS_ctx.loading),
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_0));
|
||||
__VLS_2.slots.default;
|
||||
});
|
||||
(__VLS_ctx.loading ? 'Signing in…' : 'Sign in');
|
||||
var __VLS_2;
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
|
||||
...{ class: "flex items-center gap-2" },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div)({
|
||||
...{ class: "flex-1 border-t" },
|
||||
...{ class: "flex-1 border-t border-border" },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
|
||||
...{ class: "text-xs text-muted-foreground" },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.div)({
|
||||
...{ class: "flex-1 border-t" },
|
||||
...{ class: "flex-1 border-t border-border" },
|
||||
});
|
||||
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
|
||||
...{ onClick: (__VLS_ctx.redirectToMaster) },
|
||||
...{ class: "df-login-sso w-full h-10 rounded-md text-sm font-medium transition-all" },
|
||||
});
|
||||
/** @type {[typeof Button, typeof Button, ]} */ ;
|
||||
// @ts-ignore
|
||||
const __VLS_3 = __VLS_asFunctionalComponent(Button, new Button({
|
||||
...{ 'onClick': {} },
|
||||
variant: "outline",
|
||||
...{ class: "w-full" },
|
||||
}));
|
||||
const __VLS_4 = __VLS_3({
|
||||
...{ 'onClick': {} },
|
||||
variant: "outline",
|
||||
...{ class: "w-full" },
|
||||
}, ...__VLS_functionalComponentArgsRest(__VLS_3));
|
||||
let __VLS_6;
|
||||
let __VLS_7;
|
||||
let __VLS_8;
|
||||
const __VLS_9 = {
|
||||
onClick: (__VLS_ctx.redirectToMaster)
|
||||
};
|
||||
__VLS_5.slots.default;
|
||||
var __VLS_5;
|
||||
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['h-screen']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-screen']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-card']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['max-w-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['space-y-6']} */ ;
|
||||
|
|
@ -174,6 +157,7 @@ var __VLS_5;
|
|||
/** @type {__VLS_StyleScopedClasses['text-muted-foreground']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['mt-1']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['space-y-3']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-input']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['px-3']} */ ;
|
||||
|
|
@ -184,6 +168,7 @@ var __VLS_5;
|
|||
/** @type {__VLS_StyleScopedClasses['focus:outline-none']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['focus:ring-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['focus:ring-[rgba(251,166,18,0.4)]']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-input']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['px-3']} */ ;
|
||||
|
|
@ -196,22 +181,36 @@ var __VLS_5;
|
|||
/** @type {__VLS_StyleScopedClasses['focus:ring-[rgba(251,166,18,0.4)]']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-destructive']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-submit']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['h-10']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['rounded-md']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['transition-all']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['disabled:opacity-50']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['gap-2']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['flex-1']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['border-t']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['border-border']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-muted-foreground']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['flex-1']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['border-t']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['border-border']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['df-login-sso']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['h-10']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['rounded-md']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['font-medium']} */ ;
|
||||
/** @type {__VLS_StyleScopedClasses['transition-all']} */ ;
|
||||
var __VLS_dollars;
|
||||
const __VLS_self = (await import('vue')).defineComponent({
|
||||
setup() {
|
||||
return {
|
||||
Button: Button,
|
||||
email: email,
|
||||
password: password,
|
||||
error: error,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue