Add copy button to claim cards with full attribution

Each claim card now includes a copy button that copies all 5 claims plus proper attribution to the clipboard in a citation-ready format.

Features:
- Copy button with icon (Copy → Check on success)
- Copies all 5 numbered claims
- Includes full attribution footer:
  - Source title
  - Author: Kamil Banc, AI Adopters Club
  - URL to claim page
  - Original article URL
  - CC BY 4.0 license
- Visual feedback: "Copied!" confirmation for 2 seconds
- Lightweight: Uses native Clipboard API, no dependencies

Documentation updates:
- Added "Current System Architecture" section to WORKFLOW.md
- Documented homepage structure (unified header, wide containers)
- Documented claims library features (5-column grid, copy button)
- Listed all strict build requirements (12-18 tokens, etc.)
- Included copy format template for reference

This ensures:
✓ Easy claim sharing with proper attribution
✓ Compliance with CC BY 4.0 license requirements
✓ All future claims follow current system setup
✓ Consistent citation format across all uses

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kbanc85 2025-11-09 14:34:03 -05:00
parent 98b1e6482b
commit 8e87da3958
2 changed files with 104 additions and 14 deletions

View File

@ -14,6 +14,55 @@ This document outlines the complete, step-by-step process for creating new claim
---
## Current System Architecture (2025-11-09)
### Homepage Structure
- **Unified Header:** Photo + name/title flows horizontally with bio content on desktop, stacks vertically on mobile
- **Container Width:** `max-w-[1920px]` with responsive padding (`px-6 md:px-8 lg:px-12`)
- **Claims Library:** Full interactive library with search, topic filters, and 5-column responsive grid
- **No separate Bio section:** All consolidated into Header component
### Claims Library Features
- **Responsive Grid:** 1 → 2 → 3 → 4 → 5 columns as screen width increases
- **Card Structure (per article):**
- Topic tags
- Article title (linked to detail page)
- Featured claim (single-sentence italic context)
- All 5 atomic claims (bulleted list, 12-18 tokens each)
- Publication date
- "View Claims →" link
- **Copy button:** Copies all 5 claims + full attribution to clipboard
- **Copy Format:**
```
[Article Title]
1. [Claim 1]
2. [Claim 2]
3. [Claim 3]
4. [Claim 4]
5. [Claim 5]
---
Source: [Article Title]
Author: Kamil Banc, AI Adopters Club
URL: https://kbanc.com/claims-library/[slug]
Original Article: [originalUrl]
License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
```
### Strict Requirements (Build Blockers)
1. **Token Length:** Every claim MUST be 12-18 tokens (validation enforced, build fails otherwise)
2. **Claim Count:** Exactly 5 claims per article
3. **Featured Claim:** Required single-sentence summary for card display
4. **Date Format:** YYYY-MM-DD
5. **URL Format:** Must start with `https://aiadopters.club/p/`
---
## Step 1: Select Source Article
### 1.1 Identify Article

View File

@ -1,13 +1,14 @@
"use client";
import Link from "next/link";
import { Search } from "lucide-react";
import { Search, Copy, Check } from "lucide-react";
import { useState, useMemo } from "react";
import { ALL_CLAIMS_DATA, getTotalClaimsCount } from "@/data/claims";
const ClaimsLibrary = () => {
const [selectedTopic, setSelectedTopic] = useState<string>("all");
const [searchQuery, setSearchQuery] = useState("");
const [copiedSlug, setCopiedSlug] = useState<string | null>(null);
// Automatically populated from centralized claims data
const articles = ALL_CLAIMS_DATA;
@ -48,6 +49,27 @@ const ClaimsLibrary = () => {
{ id: "measurement", label: "ROI & Measurement", color: "bg-purple-100 text-purple-800" },
];
const copyClaimsToClipboard = async (article: typeof ALL_CLAIMS_DATA[0]) => {
const formattedText = `${article.title}
${article.claims.map((claim, idx) => `${idx + 1}. ${claim}`).join('\n\n')}
---
Source: ${article.title}
Author: Kamil Banc, AI Adopters Club
URL: https://kbanc.com/claims-library/${article.slug}
Original Article: ${article.originalUrl}
License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)`;
try {
await navigator.clipboard.writeText(formattedText);
setCopiedSlug(article.slug);
setTimeout(() => setCopiedSlug(null), 2000);
} catch (err) {
console.error('Failed to copy:', err);
}
};
return (
<section className="py-10 md:py-12 border-b border-border">
<div className="container max-w-[1920px] mx-auto px-6 md:px-8 lg:px-12">
@ -143,7 +165,8 @@ const ClaimsLibrary = () => {
</ul>
{/* Footer */}
<div className="flex items-center justify-between pt-3 border-t border-border">
<div className="pt-3 border-t border-border">
<div className="flex items-center justify-between mb-2">
<span className="text-xs text-muted-foreground">
{new Date(article.date).toLocaleDateString('en-US', {
month: 'short',
@ -158,6 +181,24 @@ const ClaimsLibrary = () => {
View Claims →
</Link>
</div>
<button
onClick={() => copyClaimsToClipboard(article)}
className="w-full flex items-center justify-center gap-2 py-2 px-3 text-xs font-medium text-muted-foreground hover:text-foreground bg-muted hover:bg-muted/80 rounded transition-colors"
aria-label="Copy all claims to clipboard"
>
{copiedSlug === article.slug ? (
<>
<Check className="h-3 w-3" />
Copied!
</>
) : (
<>
<Copy className="h-3 w-3" />
Copy All Claims
</>
)}
</button>
</div>
</article>
))}
</div>