87 lines
3.3 KiB
TypeScript
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>
|
|
);
|
|
}
|