| ... | @@ -86,6 +86,15 @@ const PlanSidebar = memo(function PlanSidebar({ | ... | @@ -86,6 +86,15 @@ const PlanSidebar = memo(function PlanSidebar({ |
| 86 | }, 2000); | 86 | }, 2000); |
| 87 | }, [planMarkdown]); | 87 | }, [planMarkdown]); |
| 88 | | 88 | |
| | 89 | // Cleanup timeout on unmount |
| | 90 | useEffect(() => { |
| | 91 | return () => { |
| | 92 | if (copiedTimerRef.current != null) { |
| | 93 | clearTimeout(copiedTimerRef.current); |
| | 94 | } |
| | 95 | }; |
| | 96 | }, []); |
| | 97 | |
| 89 | const handleDownload = useCallback(() => { | 98 | const handleDownload = useCallback(() => { |
| 90 | if (!planMarkdown) return; | 99 | if (!planMarkdown) return; |
| 91 | const filename = buildProposedPlanMarkdownFilename(planMarkdown); | 100 | const filename = buildProposedPlanMarkdownFilename(planMarkdown); |
| ... | @@ -128,14 +137,6 @@ const PlanSidebar = memo(function PlanSidebar({ | ... | @@ -128,14 +137,6 @@ const PlanSidebar = memo(function PlanSidebar({ |
| 128 | {/* Header */} | 137 | {/* Header */} |
| 129 | <div className="flex h-12 shrink-0 items-center justify-between border-b border-border/60 px-3"> | 138 | <div className="flex h-12 shrink-0 items-center justify-between border-b border-border/60 px-3"> |
| 130 | <div className="flex items-center gap-2"> | 139 | <div className="flex items-center gap-2"> |
| 131 | // Cleanup timeout on unmount | | |
| 132 | useEffect(() => { | | |
| 133 | return () => { | | |
| 134 | if (copiedTimerRef.current \!= null) { | | |
| 135 | clearTimeout(copiedTimerRef.current); | | |
| 136 | } | | |
| 137 | }; | | |
| 138 | }, []); | | |
| 139 | <Badge | 140 | <Badge |
| 140 | variant="secondary" | 141 | variant="secondary" |
| 141 | className="rounded-md bg-blue-500/10 px-1.5 py-0 text-[10px] font-semibold tracking-wide text-blue-400 uppercase" | 142 | className="rounded-md bg-blue-500/10 px-1.5 py-0 text-[10px] font-semibold tracking-wide text-blue-400 uppercase" |