fix: 콘텐츠 캘린더 흐림 현상 수정 — whileInView 제거

SectionWrapper의 motion.section이 opacity:0 initial 상태에서
framer-motion animate가 발동하지 않아 전체 섹션이 투명하게 보이는
문제를 수정. SectionWrapper를 일반 <section>으로 교체하고,
plan 컴포넌트들의 whileInView/viewport 애니메이션 제거.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
Haewon Kam 2026-04-14 15:33:34 +09:00
parent 7dfa416089
commit 5f7d58c490
7 changed files with 15 additions and 33 deletions

View File

@ -92,8 +92,7 @@ export default function AssetCollection({ data }: AssetCollectionProps) {
className="rounded-2xl border border-slate-100 bg-white shadow-sm p-5 cursor-pointer hover:shadow-[3px_4px_12px_rgba(0,0,0,0.06)] hover:border-[#D5CDF5] transition-all" className="rounded-2xl border border-slate-100 bg-white shadow-sm p-5 cursor-pointer hover:shadow-[3px_4px_12px_rgba(0,0,0,0.06)] hover:border-[#D5CDF5] transition-all"
onClick={() => setSelectedAsset({ kind: 'asset', data: asset })} onClick={() => setSelectedAsset({ kind: 'asset', data: asset })}
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: i * 0.05 }} transition={{ duration: 0.4, delay: i * 0.05 }}
> >
{/* Top badges row */} {/* Top badges row */}
@ -155,8 +154,7 @@ export default function AssetCollection({ data }: AssetCollectionProps) {
className="min-w-[280px] rounded-2xl border border-slate-100 bg-white shadow-sm p-5 shrink-0 cursor-pointer hover:shadow-[3px_4px_12px_rgba(0,0,0,0.06)] hover:border-[#D5CDF5] transition-all" className="min-w-[280px] rounded-2xl border border-slate-100 bg-white shadow-sm p-5 shrink-0 cursor-pointer hover:shadow-[3px_4px_12px_rgba(0,0,0,0.06)] hover:border-[#D5CDF5] transition-all"
onClick={() => setSelectedAsset({ kind: 'youtube', data: video })} onClick={() => setSelectedAsset({ kind: 'youtube', data: video })}
initial={{ opacity: 0, x: 20 }} initial={{ opacity: 0, x: 20 }}
whileInView={{ opacity: 1, x: 0 }} animate={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: i * 0.1 }} transition={{ duration: 0.4, delay: i * 0.1 }}
> >
<div className="flex items-start gap-2 mb-3"> <div className="flex items-start gap-2 mb-3">

View File

@ -54,8 +54,7 @@ export default function ChannelStrategy({ channels }: ChannelStrategyProps) {
key={ch.channelId} key={ch.channelId}
className="bg-white rounded-2xl p-6 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] hover:shadow-[4px_6px_16px_rgba(0,0,0,0.09)] transition-shadow" className="bg-white rounded-2xl p-6 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] hover:shadow-[4px_6px_16px_rgba(0,0,0,0.09)] transition-shadow"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: index * 0.1 }} transition={{ duration: 0.5, delay: index * 0.1 }}
> >
{/* Header */} {/* Header */}

View File

@ -320,8 +320,7 @@ export default function ContentCalendar({ data, planId, onEntryUpdate }: Content
} ${filterType && !isActive ? 'opacity-40' : ''}`} } ${filterType && !isActive ? 'opacity-40' : ''}`}
onClick={() => toggleFilter(item.type)} onClick={() => toggleFilter(item.type)}
initial={{ opacity: 0, y: 10 }} initial={{ opacity: 0, y: 10 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.3, delay: i * 0.07 }} transition={{ duration: 0.3, delay: i * 0.07 }}
> >
<Icon size={16} className={`${colors.text} opacity-70`} /> <Icon size={16} className={`${colors.text} opacity-70`} />
@ -362,8 +361,7 @@ export default function ContentCalendar({ data, planId, onEntryUpdate }: Content
key={week.weekNumber} key={week.weekNumber}
className="bg-white rounded-2xl p-5 mb-4 shadow-[3px_4px_12px_rgba(0,0,0,0.06)]" className="bg-white rounded-2xl p-5 mb-4 shadow-[3px_4px_12px_rgba(0,0,0,0.06)]"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: weekIdx * 0.1 }} transition={{ duration: 0.4, delay: weekIdx * 0.1 }}
> >
<p className="text-sm font-bold text-[#0A1128] mb-3">{week.label}</p> <p className="text-sm font-bold text-[#0A1128] mb-3">{week.label}</p>

View File

