Files
sam-react-prod/src/components/common/ScheduleCalendar/ScheduleBar.tsx
유병철 1575f9e680 feat(WEB): 스켈레톤 구조 개선 및 달력 UI 개선
스켈레톤 시스템:
- 타이틀은 항상 표시, 나머지 영역만 스켈레톤 처리
- 헤더 액션, 검색, 테이블 영역 개별 스켈레톤 적용

달력 UI:
- 경계선 색상 border-gray-200으로 통일
- 지난 일자 배경색 bg-gray-300으로 더 어둡게
- 선택/오늘 날짜 색상 보라색으로 변경 (이벤트 바와 구분)
- 날짜-이벤트 바 간격 8px 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 22:31:40 +09:00

96 lines
2.8 KiB
TypeScript

'use client';
import { cn } from '@/components/ui/utils';
import type { ScheduleEvent } from './types';
import { EVENT_COLORS } from './types';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';
interface ScheduleBarProps {
event: ScheduleEvent;
/** 현재 주에서 시작하는지 */
isStart: boolean;
/** 현재 주에서 끝나는지 */
isEnd: boolean;
/** 차지하는 컬럼 수 (1-7) */
colSpan: number;
/** 시작 위치 (0-6) */
startCol: number;
/** 행 인덱스 (겹치는 이벤트 처리) */
rowIndex: number;
onClick: (event: ScheduleEvent) => void;
}
/**
* 일정 바 컴포넌트
* - 일정 바 렌더링 (시작~종료 날짜)
* - 여러 날에 걸치는 바 표시
* - 색상 구분 (상태별)
* - 호버/클릭 이벤트
* - 툴팁으로 담당자/기간 정보 표시
*/
export function ScheduleBar({
event,
isStart,
isEnd,
colSpan,
startCol,
rowIndex,
onClick,
}: ScheduleBarProps) {
const color = event.color || 'blue';
const colorClass = EVENT_COLORS[color] || EVENT_COLORS.blue;
// 컬럼 너비 계산 (각 셀은 1/7)
const widthPercent = (colSpan / 7) * 100;
const leftPercent = (startCol / 7) * 100;
// 툴팁 내용 생성
const tooltipContent = `${event.title}\n기간: ${event.startDate} ~ ${event.endDate}`;
return (
<TooltipProvider delayDuration={200}>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onClick(event);
}}
className={cn(
'absolute h-5 px-2 text-xs font-medium truncate',
'transition-all hover:opacity-80 hover:shadow-sm',
'flex items-center cursor-pointer',
colorClass,
// 라운드 처리
isStart && isEnd && 'rounded-md',
isStart && !isEnd && 'rounded-l-md',
!isStart && isEnd && 'rounded-r-md',
!isStart && !isEnd && 'rounded-none'
)}
style={{
width: `calc(${widthPercent}% - 4px)`,
left: `calc(${leftPercent}% + 2px)`,
top: `${rowIndex * 24 + 40}px`, // 날짜 영역(40px) 아래부터 시작 (간격 8px 추가)
}}
>
{isStart && <span className="truncate">{event.title}</span>}
</button>
</TooltipTrigger>
<TooltipContent side="top" className="max-w-xs">
<div className="text-sm">
<p className="font-medium">{event.title}</p>
<p className="text-muted-foreground text-xs mt-1">
: {event.startDate} ~ {event.endDate}
</p>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}