feat: Implement batch team owner processing with file upload, configuration, and real-time status monitoring.

This commit is contained in:
2026-01-30 14:30:42 +08:00
parent 402daf79ad
commit d7f4724473
6 changed files with 289 additions and 93 deletions

View File

@@ -0,0 +1,72 @@
import { useId } from 'react'
interface SwitchProps {
checked: boolean
onChange: (checked: boolean) => void
disabled?: boolean
label?: string
description?: string
className?: string
}
export default function Switch({
checked,
onChange,
disabled = false,
label,
description,
className = '',
}: SwitchProps) {
const id = useId()
return (
<div className={`flex items-center justify-between ${className}`}>
{(label || description) && (
<div className="flex-1 mr-3">
{label && (
<label
htmlFor={id}
className="text-sm font-medium text-slate-700 dark:text-slate-300 cursor-pointer"
>
{label}
</label>
)}
{description && (
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
{description}
</p>
)}
</div>
)}
<button
id={id}
type="button"
role="switch"
aria-checked={checked}
disabled={disabled}
onClick={() => !disabled && onChange(!checked)}
className={`
relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full
border-2 border-transparent transition-colors duration-200 ease-in-out
focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2
${checked
? 'bg-blue-500'
: 'bg-slate-200 dark:bg-slate-700'
}
${disabled ? 'opacity-50 cursor-not-allowed' : ''}
`}
>
<span
aria-hidden="true"
className={`
pointer-events-none inline-block h-5 w-5 transform rounded-full
bg-white shadow-lg ring-0 transition duration-200 ease-in-out
${checked ? 'translate-x-5' : 'translate-x-0'}
`}
/>
</button>
</div>
)
}
export type { SwitchProps }

View File

@@ -31,3 +31,6 @@ export { ToastProvider, useToast } from './Toast'
export { Tabs } from './Tabs'
export type { TabItem } from './Tabs'
export { default as Switch } from './Switch'
export type { SwitchProps } from './Switch'