243 lines
8.5 KiB
TypeScript
243 lines
8.5 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { notFound } from "next/navigation";
|
|
import { getPatternTutorial } from "@/lib/api";
|
|
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
|
|
import { CodeBlock } from "@/components/ui/code-block";
|
|
import { Markdown } from "@/components/ui/markdown";
|
|
import { Callout } from "@/components/ui/callout";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import {
|
|
CommonMistakesList,
|
|
LearningProgression,
|
|
PatternVariations,
|
|
RecognitionSignals,
|
|
RelatedPatterns,
|
|
} from "@/components/patterns";
|
|
import { PatternVisualization } from "@/components/visualization";
|
|
import { TwoPointersVisualization, PrefixSumVisualization, LinkedListVisualization, MonotonicStackVisualization, TreeTraversalVisualization, BFSVisualization, DFSVisualization, CoinChangeVisualization, BacktrackingVisualization, HeapVisualization } from "@/components/visualizations-new";
|
|
import { twoSumAlgorithm } from "@/content/algorithms/two-sum";
|
|
import { slidingWindowAlgorithm } from "@/content/algorithms/sliding-window";
|
|
import { binarySearchAlgorithm } from "@/content/algorithms/binary-search";
|
|
import { prefixSumAlgorithm } from "@/content/algorithms/prefix-sum";
|
|
import { fastSlowPointersAlgorithm } from "@/content/algorithms/fast-slow-pointers";
|
|
import { linkedListReversalAlgorithm } from "@/content/algorithms/linkedlist-reversal";
|
|
import { monotonicStackAlgorithm } from "@/content/algorithms/monotonic-stack";
|
|
import { treeTraversalAlgorithm } from "@/content/algorithms/tree-traversal";
|
|
import { bfsAlgorithm } from "@/content/algorithms/bfs";
|
|
import { dfsAlgorithm } from "@/content/algorithms/dfs";
|
|
import { coinChangeAlgorithm } from "@/content/algorithms/coin-change";
|
|
import { subsetsAlgorithm } from "@/content/algorithms/subsets";
|
|
import { kthLargestAlgorithm } from "@/content/algorithms/kth-largest";
|
|
|
|
interface PageProps {
|
|
params: Promise<{ slug: string }>;
|
|
}
|
|
|
|
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
|
const { slug } = await params;
|
|
|
|
try {
|
|
const pattern = await getPatternTutorial(slug);
|
|
const description =
|
|
pattern.description ||
|
|
`Learn the ${pattern.name} pattern with ${pattern.question_count} practice problems.`;
|
|
|
|
return {
|
|
title: `${pattern.name} Pattern`,
|
|
description,
|
|
openGraph: {
|
|
title: `${pattern.name} Pattern | CodeTutor`,
|
|
description,
|
|
type: "article",
|
|
},
|
|
};
|
|
} catch {
|
|
return {
|
|
title: "Pattern Not Found",
|
|
};
|
|
}
|
|
}
|
|
|
|
export default async function PatternDetailPage({ params }: PageProps) {
|
|
const { slug } = await params;
|
|
|
|
let pattern;
|
|
try {
|
|
pattern = await getPatternTutorial(slug);
|
|
} catch {
|
|
notFound();
|
|
}
|
|
|
|
const difficultyLabels = ["Beginner", "Easy", "Intermediate", "Advanced", "Expert"];
|
|
const difficultyLabel = pattern.difficulty_level
|
|
? difficultyLabels[pattern.difficulty_level - 1] || "Intermediate"
|
|
: null;
|
|
|
|
return (
|
|
<div className="mx-auto space-y-8">
|
|
{/* Header */}
|
|
<div>
|
|
<div className="flex items-center gap-3 mb-2">
|
|
<h1 className="text-3xl font-bold">{pattern.name}</h1>
|
|
{difficultyLabel && (
|
|
<Badge variant="outline">{difficultyLabel}</Badge>
|
|
)}
|
|
</div>
|
|
<p className="text-[var(--muted-foreground)]">
|
|
{pattern.question_count} questions using this pattern
|
|
</p>
|
|
</div>
|
|
|
|
{/* Description */}
|
|
{pattern.description && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>What is {pattern.name}?</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Markdown>{pattern.description}</Markdown>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Metaphor - The relatable analogy */}
|
|
{pattern.metaphor && (
|
|
<Callout variant="insight" title="Think of it like this...">
|
|
<Markdown>{pattern.metaphor}</Markdown>
|
|
</Callout>
|
|
)}
|
|
|
|
{/* Core Concept - The "aha!" insight */}
|
|
{pattern.core_concept && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Core Concept</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Markdown>{pattern.core_concept}</Markdown>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Interactive Visualization */}
|
|
{slug === "two-pointers" ? (
|
|
<TwoPointersVisualization algorithm={twoSumAlgorithm} />
|
|
) : slug === "sliding-window" ? (
|
|
<TwoPointersVisualization algorithm={slidingWindowAlgorithm} />
|
|
) : slug === "binary-search" ? (
|
|
<TwoPointersVisualization algorithm={binarySearchAlgorithm} />
|
|
) : slug === "prefix-sum" ? (
|
|
<PrefixSumVisualization algorithm={prefixSumAlgorithm} />
|
|
) : slug === "fast-slow-pointers" ? (
|
|
<LinkedListVisualization algorithm={fastSlowPointersAlgorithm} />
|
|
) : slug === "linkedlist-reversal" ? (
|
|
<LinkedListVisualization algorithm={linkedListReversalAlgorithm} />
|
|
) : slug === "monotonic-stack" ? (
|
|
<MonotonicStackVisualization algorithm={monotonicStackAlgorithm} />
|
|
) : slug === "tree-traversal" ? (
|
|
<TreeTraversalVisualization algorithm={treeTraversalAlgorithm} />
|
|
) : slug === "bfs" ? (
|
|
<BFSVisualization algorithm={bfsAlgorithm} />
|
|
) : slug === "dfs" ? (
|
|
<DFSVisualization algorithm={dfsAlgorithm} />
|
|
) : slug === "dynamic-programming" ? (
|
|
<CoinChangeVisualization algorithm={coinChangeAlgorithm} />
|
|
) : slug === "backtracking" ? (
|
|
<BacktrackingVisualization algorithm={subsetsAlgorithm} />
|
|
) : slug === "heap" ? (
|
|
<HeapVisualization algorithm={kthLargestAlgorithm} />
|
|
) : pattern.visualization_examples && pattern.visualization_examples.length > 0 ? (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Interactive Visualization</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<PatternVisualization examples={pattern.visualization_examples} />
|
|
</CardContent>
|
|
</Card>
|
|
) : null}
|
|
|
|
{/* Static Visualization - ASCII diagram walkthrough (fallback) */}
|
|
{pattern.visualization && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Visual Walkthrough</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Markdown>{pattern.visualization}</Markdown>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Code Template */}
|
|
{pattern.code_template && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Code Template</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p className="text-sm text-[var(--muted-foreground)] mb-4">
|
|
Use this skeleton as a starting point for problems using this pattern:
|
|
</p>
|
|
<CodeBlock
|
|
code={pattern.code_template}
|
|
language="python"
|
|
label="Pattern code template"
|
|
/>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Recognition Signals */}
|
|
{pattern.recognition_signals && pattern.recognition_signals.length > 0 && (
|
|
<RecognitionSignals signals={pattern.recognition_signals} />
|
|
)}
|
|
|
|
{/* When to Use */}
|
|
{pattern.when_to_use && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>When to Use</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Markdown>{pattern.when_to_use}</Markdown>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Common Mistakes */}
|
|
{pattern.common_mistakes && pattern.common_mistakes.length > 0 && (
|
|
<CommonMistakesList mistakes={pattern.common_mistakes} />
|
|
)}
|
|
|
|
{/* Pattern Variations */}
|
|
{pattern.variations && pattern.variations.length > 0 && (
|
|
<PatternVariations variations={pattern.variations} />
|
|
)}
|
|
|
|
{/* Learning Progression */}
|
|
{pattern.learning_progression && (
|
|
<LearningProgression progression={pattern.learning_progression} />
|
|
)}
|
|
|
|
{/* Related Patterns */}
|
|
<div className="grid md:grid-cols-2 gap-6">
|
|
{pattern.prerequisite_patterns && pattern.prerequisite_patterns.length > 0 && (
|
|
<RelatedPatterns
|
|
title="Prerequisites"
|
|
description="Learn these patterns first:"
|
|
patterns={pattern.prerequisite_patterns}
|
|
/>
|
|
)}
|
|
{pattern.related_patterns && pattern.related_patterns.length > 0 && (
|
|
<RelatedPatterns
|
|
title="Related Patterns"
|
|
description="Explore similar techniques:"
|
|
patterns={pattern.related_patterns}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|