75 lines
3.5 KiB
TypeScript
75 lines
3.5 KiB
TypeScript
import { Button } from '@/components/ui/button';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { cn } from '@/lib/utils';
|
|
import {
|
|
Sparkles, TrendingUp, Layers, MapPin, Search,
|
|
} from 'lucide-react';
|
|
import type { Surface, PlacementItem } from '@/lib/types/ad-control';
|
|
|
|
const SURFACE_ICONS: Record<string, React.ElementType> = {
|
|
Sparkles, TrendingUp, Layers, MapPin, Search,
|
|
};
|
|
|
|
interface SurfaceTabsProps {
|
|
surfaces: Surface[];
|
|
activeSurfaceId: string;
|
|
onSelect: (surfaceId: string) => void;
|
|
placementCounts: Record<string, number>; // surfaceId → active/scheduled count
|
|
}
|
|
|
|
export function SurfaceTabs({ surfaces, activeSurfaceId, onSelect, placementCounts }: SurfaceTabsProps) {
|
|
return (
|
|
<div className="w-64 flex-shrink-0">
|
|
<div className="sticky top-24 space-y-1.5">
|
|
<p className="px-3 text-[10px] uppercase tracking-widest text-muted-foreground font-semibold mb-3">
|
|
Placement Surfaces
|
|
</p>
|
|
{surfaces.map((surface) => {
|
|
const Icon = SURFACE_ICONS[surface.icon] || Sparkles;
|
|
const count = placementCounts[surface.id] || 0;
|
|
const isActive = surface.id === activeSurfaceId;
|
|
|
|
return (
|
|
<button
|
|
key={surface.id}
|
|
onClick={() => onSelect(surface.id)}
|
|
className={cn(
|
|
'w-full flex items-center gap-3 px-3 py-3 rounded-xl text-left transition-all duration-200',
|
|
isActive
|
|
? 'bg-primary text-primary-foreground shadow-lg'
|
|
: 'hover:bg-muted/50 text-foreground'
|
|
)}
|
|
>
|
|
<div className={cn(
|
|
'h-9 w-9 rounded-lg flex items-center justify-center flex-shrink-0',
|
|
isActive ? 'bg-white/20' : 'bg-muted'
|
|
)}>
|
|
<Icon className="h-4 w-4" />
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<p className="text-sm font-medium truncate">{surface.name.replace('Home ', '').replace(' Events', '')}</p>
|
|
<p className={cn(
|
|
'text-[11px]',
|
|
isActive ? 'text-primary-foreground/70' : 'text-muted-foreground'
|
|
)}>
|
|
{surface.layoutType} · {surface.sortBehavior}
|
|
</p>
|
|
</div>
|
|
<Badge
|
|
variant={isActive ? 'secondary' : 'outline'}
|
|
className={cn(
|
|
'text-[10px] h-5 min-w-[36px] justify-center font-mono',
|
|
isActive && 'bg-white/20 text-primary-foreground border-transparent',
|
|
count >= surface.maxSlots && !isActive && 'bg-red-50 text-red-600 border-red-200'
|
|
)}
|
|
>
|
|
{count}/{surface.maxSlots}
|
|
</Badge>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|