Add 4 card types, evidence board with red yarn strings, and 8 unique persistent boards
This commit is contained in:
1 parent
19eb968f86
commit
2bc4f55c44
10 files changed
+1637
-332
No files matched your search
@@ -531,6 +531,101 @@ export const PaperCard: React.FC<PaperCardProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 10. INTERACTIVE CHECKLIST CARD */}
|
||||
{card.type === 'checklist' && (
|
||||
<div className="p-4 flex flex-col justify-between h-full bg-[#FCFAF2] text-neutral-900 border border-neutral-300/80">
|
||||
<div>
|
||||
<div className="flex justify-between items-center pb-2 mb-2 border-b border-neutral-300">
|
||||
<span className="font-bold text-sm tracking-tight">{card.title || 'To-Do List'}</span>
|
||||
{card.todoItems && card.todoItems.length > 0 && (
|
||||
<span className="font-mono text-[10px] px-1.5 py-0.5 rounded bg-neutral-200 text-neutral-700">
|
||||
{card.todoItems.filter((t) => t.done).length}/{card.todoItems.length}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{card.todoItems && card.todoItems.length > 0 ? (
|
||||
<div className={`space-y-1.5 py-1 ${card.fontFamily || 'font-caveat'} text-base`}>
|
||||
{card.todoItems.map((item, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="flex items-center gap-2 cursor-pointer group"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onToggleTodo?.(card.id, idx);
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={item.done}
|
||||
readOnly
|
||||
className="cursor-pointer accent-neutral-900 rounded-sm w-3.5 h-3.5 pointer-events-none"
|
||||
/>
|
||||
<span className={`${item.done ? 'line-through text-neutral-400' : 'text-neutral-800'}`}>
|
||||
{item.text}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-xs text-neutral-500 italic py-2">
|
||||
{card.content || 'No tasks listed'}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="pt-2 border-t border-neutral-200 flex justify-between text-[10px] font-mono text-neutral-500">
|
||||
<span>CHECKLIST</span>
|
||||
<span>{card.date || 'PENDING'}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 11. VINTAGE TICKET / BOARDING PASS */}
|
||||
{card.type === 'ticket' && (
|
||||
<div
|
||||
className="p-3.5 flex flex-col justify-between bg-[#F4EDE2] text-neutral-900 font-mono text-xs border border-amber-900/30"
|
||||
style={{
|
||||
clipPath: 'polygon(0% 0%, 100% 0%, 100% 40%, 96% 45%, 96% 55%, 100% 60%, 100% 100%, 0% 100%, 0% 60%, 4% 55%, 4% 45%, 0% 40%)'
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-between items-center pb-1.5 border-b border-amber-900/30">
|
||||
<span className="text-[10px] font-black tracking-widest text-amber-900 uppercase">
|
||||
{card.subtitle || 'PASS // TICKET'}
|
||||
</span>
|
||||
<span className="text-[10px] text-neutral-600">
|
||||
NO. {card.tagNumber || '78429'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="my-auto py-2 text-center">
|
||||
<div className="text-sm font-bold tracking-wider text-neutral-900 uppercase">
|
||||
{card.title || 'BOARDING PASS'}
|
||||
</div>
|
||||
<div className="text-[11px] text-neutral-700 mt-1 whitespace-pre-line">
|
||||
{card.content || 'ADMIT ONE · GENERAL ACCESS'}
|
||||
</div>
|
||||
{card.date && (
|
||||
<div className="text-[10px] text-amber-900 mt-1.5 font-bold">
|
||||
{card.date}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Perforated barcode tear stub */}
|
||||
<div className="pt-2 border-t border-dashed border-amber-900/40 flex flex-col items-center">
|
||||
<div className="h-4 w-28 flex items-stretch gap-[1.5px] justify-center opacity-70">
|
||||
{[1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 3, 1, 2, 1, 3].map((w, i) => (
|
||||
<div key={i} className="bg-neutral-900" style={{ width: `${w}px` }} />
|
||||
))}
|
||||
</div>
|
||||
<span className="text-[8px] tracking-widest text-neutral-500 mt-0.5">
|
||||
★ NON-TRANSFERABLE ★
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user