feat: add authenticated settings page.

This commit is contained in:
liqupan
2026-02-02 20:12:19 +08:00
parent cb3e16cd16
commit 6c32d845a7
259 changed files with 24685 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
import {
ChevronLeftIcon,
ChevronRightIcon,
DoubleArrowLeftIcon,
DoubleArrowRightIcon,
} from '@radix-ui/react-icons'
import { type Table } from '@tanstack/react-table'
import { cn, getPageNumbers } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
type DataTablePaginationProps<TData> = {
table: Table<TData>
className?: string
}
export function DataTablePagination<TData>({
table,
className,
}: DataTablePaginationProps<TData>) {
const currentPage = table.getState().pagination.pageIndex + 1
const totalPages = table.getPageCount()
const pageNumbers = getPageNumbers(currentPage, totalPages)
return (
<div
className={cn(
'flex items-center justify-between overflow-clip px-2',
'@max-2xl/content:flex-col-reverse @max-2xl/content:gap-4',
className
)}
style={{ overflowClipMargin: 1 }}
>
<div className='flex w-full items-center justify-between'>
<div className='flex w-[100px] items-center justify-center text-sm font-medium @2xl/content:hidden'>
Page {currentPage} of {totalPages}
</div>
<div className='flex items-center gap-2 @max-2xl/content:flex-row-reverse'>
<Select
value={`${table.getState().pagination.pageSize}`}
onValueChange={(value) => {
table.setPageSize(Number(value))
}}
>
<SelectTrigger className='h-8 w-[70px]'>
<SelectValue placeholder={table.getState().pagination.pageSize} />
</SelectTrigger>
<SelectContent side='top'>
{[10, 20, 30, 40, 50].map((pageSize) => (
<SelectItem key={pageSize} value={`${pageSize}`}>
{pageSize}
</SelectItem>
))}
</SelectContent>
</Select>
<p className='hidden text-sm font-medium sm:block'>Rows per page</p>
</div>
</div>
<div className='flex items-center sm:space-x-6 lg:space-x-8'>
<div className='flex w-[100px] items-center justify-center text-sm font-medium @max-3xl/content:hidden'>
Page {currentPage} of {totalPages}
</div>
<div className='flex items-center space-x-2'>
<Button
variant='outline'
className='size-8 p-0 @max-md/content:hidden'
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
>
<span className='sr-only'>Go to first page</span>
<DoubleArrowLeftIcon className='h-4 w-4' />
</Button>
<Button
variant='outline'
className='size-8 p-0'
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
<span className='sr-only'>Go to previous page</span>
<ChevronLeftIcon className='h-4 w-4' />
</Button>
{/* Page number buttons */}
{pageNumbers.map((pageNumber, index) => (
<div key={`${pageNumber}-${index}`} className='flex items-center'>
{pageNumber === '...' ? (
<span className='px-1 text-sm text-muted-foreground'>...</span>
) : (
<Button
variant={currentPage === pageNumber ? 'default' : 'outline'}
className='h-8 min-w-8 px-2'
onClick={() => table.setPageIndex((pageNumber as number) - 1)}
>
<span className='sr-only'>Go to page {pageNumber}</span>
{pageNumber}
</Button>
)}
</div>
))}
<Button
variant='outline'
className='size-8 p-0'
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
<span className='sr-only'>Go to next page</span>
<ChevronRightIcon className='h-4 w-4' />
</Button>
<Button
variant='outline'
className='size-8 p-0 @max-md/content:hidden'
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
>
<span className='sr-only'>Go to last page</span>
<DoubleArrowRightIcon className='h-4 w-4' />
</Button>
</div>
</div>
</div>
)
}