Sergei bda883d34d Add Beneficiary Detail Page with tabs and status components
- Create BeneficiaryDetailPage with Overview, Sensors, and Activity tabs
- Add StatusBadge and SensorStatusBadge UI components
- Add Tabs component (Tabs, TabsList, TabsTrigger, TabsContent)
- Add getBeneficiary API method
- Include comprehensive tests for all new components
- Update ESLint config with root:true to prevent config inheritance

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-01 08:26:31 -08:00

88 lines
2.1 KiB
TypeScript

import React, { useState, createContext, useContext } from 'react';
interface TabsContextType {
activeTab: string;
setActiveTab: (tab: string) => void;
}
const TabsContext = createContext<TabsContextType | null>(null);
interface TabsProps {
defaultValue: string;
children: React.ReactNode;
className?: string;
}
export function Tabs({ defaultValue, children, className = '' }: TabsProps) {
const [activeTab, setActiveTab] = useState(defaultValue);
return (
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
<div className={className}>{children}</div>
</TabsContext.Provider>
);
}
interface TabsListProps {
children: React.ReactNode;
className?: string;
}
export function TabsList({ children, className = '' }: TabsListProps) {
return (
<div
className={`flex border-b border-gray-200 ${className}`}
role="tablist"
>
{children}
</div>
);
}
interface TabsTriggerProps {
value: string;
children: React.ReactNode;
className?: string;
}
export function TabsTrigger({ value, children, className = '' }: TabsTriggerProps) {
const context = useContext(TabsContext);
if (!context) throw new Error('TabsTrigger must be used within Tabs');
const isActive = context.activeTab === value;
return (
<button
role="tab"
aria-selected={isActive}
onClick={() => context.setActiveTab(value)}
className={`px-4 py-3 text-sm font-medium border-b-2 transition-colors ${
isActive
? 'border-primary text-primary'
: 'border-transparent text-textSecondary hover:text-textPrimary hover:border-gray-300'
} ${className}`}
>
{children}
</button>
);
}
interface TabsContentProps {
value: string;
children: React.ReactNode;
className?: string;
}
export function TabsContent({ value, children, className = '' }: TabsContentProps) {
const context = useContext(TabsContext);
if (!context) throw new Error('TabsContent must be used within Tabs');
if (context.activeTab !== value) return null;
return (
<div role="tabpanel" className={`pt-4 ${className}`}>
{children}
</div>
);
}