o2o-clinicad-frontend/src/features/plan/ui/channelStrategy/ChannelStrategyGrid.tsx

87 lines
3.3 KiB
TypeScript

import CalendarIcon from "@/assets/report/calendar.svg?react";
import { Pill } from "@/components/atoms/Pill";
import { Surface } from "@/components/atoms/Surface";
import type { ChannelStrategyCard } from "@/features/plan/types/marketingPlan";
import { BrandingChannelIcon } from "@/features/plan/ui/branding/BrandingChannelIcon";
import { channelStrategyPriorityPillClass } from "@/features/plan/ui/channelStrategy/channelStrategyPillClass";
type ChannelStrategyGridProps = {
channels: ChannelStrategyCard[];
};
function ChannelStrategyCard({ ch, index }: { ch: ChannelStrategyCard; index: number }) {
const delayClass =
index === 0
? ""
: index === 1
? "animation-delay-100"
: index === 2
? "animation-delay-200"
: "animation-delay-300";
return (
<Surface
bordered={false}
padding="lg"
interactive="lift"
className={`animate-fade-in-up ${delayClass}`}
>
<div className="flex items-center gap-3 mb-4 min-w-0">
<div className="w-10 h-10 rounded-xl bg-[var(--color-status-good-bg)] flex items-center justify-center shrink-0">
<BrandingChannelIcon icon={ch.icon} className="text-[var(--color-status-good-dot)]" width={20} height={20} />
</div>
<h4 className="title-18-md-20 text-navy-900 flex-1 min-w-0 break-keep">{ch.channelName}</h4>
<Pill weight="semibold" className={`shrink-0 border ${channelStrategyPriorityPillClass(ch.priority)}`}>
{ch.priority}
</Pill>
</div>
<div className="flex items-center gap-2 mb-4 flex-wrap">
<Pill className="border bg-[var(--color-status-critical-bg)] text-[var(--color-status-critical-text)] border-[var(--color-status-critical-border)]">
{ch.currentStatus}
</Pill>
<span className="body-14 text-neutral-60 shrink-0" aria-hidden>
</span>
<Pill className="border bg-[var(--color-status-good-bg)] text-[var(--color-status-good-text)] border-[var(--color-status-good-border)]">
{ch.targetGoal}
</Pill>
</div>
<div className="flex flex-wrap gap-2 mb-4">
{ch.contentTypes.map((type) => (
<Pill key={type} className="bg-neutral-10 border border-neutral-20 text-neutral-70">
{type}
</Pill>
))}
</div>
<div className="flex items-center gap-2 mb-3 min-w-0">
<CalendarIcon width={14} height={14} className="text-[var(--color-status-good-dot)] shrink-0" aria-hidden />
<p className="body-14 text-neutral-70 break-keep">{ch.postingFrequency}</p>
</div>
<p className="body-14 italic text-violet-500/80 mb-4 break-keep">{ch.tone}</p>
<ul className="space-y-2">
{ch.formatGuidelines.map((guideline, i) => (
<li key={i} className="flex items-start gap-2">
<span className="shrink-0 w-2 h-2 rounded-full bg-violet-500 mt-2" aria-hidden />
<span className="body-14 text-neutral-80 break-keep">{guideline}</span>
</li>
))}
</ul>
</Surface>
);
}
export function ChannelStrategyGrid({ channels }: ChannelStrategyGridProps) {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{channels.map((ch, index) => (
<ChannelStrategyCard key={ch.channelId} ch={ch} index={index} />
))}
</div>
);
}