@ -12,8 +12,7 @@ export default function PlanCTA() {
<motion.section <motion.section
className="py-16 md:py-20 px-6" className="py-16 md:py-20 px-6"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6, ease: 'easeOut' }} transition={{ duration: 0.6, ease: 'easeOut' }}
> >
<div className="max-w-7xl mx-auto"> <div className="max-w-7xl mx-auto">

View File

@ -51,15 +51,13 @@ export default function PlanHeader({
<motion.div <motion.div
className="flex-1 text-center md:text-left" className="flex-1 text-center md:text-left"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5 }} transition={{ duration: 0.5 }}
> >
<motion.p <motion.p
className="text-xs font-semibold text-[#6C5CE7] mb-4 tracking-widest uppercase" className="text-xs font-semibold text-[#6C5CE7] mb-4 tracking-widest uppercase"
initial={{ opacity: 0, y: 10 }} initial={{ opacity: 0, y: 10 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: 0.1 }} transition={{ duration: 0.5, delay: 0.1 }}
> >
Marketing Execution Plan Marketing Execution Plan
@ -68,8 +66,7 @@ export default function PlanHeader({
<motion.h1 <motion.h1
className="font-serif text-4xl md:text-5xl font-bold text-[#0A1128] mb-3" className="font-serif text-4xl md:text-5xl font-bold text-[#0A1128] mb-3"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: 0.2 }} transition={{ duration: 0.5, delay: 0.2 }}
> >
{clinicName} {clinicName}
@ -78,8 +75,7 @@ export default function PlanHeader({
<motion.p <motion.p
className="text-xl text-slate-600 mb-8" className="text-xl text-slate-600 mb-8"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: 0.3 }} transition={{ duration: 0.5, delay: 0.3 }}
> >
{clinicNameEn} {clinicNameEn}
@ -88,8 +84,7 @@ export default function PlanHeader({
<motion.div <motion.div
className="flex flex-wrap gap-3 justify-center md:justify-start" className="flex flex-wrap gap-3 justify-center md:justify-start"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: 0.4 }} transition={{ duration: 0.5, delay: 0.4 }}
> >
<span className="inline-flex items-center gap-2 rounded-full bg-white/60 backdrop-blur-sm border border-white/40 px-3 py-1 text-sm font-medium text-slate-700"> <span className="inline-flex items-center gap-2 rounded-full bg-white/60 backdrop-blur-sm border border-white/40 px-3 py-1 text-sm font-medium text-slate-700">
@ -107,8 +102,7 @@ export default function PlanHeader({
<motion.div <motion.div
className="shrink-0" className="shrink-0"
initial={{ opacity: 0, scale: 0.8 }} initial={{ opacity: 0, scale: 0.8 }}
whileInView={{ opacity: 1, scale: 1 }} animate={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.6, delay: 0.3 }} transition={{ duration: 0.6, delay: 0.3 }}
> >
<div className="w-32 h-32 rounded-full bg-gradient-to-r from-[#4F1DA1] to-[#021341] flex flex-col items-center justify-center shadow-lg"> <div className="w-32 h-32 rounded-full bg-gradient-to-r from-[#4F1DA1] to-[#021341] flex flex-col items-center justify-center shadow-lg">

View File

@ -67,8 +67,7 @@ export default function RepurposingProposal({ proposals }: RepurposingProposalPr
key={item.sourceVideo.title} key={item.sourceVideo.title}
className="rounded-2xl border border-slate-100 bg-white shadow-[3px_4px_12px_rgba(0,0,0,0.06)] overflow-hidden" className="rounded-2xl border border-slate-100 bg-white shadow-[3px_4px_12px_rgba(0,0,0,0.06)] overflow-hidden"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: idx * 0.08 }} transition={{ duration: 0.4, delay: idx * 0.08 }}
> >
{/* Card Header — click to expand */} {/* Card Header — click to expand */}

View File

@ -1,5 +1,4 @@
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { motion } from 'motion/react';
interface SectionWrapperProps { interface SectionWrapperProps {
id: string; id: string;
@ -19,12 +18,8 @@ export function SectionWrapper({
className = '', className = '',
}: SectionWrapperProps) { }: SectionWrapperProps) {
return ( return (
<motion.section <section
id={id} id={id}
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6, ease: 'easeOut' }}
className={` className={`
${dark ${dark
? 'bg-[#0A1128] text-white relative overflow-hidden' ? 'bg-[#0A1128] text-white relative overflow-hidden'
@ -60,6 +55,6 @@ export function SectionWrapper({
</div> </div>
{children} {children}
</div> </div>
</motion.section> </section>
); );
} }