fix: move SidebarTrigger to sidebar edge, move Dialog/AlertDialog outside SectionPageLayout
Docker Build / Build and Push Docker Image (push) Successful in 3m29s

This commit is contained in:
2026-06-15 03:57:06 +08:00
parent ff407c4607
commit c52ff411a7
4 changed files with 60 additions and 61 deletions
@@ -23,7 +23,6 @@ import { LanguageSwitcher } from '@/components/language-switcher'
import { NotificationPopover } from '@/components/notification-popover'
import { ProfileDropdown } from '@/components/profile-dropdown'
import { Search } from '@/components/search'
import { SidebarTrigger } from '@/components/ui/sidebar'
import { defaultTopNavLinks } from '../config/top-nav.config'
import { type TopNavLink } from '../types'
import { Header } from './header'
@@ -114,7 +113,6 @@ export function AppHeader({
<>
<Header>
<SystemBrand variant='inline' />
<SidebarTrigger variant='ghost' className='size-8' />
{leftContent ? (
<div className='ms-2 flex items-center'>{leftContent}</div>
@@ -20,7 +20,7 @@ import { getCookie } from '@/lib/cookies'
import { cn } from '@/lib/utils'
import { LayoutProvider } from '@/context/layout-provider'
import { SearchProvider } from '@/context/search-provider'
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'
import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'
import { AnimatedOutlet } from '@/components/page-transition'
import { SkipToMain } from '@/components/skip-to-main'
import { AppHeader } from './app-header'
@@ -49,6 +49,7 @@ export function AuthenticatedLayout(props: AuthenticatedLayoutProps) {
'peer-data-[variant=inset]:h-[calc(100svh-var(--app-header-height,0px)-(var(--spacing)*4))]'
)}
>
<SidebarTrigger variant='ghost' className='absolute left-1 top-1/2 z-30 size-8 -translate-y-1/2' />
{props.children ?? <AnimatedOutlet />}
</SidebarInset>
</div>
+54 -54
View File
@@ -163,61 +163,61 @@ export function DocCategories() {
</TableBody>
</Table>
</SectionPageLayout.Content>
{/* Create/Edit Dialog */}
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>{editingCategory ? t('Edit Category') : t('Add Category')}</DialogTitle>
</DialogHeader>
<div className='space-y-4 py-4'>
<div className='space-y-2'>
<label className='text-sm font-medium'>{t('Category Name')}</label>
<Input value={form.name} onChange={e => handleNameChange(e.target.value)} placeholder={t('Category name is required')} />
</div>
<div className='space-y-2'>
<label className='text-sm font-medium'>{t('Slug')}</label>
<Input value={form.slug} onChange={e => setForm(prev => ({ ...prev, slug: e.target.value }))} placeholder='category-slug' />
</div>
<div className='space-y-2'>
<label className='text-sm font-medium'>{t('Parent Category')}</label>
<select
className='flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors'
value={form.parent_id}
onChange={e => setForm(prev => ({ ...prev, parent_id: e.target.value }))}
>
<option value=''>{t('None')}</option>
{categories.filter(c => c.id !== editingCategory?.id).map(c => (
<option key={c.id} value={c.id.toString()}>{c.name}</option>
))}
</select>
</div>
<div className='space-y-2'>
<label className='text-sm font-medium'>{t('Sort Order')}</label>
<Input type='number' value={form.sort_order} onChange={e => setForm(prev => ({ ...prev, sort_order: parseInt(e.target.value) || 0 }))} />
</div>
</div>
<DialogFooter>
<Button variant='outline' onClick={() => setDialogOpen(false)}>{t('Cancel')}</Button>
<Button onClick={handleSubmit} disabled={!form.name}>{t('Save')}</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* Delete Confirmation */}
<AlertDialog open={!!deleteTarget} onOpenChange={() => setDeleteTarget(null)}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{t('Delete Category')}</AlertDialogTitle>
<AlertDialogDescription>{t('Are you sure you want to delete this category? This action cannot be undone.')}</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>{t('Cancel')}</AlertDialogCancel>
<AlertDialogAction onClick={handleDelete} className='bg-destructive text-destructive-foreground hover:bg-destructive/90'>{t('Delete')}</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</SectionPageLayout>
{/* Create/Edit Dialog */}
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>{editingCategory ? t('Edit Category') : t('Add Category')}</DialogTitle>
</DialogHeader>
<div className='space-y-4 py-4'>
<div className='space-y-2'>
<label className='text-sm font-medium'>{t('Category Name')}</label>
<Input value={form.name} onChange={e => handleNameChange(e.target.value)} placeholder={t('Category name is required')} />
</div>
<div className='space-y-2'>
<label className='text-sm font-medium'>{t('Slug')}</label>
<Input value={form.slug} onChange={e => setForm(prev => ({ ...prev, slug: e.target.value }))} placeholder='category-slug' />
</div>
<div className='space-y-2'>
<label className='text-sm font-medium'>{t('Parent Category')}</label>
<select
className='flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors'
value={form.parent_id}
onChange={e => setForm(prev => ({ ...prev, parent_id: e.target.value }))}
>
<option value=''>{t('None')}</option>
{categories.filter(c => c.id !== editingCategory?.id).map(c => (
<option key={c.id} value={c.id.toString()}>{c.name}</option>
))}
</select>
</div>
<div className='space-y-2'>
<label className='text-sm font-medium'>{t('Sort Order')}</label>
<Input type='number' value={form.sort_order} onChange={e => setForm(prev => ({ ...prev, sort_order: parseInt(e.target.value) || 0 }))} />
</div>
</div>
<DialogFooter>
<Button variant='outline' onClick={() => setDialogOpen(false)}>{t('Cancel')}</Button>
<Button onClick={handleSubmit} disabled={!form.name}>{t('Save')}</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* Delete Confirmation */}
<AlertDialog open={!!deleteTarget} onOpenChange={() => setDeleteTarget(null)}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{t('Delete Category')}</AlertDialogTitle>
<AlertDialogDescription>{t('Are you sure you want to delete this category? This action cannot be undone.')}</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>{t('Cancel')}</AlertDialogCancel>
<AlertDialogAction onClick={handleDelete} className='bg-destructive text-destructive-foreground hover:bg-destructive/90'>{t('Delete')}</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
)
}
+4 -4
View File
@@ -211,10 +211,11 @@ export function DocsManagement() {
</TableBody>
</Table>
</SectionPageLayout.Content>
</SectionPageLayout>
{/* Create/Edit Dialog */}
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<DialogContent className='max-w-2xl max-h-[85vh] overflow-y-auto'>
{/* Create/Edit Dialog */}
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
<DialogContent className='max-w-2xl max-h-[85vh] overflow-y-auto'>
<DialogHeader>
<DialogTitle>{editingDoc ? t('Edit Document') : t('Add Document')}</DialogTitle>
</DialogHeader>
@@ -290,7 +291,6 @@ export function DocsManagement() {
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</SectionPageLayout>
</>
)
}