diff --git a/src/components/shared/Carousel.jsx b/src/components/shared/Carousel.tsx similarity index 83% rename from src/components/shared/Carousel.jsx rename to src/components/shared/Carousel.tsx index 032ea59..2f04662 100644 --- a/src/components/shared/Carousel.jsx +++ b/src/components/shared/Carousel.tsx @@ -1,4 +1,13 @@ -import React, { useRef, useCallback, useState } from 'react'; +import React, { useRef, useCallback, useState, ReactNode, KeyboardEvent, TouchEvent } from 'react'; + +interface CarouselProps { + children: ReactNode; + activeIndex: number; + setActiveIndex: (index: number) => void; + labels?: string[]; + showLabels?: boolean; + className?: string; +} function Carousel({ children, @@ -7,10 +16,10 @@ function Carousel({ labels = [], showLabels = true, className = '' -}) { - const touchStartX = useRef(null); - const touchStartY = useRef(null); - const trackRef = useRef(null); +}: CarouselProps) { + const touchStartX = useRef(null); + const touchStartY = useRef(null); + const trackRef = useRef(null); const [isDragging, setIsDragging] = useState(false); const [dragOffset, setDragOffset] = useState(0); const itemCount = React.Children.count(children); @@ -19,20 +28,20 @@ function Carousel({ const SWIPE_THRESHOLD = 50; const VELOCITY_THRESHOLD = 0.3; - const handleTouchStart = useCallback((e) => { + const handleTouchStart = useCallback((e: TouchEvent) => { touchStartX.current = e.touches[0].clientX; touchStartY.current = e.touches[0].clientY; setIsDragging(true); setDragOffset(0); }, []); - const handleTouchMove = useCallback((e) => { + const handleTouchMove = useCallback((e: TouchEvent) => { if (!touchStartX.current || !isDragging) return; const currentX = e.touches[0].clientX; const currentY = e.touches[0].clientY; const diffX = currentX - touchStartX.current; - const diffY = currentY - touchStartY.current; + const diffY = currentY - (touchStartY.current || 0); // Only handle horizontal swipes if (Math.abs(diffX) > Math.abs(diffY)) { @@ -46,7 +55,7 @@ function Carousel({ } }, [isDragging, activeIndex, itemCount]); - const handleTouchEnd = useCallback((e) => { + const handleTouchEnd = useCallback((e: TouchEvent) => { if (!touchStartX.current || !isDragging) return; const endX = e.changedTouches[0].clientX; @@ -69,7 +78,7 @@ function Carousel({ setDragOffset(0); }, [isDragging, activeIndex, setActiveIndex, itemCount]); - const handleKeyDown = useCallback((e) => { + const handleKeyDown = useCallback((e: KeyboardEvent) => { if (e.key === 'ArrowLeft' && activeIndex > 0) { setActiveIndex(activeIndex - 1); } else if (e.key === 'ArrowRight' && activeIndex < itemCount - 1) { diff --git a/src/components/shared/ChartCard.jsx b/src/components/shared/ChartCard.tsx similarity index 73% rename from src/components/shared/ChartCard.jsx rename to src/components/shared/ChartCard.tsx index a9fa93b..83e4a40 100644 --- a/src/components/shared/ChartCard.jsx +++ b/src/components/shared/ChartCard.tsx @@ -1,4 +1,13 @@ -import React from 'react'; +import React, { ReactNode } from 'react'; + +interface ChartCardProps { + title?: string; + children: ReactNode; + className?: string; + headerRight?: ReactNode; + fullWidth?: boolean; + halfWidth?: boolean; +} function ChartCard({ title, @@ -7,7 +16,7 @@ function ChartCard({ headerRight = null, fullWidth = false, halfWidth = false -}) { +}: ChartCardProps) { const sizeClass = fullWidth ? 'full-width' : halfWidth ? 'half-width' : ''; return ( diff --git a/src/components/shared/EmptyState.jsx b/src/components/shared/EmptyState.tsx similarity index 79% rename from src/components/shared/EmptyState.jsx rename to src/components/shared/EmptyState.tsx index bc06edd..9dd75db 100644 --- a/src/components/shared/EmptyState.jsx +++ b/src/components/shared/EmptyState.tsx @@ -1,5 +1,14 @@ import React from 'react'; +interface EmptyStateProps { + icon?: string; + title?: string; + message?: string; + action?: (() => void) | null; + actionLabel?: string; + className?: string; +} + function EmptyState({ icon = '📊', title, @@ -7,7 +16,7 @@ function EmptyState({ action = null, actionLabel = 'Try Again', className = '' -}) { +}: EmptyStateProps) { return (