mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-05-06 20:42:57 +08:00
✨ Feature(custom): support indicate current picbed config page
This commit is contained in:
@@ -1,26 +1,38 @@
|
||||
<template>
|
||||
<nav class="navigation" :class="{ collapsed: isCollapsed }">
|
||||
<div class="title-bar">
|
||||
<div v-show="!isCollapsed" class="app-title">
|
||||
<div class="app-text" @click="openGithubPage">
|
||||
<nav
|
||||
class="group no-scrollbar flex h-screen w-[150px] flex-col overflow-hidden border-r border-r-border-secondary/50 bg-bg-secondary transition-all duration-medium ease-apple max-md:w-[60px] [.collapsed]:w-[60px]"
|
||||
:class="{ collapsed: isCollapsed }"
|
||||
>
|
||||
<div
|
||||
class="relative flex items-center justify-center bg-bg-secondary px-4 py-5 group-[.collapsed]:px-2 group-[.collapsed]:py-4"
|
||||
>
|
||||
<div v-show="!isCollapsed" class="flex flex-col items-center gap-1 group-[.collapsed]:hidden max-md:hidden">
|
||||
<div
|
||||
class="text-[16px] font-bold tracking-tight text-main hover:cursor-pointer hover:text-accent"
|
||||
@click="openGithubPage"
|
||||
>
|
||||
{{ t('app.title') }}
|
||||
</div>
|
||||
<div class="app-version">v{{ version }}</div>
|
||||
<div
|
||||
class="rounded-lg border border-border/50 bg-bg-secondary px-[8px] py-[3px] text-[10px] font-medium text-secondary"
|
||||
>
|
||||
v{{ version }}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
:title="isCollapsed ? t('navigation.expand') : t('navigation.collapse')"
|
||||
class="collapse-button"
|
||||
class="absolute top-1/2 right-[8px] flex -translate-y-1/2 cursor-pointer items-center justify-center rounded-sm border-none bg-transparent p-[4px] transition-all duration-200 ease-apple group-[.collapsed]:absolute group-[.collapsed]:top-[20px] group-[.collapsed]:right-[16px] group-[.collapsed]:transform-none hover:bg-surface-elevated hover:text-main"
|
||||
@click="isCollapsed = !isCollapsed"
|
||||
>
|
||||
<component :is="isCollapsed ? ChevronRightIcon : ChevronLeftIcon" :size="16" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="theme-section">
|
||||
<div class="flex items-center justify-center p-3">
|
||||
<ThemeSwitcher :collapsed="isCollapsed" />
|
||||
</div>
|
||||
|
||||
<div class="nav-menu">
|
||||
<div class="no-scrollbar min-h-0 flex-1 overflow-y-auto py-4">
|
||||
<div
|
||||
v-for="item in navigationItems.slice(0, 3)"
|
||||
:key="item.path"
|
||||
@@ -32,22 +44,29 @@
|
||||
<div class="nav-icon-container">
|
||||
<component :is="item.icon" :size="18" />
|
||||
</div>
|
||||
<span v-show="!isCollapsed" class="nav-label">{{ item.name }}</span>
|
||||
<span v-show="!isCollapsed" class="max-md:hidden" :class="isCollapsed ? 'hidden' : ''">{{ item.name }}</span>
|
||||
</div>
|
||||
|
||||
<Disclosure v-show="!isCollapsed" v-slot="{ open }" as="div" class="nav-submenu">
|
||||
<DisclosureButton class="nav-item submenu-trigger">
|
||||
<Disclosure v-show="!isCollapsed" v-slot="{ open }" as="div" class="relative mt-[4px] justify-center">
|
||||
<DisclosureButton
|
||||
class="nav-item relative flex w-full cursor-pointer items-center justify-center gap-3 border-none bg-transparent px-4 py-3 text-sm font-medium text-secondary no-underline transition-all duration-200 ease-apple hover:bg-surface-elevated hover:text-main"
|
||||
>
|
||||
<div class="nav-icon-container">
|
||||
<DatabaseIcon :size="18" />
|
||||
</div>
|
||||
<span class="nav-label">{{ t('navigation.picbed') }}</span>
|
||||
<ChevronDownIcon :size="16" class="submenu-arrow" :class="{ 'rotate-180': open }" />
|
||||
<span class="shrink-0 max-md:hidden" :class="isCollapsed ? 'hidden' : ''">{{ t('navigation.picbed') }}</span>
|
||||
<ChevronDownIcon
|
||||
:size="16"
|
||||
class="absolute right-4 shrink-0 transition-all duration-200 ease-apple"
|
||||
:class="{ 'rotate-180': open }"
|
||||
/>
|
||||
</DisclosureButton>
|
||||
<DisclosurePanel class="submenu-panel">
|
||||
<DisclosurePanel class="mt-[2px] flex flex-col gap-[4px] pl-11">
|
||||
<div
|
||||
v-for="item in visiblePicBeds"
|
||||
:key="item.type"
|
||||
class="submenu-item"
|
||||
:class="{ 'router-link-active': isPicBedPathActive(item.type) }"
|
||||
class="flex cursor-pointer items-center px-4 py-2 text-sm font-medium text-secondary no-underline transition-all duration-200 ease-apple hover:bg-surface-elevated hover:text-accent-hover [.router-link-active]:border-r-4 [.router-link-active]:border-accent [.router-link-active]:bg-surface [.router-link-active]:text-accent"
|
||||
@click="navigateToUploaderConfig(item.type)"
|
||||
>
|
||||
<span>{{ item.name }}</span>
|
||||
@@ -56,7 +75,7 @@
|
||||
</Disclosure>
|
||||
<div
|
||||
v-show="isCollapsed"
|
||||
class="nav-item collapsed-picbed"
|
||||
class="nav-item cursor-default bg-surface-elevated hover:text-main"
|
||||
:title="t('navigation.picbed')"
|
||||
@click="isCollapsed = !isCollapsed"
|
||||
>
|
||||
@@ -76,11 +95,15 @@
|
||||
<div class="nav-icon-container">
|
||||
<component :is="item.icon" :size="18" />
|
||||
</div>
|
||||
<span v-show="!isCollapsed" class="nav-label">{{ item.name }}</span>
|
||||
<span v-show="!isCollapsed" class="max-md:hidden" :class="isCollapsed ? 'hidden' : ''">{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-footer">
|
||||
<button class="footer-button" :title="t('navigation.moreOptions')" @click="openMenu">
|
||||
<div class="border-t border-t-border p-3">
|
||||
<button
|
||||
class="fixed bottom-[4px] left-[4px] cursor-pointer rounded-full border-none bg-transparent p-[8px] text-tertiary hover:bg-surface-elevated hover:text-main"
|
||||
:title="t('navigation.moreOptions')"
|
||||
@click="openMenu"
|
||||
>
|
||||
<Info :size="20" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -89,38 +112,51 @@
|
||||
<FirstTimeGuide ref="guideRef" />
|
||||
|
||||
<TransitionRoot appear :show="qrcodeVisible" as="template">
|
||||
<Dialog as="div" class="qr-dialog" @close="qrcodeVisible = false">
|
||||
<div class="dialog-container">
|
||||
<Dialog
|
||||
as="div"
|
||||
class="fixed inset-0 z-50 flex items-center justify-center overflow-y-auto"
|
||||
@close="qrcodeVisible = false"
|
||||
>
|
||||
<div class="fixed inset-0 z-50 flex min-h-screen items-center justify-center overflow-y-auto p-[16px]">
|
||||
<TransitionChild as="template">
|
||||
<DialogPanel class="dialog-panel">
|
||||
<DialogTitle class="dialog-title">
|
||||
<DialogPanel
|
||||
class="w-full max-w-[500px] overflow-visible rounded-xl border border-border bg-bg-tertiary shadow-md"
|
||||
>
|
||||
<DialogTitle class="m-0 px-[24px] pt-[20px] text-2xl font-semibold text-main">
|
||||
{{ t('navigation.picBedQrCode') }}
|
||||
</DialogTitle>
|
||||
|
||||
<div class="dialog-content">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('navigation.choosePicBed') }}</label>
|
||||
<div class="p-4">
|
||||
<div class="mb-5">
|
||||
<label class="mb-2 block text-base font-medium text-main">{{ t('navigation.choosePicBed') }}</label>
|
||||
<Listbox v-model="choosedPicBedForQRCode" multiple>
|
||||
<div class="listbox-container">
|
||||
<ListboxButton class="listbox-button">
|
||||
<span v-if="choosedPicBedForQRCode.length === 0" class="placeholder">
|
||||
<div class="relative">
|
||||
<ListboxButton
|
||||
class="flex w-full cursor-pointer items-center justify-between rounded-2xl border border-border bg-surface px-4 py-3 text-base text-main hover:border-accent"
|
||||
>
|
||||
<span v-if="choosedPicBedForQRCode.length === 0" class="text-secondary">
|
||||
{{ t('navigation.selectPicBeds') }}
|
||||
</span>
|
||||
<span v-else class="selected-count">
|
||||
<span v-else class="text-main">
|
||||
{{ choosedPicBedForQRCode.length }} {{ t('navigation.selected') }}
|
||||
</span>
|
||||
<ChevronDownIcon :size="16" class="listbox-arrow" />
|
||||
<ChevronDownIcon :size="16" class="text-secondary" />
|
||||
</ListboxButton>
|
||||
|
||||
<transition>
|
||||
<ListboxOptions class="listbox-options">
|
||||
<ListboxOptions
|
||||
class="absolute top-full right-0 left-0 z-1000 mt-[4px] max-h-[300px] overflow-y-auto rounded-sm border border-border bg-bg-tertiary shadow-md"
|
||||
>
|
||||
<ListboxOption
|
||||
v-for="picbed in picBedG"
|
||||
:key="picbed.type"
|
||||
v-slot="{ active, selected }"
|
||||
:value="picbed.type"
|
||||
>
|
||||
<li class="listbox-option" :class="{ active, selected }">
|
||||
<li
|
||||
class="flex cursor-pointer items-center justify-between px-4 py-3 text-base text-main [.active]:bg-surface-elevated [.selected]:bg-accent [.selected]:text-white"
|
||||
:class="{ active, selected }"
|
||||
>
|
||||
<span>{{ picbed.name }}</span>
|
||||
<CheckIcon v-if="selected" :size="16" />
|
||||
</li>
|
||||
@@ -130,19 +166,26 @@
|
||||
</div>
|
||||
</Listbox>
|
||||
|
||||
<button v-if="choosedPicBedForQRCode.length > 0" class="copy-button" @click="handleCopyPicBedConfig">
|
||||
<button
|
||||
v-if="choosedPicBedForQRCode.length > 0"
|
||||
class="mt-3 flex cursor-pointer items-center gap-2 rounded-sm border-none bg-accent px-4 py-2 text-base font-medium text-white hover:bg-accent-hover"
|
||||
@click="handleCopyPicBedConfig"
|
||||
>
|
||||
<CopyIcon :size="16" />
|
||||
{{ t('navigation.copyPicBedConfig') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="choosedPicBedForQRCode.length > 0" class="qr-container">
|
||||
<qrcode-vue :size="280" :value="picBedConfigString" class="qr-code" />
|
||||
<div v-if="choosedPicBedForQRCode.length > 0" class="flex justify-center py-5">
|
||||
<qrcode-vue :size="280" :value="picBedConfigString" class="overflow-hidden shadow-sm" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button class="cancel-button" @click="qrcodeVisible = false">
|
||||
<div class="flex justify-end gap-3 px-4 pb-4">
|
||||
<button
|
||||
class="cursor-pointer rounded-sm border border-border bg-danger/50 px-4 py-2 text-base text-main hover:bg-danger/70"
|
||||
@click="qrcodeVisible = false"
|
||||
>
|
||||
{{ $t('navigation.close') }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -268,6 +311,11 @@ function isPathActive(path: string): boolean {
|
||||
return route.path === path
|
||||
}
|
||||
|
||||
function isPicBedPathActive(type: string): boolean {
|
||||
console.log('type:', type, 'route.params.type:', route.params.type)
|
||||
return route.name === routerConfig.UPLOADER_CONFIG_PAGE && route.params.type === type
|
||||
}
|
||||
|
||||
const navigationItems = computed(() => [
|
||||
{ name: t('navigation.upload'), path: '/main-page/upload', icon: UploadIcon },
|
||||
{ name: t('navigation.manage'), path: '/main-page/manage-login-page', icon: BriefcaseBusiness },
|
||||
|
||||
@@ -1,464 +1,14 @@
|
||||
.navigation {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
border-right: 1px solid var(--color-border-secondary);
|
||||
width: 150px;
|
||||
height: 100vh;
|
||||
background: var(--color-background-secondary);
|
||||
transition: width 0.3s ease;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.navigation.collapsed {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.title-bar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1.25rem 1rem;
|
||||
background: var(--color-background-secondary);
|
||||
}
|
||||
|
||||
.navigation.collapsed .title-bar {
|
||||
padding: 1rem 0.5rem;
|
||||
}
|
||||
|
||||
.collapse-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
color: var(--color-text-primary);
|
||||
background: transparent;
|
||||
transition: all 0.2s ease;
|
||||
transform: translateY(-50%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.collapse-button:hover {
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface-elevated);
|
||||
}
|
||||
|
||||
.navigation.collapsed .collapse-button {
|
||||
position: static;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.app-title {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.app-text {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-primary);
|
||||
letter-spacing: -0.025em;
|
||||
}
|
||||
|
||||
.app-text:hover {
|
||||
cursor: pointer;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.app-version {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 3px 8px;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-secondary);
|
||||
background: var(--color-background-secondary);
|
||||
}
|
||||
|
||||
.theme-section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.nav-menu {
|
||||
overflow-y: auto;
|
||||
padding: 1rem 0;
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
}
|
||||
@import "tailwindcss" reference;
|
||||
@import "../../assets/css/theme.css" reference;
|
||||
@import "../../assets/css/utilities.css" reference;
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.75rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: var(--color-text-secondary);
|
||||
transition: all 0.2s ease;
|
||||
gap: 0.75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.navigation.collapsed .nav-item {
|
||||
justify-content: center;
|
||||
padding: 0.75rem 0.5rem;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.navigation.collapsed .nav-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface);
|
||||
}
|
||||
|
||||
.nav-item.router-link-active {
|
||||
border-right: 3px solid var(--color-accent);
|
||||
color: var(--color-accent);
|
||||
background: var(--color-surface);
|
||||
@apply flex items-center justify-center py-3 px-4 text-sm font-medium no-underline text-secondary gap-3 cursor-pointer transition-all duration-200 ease-apple;
|
||||
@apply hover:text-main hover:bg-surface;
|
||||
@apply group-[.collapsed]:justify-center group-[.collapsed]:py-3 group-[.collapsed]:px-2 group-[.collapsed]:gap-0 ;
|
||||
@apply [.router-link-active]:border-accent [.router-link-active]:border-r-4 [.router-link-active]:text-accent [.router-link-active]:bg-surface;
|
||||
}
|
||||
|
||||
.nav-icon-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
border-top: 1px solid var(--color-border);
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.footer-button {
|
||||
position: fixed;
|
||||
bottom: 4px;
|
||||
left: 4px;
|
||||
border: none;
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 8px;
|
||||
color: var(--color-text-tertiary);
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.footer-button:hover {
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface-elevated);
|
||||
}
|
||||
|
||||
.nav-submenu {
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.submenu-trigger {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: none;
|
||||
padding: 0.75rem 1rem;
|
||||
width: 100%;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: var(--color-text-secondary);
|
||||
background: transparent;
|
||||
transition: all 0.2s ease;
|
||||
gap: 0.75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.submenu-trigger:hover {
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface-elevated);
|
||||
}
|
||||
|
||||
.submenu-trigger .nav-icon-container {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.submenu-trigger span {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.submenu-arrow {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
transition: transform 0.2s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.rotate-180 {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.submenu-panel {
|
||||
display: flex;
|
||||
margin-top: 2px;
|
||||
padding-left: 2.75rem;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.submenu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: var(--color-text-secondary);
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.submenu-item:hover {
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface-elevated);
|
||||
}
|
||||
|
||||
.collapsed-picbed {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.collapsed-picbed:hover {
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface-elevated);
|
||||
}
|
||||
|
||||
.qr-dialog {
|
||||
position: fixed;
|
||||
z-index: 50;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow-y: auto;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
.dialog-container {
|
||||
position: fixed;
|
||||
z-index: 50;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
min-height: 100vh;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
.dialog-panel {
|
||||
overflow: visible;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-xl);
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
background: var(--color-background-tertiary);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.dialog-title {
|
||||
margin: 0;
|
||||
padding: 20px 24px 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.listbox-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.listbox-button {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 12px 16px;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface);
|
||||
transition: var(--transition);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.listbox-button:hover {
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.selected-count {
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.listbox-arrow {
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.listbox-options {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
overflow-y: auto;
|
||||
margin-top: 4px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
max-height: 300px;
|
||||
background: var(--color-background-tertiary);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.listbox-option {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
font-size: 14px;
|
||||
color: var(--color-text-primary);
|
||||
transition: var(--transition);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.listbox-option.active {
|
||||
background: var(--color-surface-elevated);
|
||||
}
|
||||
|
||||
.listbox-option.selected {
|
||||
color: white;
|
||||
background: var(--color-accent);
|
||||
}
|
||||
|
||||
.copy-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 12px;
|
||||
border: none;
|
||||
border-radius: var(--border-radius);
|
||||
padding: 10px 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: white;
|
||||
background: var(--color-accent);
|
||||
transition: var(--transition);
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.copy-button:hover {
|
||||
background: var(--color-accent-hover);
|
||||
}
|
||||
|
||||
.qr-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.qr-code {
|
||||
overflow: hidden;
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 0 24px 20px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 10px 20px;
|
||||
font-size: 14px;
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface-elevated);
|
||||
transition: var(--transition);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cancel-button:hover {
|
||||
background: var(--color-border);
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (width <= 768px) {
|
||||
.navigation {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.nav-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.app-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse-button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scrollbar Styling */
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 0;
|
||||
background: var(--color-border);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--color-text-secondary);
|
||||
@apply relative flex justify-center items-center w-[20px] h-[20px] shrink-0;
|
||||
}
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
|
||||
<!-- Config Grid -->
|
||||
<div
|
||||
class="no-scrollbar flex w-full flex-1 items-center gap-4 overflow-auto rounded-2xl border border-border-secondary px-4 py-6 shadow-md"
|
||||
class="no-scrollbar flex w-full flex-1 items-start gap-4 overflow-auto rounded-2xl border border-border-secondary px-4 py-6 shadow-md"
|
||||
>
|
||||
<div
|
||||
class="no-scrollbar grid h-full w-full grid-cols-[repeat(auto-fill,minmax(300px,1fr))] gap-5 overflow-auto border-none p-1 max-md:grid-cols-1 max-md:gap-4 xl:grid-cols-[repeat(auto-fill,minmax(325px,1fr))]"
|
||||
class="no-scrollbar grid h-auto w-full grid-cols-[repeat(auto-fill,minmax(300px,1fr))] gap-5 overflow-auto border-none p-1 max-md:grid-cols-1 max-md:gap-4 xl:grid-cols-[repeat(auto-fill,minmax(325px,1fr))]"
|
||||
>
|
||||
<!-- Config Items -->
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user