mirror of
https://github.com/azaion/ui.git
synced 2026-04-22 12:06:35 +00:00
73 lines
2.5 KiB
TypeScript
73 lines
2.5 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { api } from '../api/client'
|
|
import type { DetectionClass } from '../types'
|
|
|
|
interface Props {
|
|
selectedClassNum: number
|
|
onSelect: (classNum: number) => void
|
|
photoMode: number
|
|
onPhotoModeChange: (mode: number) => void
|
|
}
|
|
|
|
export default function DetectionClasses({ selectedClassNum, onSelect, photoMode, onPhotoModeChange }: Props) {
|
|
const { t } = useTranslation()
|
|
const [classes, setClasses] = useState<DetectionClass[]>([])
|
|
|
|
useEffect(() => {
|
|
api.get<DetectionClass[]>('/api/annotations/classes').then(setClasses).catch(() => {})
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
const handler = (e: KeyboardEvent) => {
|
|
const num = parseInt(e.key)
|
|
if (num >= 1 && num <= 9) {
|
|
const idx = num - 1
|
|
const cls = classes[idx + photoMode]
|
|
if (cls) onSelect(cls.id)
|
|
}
|
|
}
|
|
window.addEventListener('keydown', handler)
|
|
return () => window.removeEventListener('keydown', handler)
|
|
}, [classes, photoMode, onSelect])
|
|
|
|
const modes = [
|
|
{ value: 0, label: t('annotations.regular') },
|
|
{ value: 20, label: t('annotations.winter') },
|
|
{ value: 40, label: t('annotations.night') },
|
|
]
|
|
|
|
return (
|
|
<div className="border-t border-az-border p-2">
|
|
<div className="text-xs text-az-muted mb-1 font-semibold">{t('annotations.classes')}</div>
|
|
<div className="flex gap-1 mb-2">
|
|
{modes.map(m => (
|
|
<button
|
|
key={m.value}
|
|
onClick={() => onPhotoModeChange(m.value)}
|
|
className={`text-xs px-2 py-0.5 rounded ${photoMode === m.value ? 'bg-az-orange text-white' : 'bg-az-bg text-az-muted'}`}
|
|
>
|
|
{m.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
<div className="space-y-0.5 max-h-48 overflow-y-auto">
|
|
{classes.filter(c => c.photoMode === photoMode).map((c, i) => (
|
|
<button
|
|
key={c.id}
|
|
onClick={() => onSelect(c.id)}
|
|
className={`w-full flex items-center gap-1.5 px-1.5 py-0.5 rounded text-xs text-left ${
|
|
selectedClassNum === c.id ? 'bg-az-border text-white' : 'text-az-text hover:bg-az-bg'
|
|
}`}
|
|
>
|
|
<span className="w-2.5 h-2.5 rounded-full shrink-0" style={{ backgroundColor: c.color }} />
|
|
<span className="text-az-muted">{i + 1}.</span>
|
|
<span className="truncate">{c.name}</span>
|
|
<span className="text-az-muted ml-auto">{c.shortName}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|