feat: editor improvements and architectural grid prototype
Multiple feature additions and improvements across the application: - NextGen Editor: drag handles, smart paste, block actions - Structured views: Kanban and table layouts for notes - Architectural Grid: new brainstorming/agent interface prototype - Flashcards: SM-2 revision algorithm with AI generation - MCP server: robustness improvements - Graph/PDF chat: fix click propagation and copy behavior - Various UI/UX enhancements and bug fixes Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
169
architectural-grid1/src/components/TemporalView.tsx
Normal file
169
architectural-grid1/src/components/TemporalView.tsx
Normal file
@@ -0,0 +1,169 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import {
|
||||
Clock,
|
||||
Calendar,
|
||||
TrendingUp,
|
||||
Zap,
|
||||
History,
|
||||
ArrowRight,
|
||||
Sparkles,
|
||||
PieChart
|
||||
} from 'lucide-react';
|
||||
import { Note, NoteAccessLog, NotePrediction } from '../types';
|
||||
import { predictNextAccess, detectAccessCycle } from '../services/temporalService';
|
||||
|
||||
interface TemporalViewProps {
|
||||
notes: Note[];
|
||||
accessLogs: NoteAccessLog[];
|
||||
onNoteSelect: (id: string) => void;
|
||||
}
|
||||
|
||||
export const TemporalView: React.FC<TemporalViewProps> = ({ notes, accessLogs, onNoteSelect }) => {
|
||||
const predictions = useMemo(() => {
|
||||
return notes
|
||||
.map(note => {
|
||||
const noteLogs = accessLogs.filter(l => l.noteId === note.id);
|
||||
const prediction = predictNextAccess(note, noteLogs);
|
||||
return { note, prediction };
|
||||
})
|
||||
.filter(p => p.prediction !== null) as { note: Note; prediction: NotePrediction }[];
|
||||
}, [notes, accessLogs]);
|
||||
|
||||
const cyclicalNotes = useMemo(() => {
|
||||
return notes
|
||||
.map(note => {
|
||||
const noteLogs = accessLogs.filter(l => l.noteId === note.id);
|
||||
const cycle = detectAccessCycle(noteLogs);
|
||||
return { note, cycle };
|
||||
})
|
||||
.filter(p => p.cycle !== null) as { note: Note; cycle: number }[];
|
||||
}, [notes, accessLogs]);
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col bg-paper dark:bg-[#0A0A0A] overflow-hidden">
|
||||
<div className="p-8 border-b border-border/40 backdrop-blur-xl bg-white/40 dark:bg-black/20 z-10">
|
||||
<div className="flex items-center gap-3 mb-1">
|
||||
<div className="w-8 h-8 rounded-lg bg-rose-500/10 flex items-center justify-center text-rose-500">
|
||||
<Clock size={18} />
|
||||
</div>
|
||||
<h1 className="text-2xl font-serif font-medium text-ink dark:text-dark-ink">Temporal Forecast</h1>
|
||||
</div>
|
||||
<p className="text-[11px] text-concrete tracking-[0.2em] uppercase font-bold">Predicting the recurrence of insight</p>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto custom-scrollbar p-8">
|
||||
<div className="max-w-5xl mx-auto space-y-12">
|
||||
|
||||
{/* Daily Briefing / Predictions */}
|
||||
<section>
|
||||
<div className="flex items-center gap-2 mb-6">
|
||||
<Sparkles size={16} className="text-rose-400" />
|
||||
<h3 className="text-sm font-bold uppercase tracking-widest text-ink dark:text-dark-ink">Intelligence Briefing</h3>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{predictions.map(({ note, prediction }) => (
|
||||
<motion.div
|
||||
key={note.id}
|
||||
whileHover={{ y: -4 }}
|
||||
onClick={() => onNoteSelect(note.id)}
|
||||
className="p-6 rounded-2xl bg-white dark:bg-white/5 border border-border/60 hover:border-rose-400/40 transition-all cursor-pointer shadow-sm relative overflow-hidden group"
|
||||
>
|
||||
<div className="absolute top-0 right-0 p-3">
|
||||
<TrendingUp size={14} className="text-rose-400 opacity-40 group-hover:opacity-100 transition-opacity" />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<span className="px-2 py-1 bg-rose-500/10 text-rose-500 text-[10px] font-bold rounded-full uppercase tracking-widest">
|
||||
Coming Up
|
||||
</span>
|
||||
<span className="text-[10px] text-concrete font-medium">
|
||||
{new Date(prediction.predictedRelevanceDate).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h4 className="text-lg font-serif font-medium text-ink dark:text-dark-ink mb-2 group-hover:text-rose-500 transition-colors uppercase tracking-tight">{note.title}</h4>
|
||||
<p className="text-xs text-muted-ink leading-relaxed mb-6 italic">
|
||||
"{prediction.reason}"
|
||||
</p>
|
||||
|
||||
<div className="pt-4 border-t border-border/40 flex items-center justify-between">
|
||||
<span className="text-[10px] font-bold text-concrete uppercase tracking-widest">Confidence {Math.round(prediction.confidence * 100)}%</span>
|
||||
<ArrowRight size={14} className="text-concrete group-hover:text-ink" />
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
{predictions.length === 0 && (
|
||||
<div className="col-span-full p-12 text-center bg-paper dark:bg-white/5 border-2 border-dashed border-border rounded-3xl">
|
||||
<Calendar size={40} className="mx-auto text-concrete/40 mb-4" />
|
||||
<h5 className="text-ink dark:text-dark-ink font-medium mb-1">No upcoming predictions</h5>
|
||||
<p className="text-xs text-concrete">The system needs more usage data to find cyclical patterns in your research.</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Cyclical Patterns */}
|
||||
<section>
|
||||
<div className="flex items-center gap-2 mb-6">
|
||||
<History size={16} className="text-indigo-400" />
|
||||
<h3 className="text-sm font-bold uppercase tracking-widest text-ink dark:text-dark-ink">Detected Cycles</h3>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
{cyclicalNotes.map(({ note, cycle }) => (
|
||||
<div key={note.id} className="flex items-center gap-4 p-4 rounded-xl bg-slate-50 dark:bg-white/5 border border-border/40">
|
||||
<div className="w-12 h-12 rounded-xl bg-white dark:bg-black/20 border border-border flex items-center justify-center flex-col shadow-sm">
|
||||
<span className="text-xs font-bold text-ink dark:text-dark-ink">{Math.round(cycle)}</span>
|
||||
<span className="text-[8px] font-bold text-concrete uppercase">days</span>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h5 className="text-sm font-medium text-ink dark:text-dark-ink">{note.title}</h5>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-[10px] text-concrete">Recurring theme in your architectural process</span>
|
||||
<div className="h-1 w-24 bg-border/40 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-rose-400" style={{ width: '65%' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button onClick={() => onNoteSelect(note.id)} className="p-2 hover:bg-black/5 rounded-full">
|
||||
<ArrowRight size={16} className="text-concrete" />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Productivity Stats */}
|
||||
<section className="bg-ink dark:bg-white/5 rounded-3xl p-8 text-paper relative overflow-hidden">
|
||||
<div className="relative z-10 grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div>
|
||||
<h6 className="text-[10px] font-bold uppercase tracking-[0.2em] opacity-60 mb-2">Memory Strength</h6>
|
||||
<div className="text-4xl font-serif">84%</div>
|
||||
<p className="text-[10px] opacity-60 mt-2">Active connections in your semantic network</p>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="text-[10px] font-bold uppercase tracking-[0.2em] opacity-60 mb-2">Peak Cycle</h6>
|
||||
<div className="text-4xl font-serif">28 Days</div>
|
||||
<p className="text-[10px] opacity-60 mt-2">The rhythm of your creative output</p>
|
||||
</div>
|
||||
<div className="flex flex-col justify-center">
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<div className="w-2 h-2 rounded-full bg-rose-400"></div>
|
||||
<span className="text-xs font-medium">4 Notes resurfacing this week</span>
|
||||
</div>
|
||||
<button className="w-full py-2 bg-paper text-ink rounded-xl text-[10px] font-bold uppercase tracking-widest hover:scale-105 transition-transform">
|
||||
Build Morning Briefing
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute top-0 right-0 w-64 h-64 bg-rose-500/10 blur-[80px] rounded-full -mr-20 -mt-20"></div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user