Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "Dev Server",
"runtimeExecutable": "/Users/andripurnomo/.volta/bin/pnpm",
"runtimeArgs": ["dev"],
"port": 5173
},
{
"name": "Preview (production build)",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["preview"],
"port": 4173
}
]
}
7 changes: 7 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
"recommended": true
}
},
"css": {
"parser": {
"allowWrongLineComments": false,
"cssModules": false,
"tailwindDirectives": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
Expand Down
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<title>Full-Stack Visualized</title>
</head>
<body>
Expand Down
84 changes: 44 additions & 40 deletions src/components/api-patterns/DecisionTreeDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export function DecisionTreeDemo() {
return (
<div className="space-y-6">
{/* Decision tree visualization */}
<div className="bg-zinc-900 border border-zinc-700 rounded-xl p-6 min-h-[400px] flex flex-col items-center justify-center">
<div className="bg-surface-primary border border-border-secondary rounded-xl p-6 min-h-[400px] flex flex-col items-center justify-center">
<AnimatePresence mode="wait">
{!finalResult ? (
<motion.div
Expand All @@ -150,11 +150,11 @@ export function DecisionTreeDemo() {
? "bg-green-400"
: isCurrent
? "bg-violet-400 animate-pulse"
: "bg-zinc-600"
: "bg-surface-tertiary"
}`}
/>
{idx < Object.keys(QUESTIONS).length - 1 && (
<div className="w-8 h-0.5 bg-zinc-700" />
<div className="w-8 h-0.5 bg-surface-tertiary" />
)}
</div>
);
Expand All @@ -163,7 +163,7 @@ export function DecisionTreeDemo() {

{/* Question */}
<div className="text-center mb-8">
<h3 className="text-2xl font-semibold text-white mb-2">
<h3 className="text-2xl font-semibold text-text-primary mb-2">
{question.text}
</h3>
</div>
Expand All @@ -173,14 +173,14 @@ export function DecisionTreeDemo() {
<button
type="button"
onClick={() => handleAnswer("yes")}
className="px-8 py-6 bg-green-500/10 hover:bg-green-500/20 border-2 border-green-500/40 hover:border-green-500/60 rounded-xl text-green-300 font-semibold text-lg transition-all"
className="px-8 py-6 bg-green-500/10 hover:bg-green-500/20 border-2 border-green-500/40 hover:border-green-500/60 rounded-xl text-accent-green font-semibold text-lg transition-all"
>
✓ Yes
</button>
<button
type="button"
onClick={() => handleAnswer("no")}
className="px-8 py-6 bg-rose-500/10 hover:bg-rose-500/20 border-2 border-rose-500/40 hover:border-rose-500/60 rounded-xl text-rose-300 font-semibold text-lg transition-all"
className="px-8 py-6 bg-rose-500/10 hover:bg-rose-500/20 border-2 border-rose-500/40 hover:border-rose-500/60 rounded-xl text-accent-rose font-semibold text-lg transition-all"
>
✗ No
</button>
Expand All @@ -196,62 +196,62 @@ export function DecisionTreeDemo() {
{/* Result */}
<div className="text-center mb-8">
<div className="text-6xl mb-4">{result?.icon}</div>
<h3 className="text-3xl font-bold text-white mb-2">
<h3 className="text-3xl font-bold text-text-primary mb-2">
{result?.technology}
</h3>
<p className="text-zinc-400">{result?.description}</p>
<p className="text-text-tertiary">{result?.description}</p>
</div>

{/* Architecture diagram */}
<div className="bg-zinc-800/50 rounded-xl p-6 mb-6">
<div className="bg-surface-secondary/50 rounded-xl p-6 mb-6">
<div className="flex items-center justify-center gap-8">
<div className="flex flex-col items-center">
<div className="w-16 h-16 bg-violet-500/20 border-2 border-violet-500/40 rounded-lg flex items-center justify-center text-2xl mb-2">
💻
</div>
<span className="text-xs text-zinc-500">Client</span>
<span className="text-xs text-text-muted">Client</span>
</div>

<div className="flex flex-col items-center gap-2">
{finalResult === "websocket" ? (
<>
<div className="flex items-center gap-2">
<span className="text-green-400">→</span>
<span className="text-accent-green-soft">→</span>
<div className="w-24 h-1 bg-green-400 rounded" />
<span className="text-green-400">→</span>
<span className="text-accent-green-soft">→</span>
</div>
<div className="flex items-center gap-2">
<span className="text-cyan-400">←</span>
<span className="text-accent-cyan-soft">←</span>
<div className="w-24 h-1 bg-cyan-400 rounded" />
<span className="text-cyan-400">←</span>
<span className="text-accent-cyan-soft">←</span>
</div>
<span className="text-xs text-zinc-500">
<span className="text-xs text-text-muted">
Bidirectional
</span>
</>
) : finalResult === "sse" ? (
<>
<div className="w-24 h-1 bg-zinc-700 rounded" />
<div className="w-24 h-1 bg-surface-tertiary rounded" />
<div className="flex items-center gap-2">
<span className="text-cyan-400">←</span>
<span className="text-accent-cyan-soft">←</span>
<div className="w-24 h-1 bg-cyan-400 rounded" />
<span className="text-cyan-400">←</span>
<span className="text-accent-cyan-soft">←</span>
</div>
<span className="text-xs text-zinc-500">
<span className="text-xs text-text-muted">
Server → Client
</span>
</>
) : (
<>
<div className="flex items-center gap-2">
<span className="text-amber-400">→</span>
<span className="text-accent-amber-soft">→</span>
<div className="w-24 h-1 bg-amber-400 rounded animate-pulse" />
</div>
<div className="flex items-center gap-2">
<span className="text-cyan-400">←</span>
<span className="text-accent-cyan-soft">←</span>
<div className="w-24 h-1 bg-cyan-400 rounded animate-pulse" />
</div>
<span className="text-xs text-zinc-500">
<span className="text-xs text-text-muted">
Periodic Requests
</span>
</>
Expand All @@ -262,14 +262,14 @@ export function DecisionTreeDemo() {
<div className="w-16 h-16 bg-cyan-500/20 border-2 border-cyan-500/40 rounded-lg flex items-center justify-center text-2xl mb-2">
🖥️
</div>
<span className="text-xs text-zinc-500">Server</span>
<span className="text-xs text-text-muted">Server</span>
</div>
</div>
</div>

{/* Use cases */}
<div className="mb-6">
<h4 className="text-sm font-semibold text-zinc-400 uppercase tracking-wider mb-3">
<h4 className="text-sm font-semibold text-text-tertiary uppercase tracking-wider mb-3">
Common Use Cases
</h4>
<div className="space-y-2">
Expand All @@ -279,9 +279,9 @@ export function DecisionTreeDemo() {
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: idx * 0.1 }}
className="flex items-center gap-2 text-sm text-zinc-300"
className="flex items-center gap-2 text-sm text-text-secondary"
>
<span className="text-green-400">•</span>
<span className="text-accent-green-soft">•</span>
<span>{useCase}</span>
</motion.div>
))}
Expand All @@ -291,7 +291,7 @@ export function DecisionTreeDemo() {
<button
type="button"
onClick={reset}
className="w-full py-3 bg-violet-600 hover:bg-violet-500 rounded-lg text-white font-semibold transition-colors"
className="w-full py-3 bg-violet-600 hover:bg-violet-500 rounded-lg text-text-primary font-semibold transition-colors"
>
↺ Start Over
</button>
Expand All @@ -307,7 +307,7 @@ export function DecisionTreeDemo() {
animate={{ opacity: 1, y: 0 }}
className="space-y-4"
>
<h4 className="text-sm font-semibold text-zinc-400 uppercase tracking-wider">
<h4 className="text-sm font-semibold text-text-tertiary uppercase tracking-wider">
Implementation Example
</h4>

Expand Down Expand Up @@ -408,29 +408,33 @@ app.get('/api/status', async (req, res) => {

{/* Decision summary */}
{!finalResult && (
<div className="bg-zinc-800/30 border border-zinc-700 rounded-lg p-5">
<h4 className="text-sm font-semibold text-white mb-3">Quick Guide</h4>
<div className="space-y-2 text-sm text-zinc-400">
<div className="bg-surface-secondary/30 border border-border-secondary rounded-lg p-5">
<h4 className="text-sm font-semibold text-text-primary mb-3">
Quick Guide
</h4>
<div className="space-y-2 text-sm text-text-tertiary">
<div className="flex gap-2">
<span className="text-green-400">⚡</span>
<span className="text-accent-green-soft">⚡</span>
<span>
<strong className="text-white">WebSocket:</strong> Chat, gaming,
collaborative tools, or any bidirectional real-time
<strong className="text-text-primary">WebSocket:</strong> Chat,
gaming, collaborative tools, or any bidirectional real-time
communication
</span>
</div>
<div className="flex gap-2">
<span className="text-cyan-400">📡</span>
<span className="text-accent-cyan-soft">📡</span>
<span>
<strong className="text-white">SSE:</strong> Notifications,
logs, dashboards - when server pushes updates to client only
<strong className="text-text-primary">SSE:</strong>{" "}
Notifications, logs, dashboards - when server pushes updates to
client only
</span>
</div>
<div className="flex gap-2">
<span className="text-amber-400">🔄</span>
<span className="text-accent-amber-soft">🔄</span>
<span>
<strong className="text-white">Polling:</strong> Background
sync, email checks - when updates are infrequent (&lt;1/min)
<strong className="text-text-primary">Polling:</strong>{" "}
Background sync, email checks - when updates are infrequent
(&lt;1/min)
</span>
</div>
</div>
Expand Down
Loading