ClipboardManager
clipboardmanager-1779379195924.tsx
'use client'
import { useState } from 'react'
interface ClipItem {
id: number
content: string
type: 'text' | 'code' | 'url' | 'email'
pinned: boolean
time: number
}
const INITIAL: ClipItem[] = [
{ id: 1, content: 'npx empire-ui-mcp --stdio', type: 'code', pinned: true, time: Date.now() - 60000 },
{ id: 2, content: 'https://empire-ui.com/components/glow-button', type: 'url', pinned: false, time: Date.now() - 180000 },
{ id: 3, content: 'business@digital-empire.uk', type: 'email', pinned: true, time: Date.now() - 300000 },
{ id: 4, content: "import GlowButton from '@empire-ui/components'", type: 'code', pinned: false, time: Date.now() - 600000 },
{ id: 5, content: 'Nq8jpnj17EjQaJ3ciJPb7AEH4ZuZueF9', type: 'text', pinned: false, time: Date.now() - 900000 },
]
const TYPE_ICONS = { text: '📝', code: '💻', url: '🔗', email: '📧' }
const TYPE_COLORS = { text: '#64748b', code: '#6366f1', url: '#3b82f6', email: '#22c55e' }
function timeAgo(ms: number) {
const s = (Date.now() - ms) / 1000
if (s < 60) return 'just now'
if (s < 3600) return `${Math.floor(s / 60)}m ago`
return `${Math.floor(s / 3600)}h ago`
}
export default function ClipboardManager() {
const [items, setItems] = useState(INITIAL)
const [filter, setFilter] = useState('')
const [copied, setCopied] = useState<number | null>(null)
function copy(item: ClipItem) {
navigator.clipboard.writeText(item.content)
setCopied(item.id)
setTimeout(() => setCopied(null), 1500)
}
function togglePin(id: number) {
setItems(it => it.map(i => i.id === id ? { ...i, pinned: !i.pinned } : i))
}
function remove(id: number) {
setItems(it => it.filter(i => i.id !== id))
}
const filtered = items.filter(i => i.content.toLowerCase().includes(filter.toLowerCase()))
const pinned = filtered.filter(i => i.pinned)
const unpinned = filtered.filter(i => !i.pinned)
return (
<div style={{ background: '#0D0D0D', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 16, overflow: 'hidden', width: 380 }}>
<div style={{ padding: '14px 16px', borderBottom: '1px solid rgba(255,255,255,0.06)', display: 'flex', gap: 10, alignItems: 'center' }}>
<span style={{ fontSize: 14 }}>📋</span>
<input value={filter} onChange={e => setFilter(e.target.value)} placeholder="Search clipboard..."
style={{ flex: 1, background: 'none', border: 'none', color: '#F5F5F0', fontSize: 13, outline: 'none' }} />
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: 12 }}>{items.length} items</span>
</div>
<div style={{ maxHeight: 360, overflowY: 'auto' }}>
{[...pinned, ...unpinned].map((item, i) => (
<div key={item.id} style={{ padding: '10px 14px', borderBottom: '1px solid rgba(255,255,255,0.04)', background: item.pinned ? 'rgba(201,168,76,0.03)' : 'transparent' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
<span style={{ fontSize: 12 }}>{TYPE_ICONS[item.type]}</span>
<span style={{ color: TYPE_COLORS[item.type], fontSize: 10, fontWeight: 600 }}>{item.type}</span>
{item.pinned && <span style={{ color: '#C9A84C', fontSize: 10 }}>📌</span>}
<span style={{ marginLeft: 'auto', color: 'rgba(255,255,255,0.25)', fontSize: 10 }}>{timeAgo(item.time)}</span>
</div>
<div style={{ color: 'rgba(255,255,255,0.7)', fontSize: 12, fontFamily: item.type === 'code' ? 'monospace' : 'inherit', marginBottom: 8, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{item.content}</div>
<div style={{ display: 'flex', gap: 6 }}>
<button onClick={() => copy(item)} style={{ background: copied === item.id ? 'rgba(34,197,94,0.12)' : 'rgba(255,255,255,0.06)', border: '1px solid', borderColor: copied === item.id ? 'rgba(34,197,94,0.25)' : 'rgba(255,255,255,0.08)', color: copied === item.id ? '#22c55e' : '#F5F5F0', borderRadius: 5, padding: '3px 10px', cursor: 'pointer', fontSize: 11 }}>{copied === item.id ? '✓' : 'Copy'}</button>
<button onClick={() => togglePin(item.id)} style={{ background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.07)', color: item.pinned ? '#C9A84C' : 'rgba(255,255,255,0.4)', borderRadius: 5, padding: '3px 8px', cursor: 'pointer', fontSize: 11 }}>{item.pinned ? 'Unpin' : 'Pin'}</button>
<button onClick={() => remove(item.id)} style={{ marginLeft: 'auto', background: 'none', border: 'none', color: 'rgba(255,255,255,0.2)', cursor: 'pointer', fontSize: 14, padding: '0 4px' }}>×</button>
</div>
</div>
))}
{filtered.length === 0 && <div style={{ padding: 20, textAlign: 'center', color: 'rgba(255,255,255,0.3)', fontSize: 13 }}>No results</div>}
</div>
</div>
)
}Component info
CategoryUtility
Frameworkreact
TierFREE
Views0
Copies0
About
Clipboard history manager with categories, search, pin items, and quick paste shortcuts
More from Utility
'use client'
import { useState } from 'react'
const PRESETS = [
{ name: 'Gold', primary: '#C9A84C', bg: '#0A0A0A', accent: '#6366f1' },
{ name: 'Neon', primary: '#22d3ee', bg: '#030712', accent: '#a78bfa' },
{ name: 'Crimson', primary: '#ef444ThemeCustomizer
Utility
'use client'
import { useState, useCallback } from 'react'
interface UploadedFile {
id: number
name: string
size: number
type: string
progress: number
done: boolean
error?: string
}
const ALLOWED = ['image/png', 'image/jpeg', 'image/wFileUploadZone
Utility