'use client' import { InputHTMLAttributes, SelectHTMLAttributes, ReactNode } from 'react' export { default as Modal } from './Modal' export { default as Button } from './Button' interface InputProps extends InputHTMLAttributes { label?: string; error?: string } export function Input({ label, error, className = '', ...props }: InputProps) { return (
{label && }{error &&

{error}

}
) } interface SelectProps extends SelectHTMLAttributes { label?: string; options: Array<{ value: string; label: string }> } export function Select({ label, options, className = '', ...props }: SelectProps) { return (
{label && }
) } interface TableHeadersProps { headers: string[]; children: ReactNode } export function Table({ headers, children }: TableHeadersProps) { return (
{headers.map((h) => ())}{children}
{h}
) } import { useState } from 'react' interface PaginationProps { page: number; totalPages: number; onPageChange: (p: number) => void } export function Pagination({ page, totalPages, onPageChange }: PaginationProps) { const [jumpValue, setJumpValue] = useState('') if (totalPages <= 1) return null const pages: (number | '...')[] = [] for (let i = 1; i <= totalPages; i++) { if (i === 1 || i === totalPages || (i >= page - 1 && i <= page + 1)) pages.push(i) else if (pages[pages.length - 1] !== '...') pages.push('...') } function handleJump() { const targetPage = parseInt(jumpValue) if (isNaN(targetPage) || targetPage < 1 || targetPage > totalPages) return onPageChange(targetPage) setJumpValue('') } return (
{pages.map((p, i) => p === '...' ? : )} {/* 跳转输入框 */}
跳转到 setJumpValue(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') handleJump() }} className="w-14 px-2 py-1.5 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm text-slate-900 dark:text-white text-center focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder={`1-${totalPages}`} /> / 共{totalPages}页
) } interface BadgeProps { variant?: 'default' | 'success' | 'warning' | 'danger' | 'info'; children: ReactNode } export function Badge({ variant = 'default', children }: BadgeProps) { const v = { default: 'bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-300', success: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-400', warning: 'bg-amber-100 text-amber-700 dark:bg-amber-500/10 dark:text-amber-400', danger: 'bg-red-100 text-red-700 dark:bg-red-500/10 dark:text-red-400', info: 'bg-blue-100 text-blue-700 dark:bg-blue-500/10 dark:text-blue-400' } return ({children}) } interface CardProps { children: ReactNode; className?: string } export function Card({ children, className = '' }: CardProps) { return (
{children}
) } interface ToastProps { message: string; type?: 'success' | 'error' | 'info'; onClose: () => void } export function Toast({ message, type = 'info', onClose }: ToastProps) { const c = { success: 'bg-emerald-50 text-emerald-800 border-emerald-200 dark:bg-emerald-500/10 dark:text-emerald-400 dark:border-emerald-500/20', error: 'bg-red-50 text-red-800 border-red-200 dark:bg-red-500/10 dark:text-red-400 dark:border-red-500/20', info: 'bg-blue-50 text-blue-800 border-blue-200 dark:bg-blue-500/10 dark:text-blue-400 dark:border-blue-500/20' } return (
{message}
) }