71 lines
2.7 KiB
TypeScript
71 lines
2.7 KiB
TypeScript
'use client'
|
||
|
||
import type { WorkReviewImageAnnotation, WorkReviewRole } from '@/types/work-review'
|
||
|
||
export type WorkReviewDisplayAnnotation = {
|
||
annotation: WorkReviewImageAnnotation
|
||
markerNumber: number
|
||
reviewerName?: string
|
||
reviewerRole?: WorkReviewRole
|
||
draft?: boolean
|
||
positionEditable?: boolean
|
||
}
|
||
|
||
function markerTone(item: WorkReviewDisplayAnnotation) {
|
||
if (item.draft) return 'bg-[#8a5200] text-white ring-[#fff3d6]'
|
||
if (item.reviewerRole === 'final_reviewer') return 'bg-[#087a3c] text-white ring-[#d9f6e5]'
|
||
return 'bg-[#0050cb] text-white ring-[#dcecff]'
|
||
}
|
||
|
||
export function WorkReviewAnnotationMarker({
|
||
item,
|
||
onClick,
|
||
showComment = true,
|
||
}: {
|
||
item: WorkReviewDisplayAnnotation
|
||
onClick?: () => void
|
||
showComment?: boolean
|
||
}) {
|
||
const { annotation } = item
|
||
const alignRight = annotation.x > 0.62
|
||
const roleLabel = item.draft
|
||
? '当前批注'
|
||
: item.reviewerRole === 'final_reviewer'
|
||
? '元泽'
|
||
: '评审人'
|
||
const summary = annotation.comment.trim() || '待填写修改意见'
|
||
const positionState = item.positionEditable ? ',位置可调整' : ''
|
||
const label = `${roleLabel}标注 ${item.markerNumber}${positionState}${item.reviewerName ? `,${item.reviewerName}` : ''}:${summary}`
|
||
const visualTitle = showComment ? label : `${roleLabel}标注 ${item.markerNumber}`
|
||
|
||
return (
|
||
<button
|
||
type="button"
|
||
onClick={(event) => {
|
||
event.stopPropagation()
|
||
onClick?.()
|
||
}}
|
||
onPointerDown={(event) => event.stopPropagation()}
|
||
onPointerUp={(event) => event.stopPropagation()}
|
||
aria-label={label}
|
||
title={visualTitle}
|
||
className={`group absolute z-20 h-11 w-11 -translate-x-1/2 -translate-y-1/2 outline-none ${item.positionEditable ? 'cursor-move' : 'cursor-pointer'}`}
|
||
style={{ left: `${annotation.x * 100}%`, top: `${annotation.y * 100}%` }}
|
||
>
|
||
<span className={`absolute left-1/2 top-1/2 flex h-7 w-7 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full text-[11px] font-black shadow-[0_3px_10px_rgba(15,23,42,0.35)] ring-4 ${markerTone(item)} ${item.positionEditable ? 'outline outline-2 outline-offset-2 outline-[#8a5200]' : ''} group-focus-visible:ring-[#8ab9ff]`}>
|
||
{item.markerNumber}
|
||
</span>
|
||
<span
|
||
className={`pointer-events-none absolute top-1/2 max-w-[140px] -translate-y-1/2 truncate rounded-full bg-[#101828]/90 px-3 py-1.5 text-[11px] font-semibold text-white shadow-[0_4px_14px_rgba(15,23,42,0.24)] sm:max-w-[220px] ${
|
||
showComment ? 'block' : 'hidden'
|
||
} ${
|
||
alignRight ? 'right-9' : 'left-9'
|
||
}`}
|
||
aria-hidden={!showComment}
|
||
>
|
||
{summary}
|
||
</span>
|
||
</button>
|
||
)
|
||
}
|