Scrum4Me/components/ideas/download-md-button.tsx
Madhura68 1ba9feac1a ui: idea-timeline + pbi-link-card + download-md-button (M12 T-512)
components/ideas/idea-timeline.tsx:
- Chronological merge of IdeaLog + ClaudeQuestion (sorted desc by created_at)
- Per-entry icon by log-type (DECISION/NOTE/GRILL_RESULT/PLAN_RESULT/
  STATUS_CHANGE/JOB_EVENT) + question-status label
- MD3-tokens, vertical timeline rail (border-left + dots)
- Question entries show options + answer (border-left highlight)
- Metadata expansion via <details> for log entries

components/ideas/idea-pbi-link-card.tsx:
- PLANNED + pbi present: green status-done card with PBI link
- PLANNED + pbi removed (FK SetNull): blocked-color banner with
  "Plan opnieuw beschikbaar maken" → relinkIdeaPlanAction
- Demo blocked on relink

components/ideas/download-md-button.tsx:
- Calls downloadIdeaMdAction → builds Blob + anchor + click()
- Filename: {idea.code}-{kind}.md
- Demo MAY use it (read-only)

components/ideas/idea-detail-layout.tsx:
- Replaces inline placeholders with extracted components
- Md tabs gain Download (.md) button + Edit button row

Tests: 546/546 still green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 21:39:33 +02:00

55 lines
1.4 KiB
TypeScript

'use client'
// DownloadMdButton — download grill_md of plan_md als .md-bestand.
// Demo MAG downloaden (read-only). Server-action returnt md-string; client
// bouwt een Blob + anchor + click().
import { useTransition } from 'react'
import { Download } from 'lucide-react'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { downloadIdeaMdAction } from '@/actions/ideas'
interface Props {
ideaId: string
kind: 'grill' | 'plan'
hasContent: boolean
}
export function DownloadMdButton({ ideaId, kind, hasContent }: Props) {
const [pending, startTransition] = useTransition()
function handleClick() {
startTransition(async () => {
const r = await downloadIdeaMdAction(ideaId, kind)
if ('error' in r) {
toast.error(r.error)
return
}
if (!r.data) return
const blob = new Blob([r.data.markdown], { type: 'text/markdown;charset=utf-8' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = r.data.filename
document.body.appendChild(a)
a.click()
a.remove()
URL.revokeObjectURL(url)
})
}
return (
<Button
size="sm"
variant="ghost"
onClick={handleClick}
disabled={pending || !hasContent}
title={hasContent ? `Download ${kind}_md` : 'Geen content'}
>
<Download className="size-3.5 mr-1" />
.md
</Button>
)
}