163 lines
6.1 KiB
Svelte
163 lines
6.1 KiB
Svelte
<script lang="ts">
|
|
import Navbar from '$lib/components/Navbar.svelte';
|
|
import Footer from '$lib/components/Footer.svelte';
|
|
|
|
interface Notebook {
|
|
title: string;
|
|
description: string;
|
|
category: string;
|
|
colabUrl: string;
|
|
icon: string;
|
|
}
|
|
|
|
const notebooks: Notebook[] = [
|
|
{
|
|
title: 'Exploratory Data Analysis',
|
|
description: 'Exploratory data analysis using the Gapminder dataset. Learn data wrangling, visualization, and insights extraction.',
|
|
category: 'EDA',
|
|
colabUrl: 'https://colab.research.google.com/github/valuecurve/notebooks/blob/main/eda-gapminder.ipynb',
|
|
icon: '🌍'
|
|
},
|
|
{
|
|
title: 'Statistical Tests Practice',
|
|
description: 'Hands-on practice with t-tests, ANOVA, chi-square, and correlation analysis using real datasets.',
|
|
category: 'STATISTICS',
|
|
colabUrl: 'https://colab.research.google.com/github/valuecurve/notebooks/blob/main/statistical-tests.ipynb',
|
|
icon: '📊'
|
|
},
|
|
{
|
|
title: 'Linear Regression Deep Dive',
|
|
description: 'From simple to multiple regression. Understand assumptions, diagnostics, and interpretation.',
|
|
category: 'ML',
|
|
colabUrl: '#',
|
|
icon: '📈'
|
|
},
|
|
{
|
|
title: 'Classification Models',
|
|
description: 'Logistic regression, decision trees, and random forests. Compare model performance and interpret results.',
|
|
category: 'ML',
|
|
colabUrl: '#',
|
|
icon: '🎯'
|
|
}
|
|
];
|
|
|
|
let searchQuery = $state('');
|
|
let selectedCategory = $state('all');
|
|
|
|
const categories = ['all', 'EDA', 'STATISTICS', 'ML'];
|
|
|
|
const filteredNotebooks = $derived(
|
|
notebooks.filter(nb => {
|
|
const matchesSearch = nb.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
nb.description.toLowerCase().includes(searchQuery.toLowerCase());
|
|
const matchesCategory = selectedCategory === 'all' || nb.category === selectedCategory;
|
|
return matchesSearch && matchesCategory;
|
|
})
|
|
);
|
|
|
|
function getCategoryColor(cat: string): string {
|
|
switch (cat.toUpperCase()) {
|
|
case 'EDA':
|
|
return 'bg-teal-100 text-teal-700';
|
|
case 'STATISTICS':
|
|
return 'bg-blue-100 text-blue-700';
|
|
case 'ML':
|
|
return 'bg-orange-100 text-orange-700';
|
|
default:
|
|
return 'bg-gray-100 text-gray-700';
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>Notebooks | Build with AI</title>
|
|
<meta name="description" content="Interactive Jupyter notebooks for hands-on learning. Open directly in Google Colab." />
|
|
</svelte:head>
|
|
|
|
<div class="min-h-screen bg-gradient-to-b from-slate-50 to-white">
|
|
<Navbar />
|
|
|
|
<main class="pt-24 pb-16 px-6">
|
|
<div class="max-w-6xl mx-auto">
|
|
<!-- Header -->
|
|
<div class="text-center mb-12">
|
|
<h1 class="text-4xl font-bold text-gray-900 mb-4">Notebooks</h1>
|
|
<p class="text-gray-600 max-w-2xl mx-auto">
|
|
Interactive Jupyter notebooks for hands-on learning. Open directly in Google Colab - no setup required.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Search & Filters -->
|
|
<div class="flex flex-col sm:flex-row gap-4 mb-8">
|
|
<div class="flex-1">
|
|
<input
|
|
type="text"
|
|
placeholder="Search notebooks..."
|
|
bind:value={searchQuery}
|
|
class="w-full px-4 py-2.5 border border-gray-200 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 transition-all"
|
|
/>
|
|
</div>
|
|
<select
|
|
bind:value={selectedCategory}
|
|
class="px-4 py-2.5 border border-gray-200 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 bg-white"
|
|
>
|
|
<option value="all">All Categories</option>
|
|
{#each categories.filter(c => c !== 'all') as category}
|
|
<option value={category}>{category}</option>
|
|
{/each}
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Notebooks Grid -->
|
|
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
{#each filteredNotebooks as notebook}
|
|
{@const isAvailable = notebook.colabUrl !== '#'}
|
|
<div class="group block p-6 bg-white rounded-2xl border border-gray-100 {isAvailable ? 'card-hover' : 'opacity-75'}">
|
|
<div class="flex items-start justify-between mb-4">
|
|
<div class="w-12 h-12 rounded-xl {isAvailable ? 'bg-primary-50' : 'bg-gray-100'} flex items-center justify-center {isAvailable ? 'transition-transform group-hover:scale-110' : ''}">
|
|
<span class="text-2xl {isAvailable ? '' : 'grayscale'}">{notebook.icon}</span>
|
|
</div>
|
|
<span class="text-xs font-medium px-2 py-1 rounded-full {getCategoryColor(notebook.category)}">
|
|
{notebook.category}
|
|
</span>
|
|
</div>
|
|
|
|
<h3 class="text-lg font-semibold {isAvailable ? 'text-gray-900 group-hover:text-primary-600' : 'text-gray-400'} mb-2 transition-colors">
|
|
{notebook.title}
|
|
</h3>
|
|
|
|
<p class="{isAvailable ? 'text-gray-600' : 'text-gray-400'} text-sm leading-relaxed mb-4">
|
|
{notebook.description}
|
|
</p>
|
|
|
|
{#if isAvailable}
|
|
<a
|
|
href={notebook.colabUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="inline-flex items-center gap-2 px-4 py-2 bg-yellow-400 hover:bg-yellow-500 text-gray-900 rounded-lg text-sm font-medium transition-colors"
|
|
>
|
|
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M12 0C5.372 0 0 5.372 0 12s5.372 12 12 12 12-5.372 12-12S18.628 0 12 0zm0 2.4c5.302 0 9.6 4.298 9.6 9.6s-4.298 9.6-9.6 9.6S2.4 17.302 2.4 12 6.698 2.4 12 2.4z"/>
|
|
</svg>
|
|
Open in Colab
|
|
</a>
|
|
{:else}
|
|
<span class="inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-400 rounded-lg text-sm font-medium">
|
|
Coming Soon
|
|
</span>
|
|
{/if}
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
|
|
{#if filteredNotebooks.length === 0}
|
|
<div class="text-center py-12">
|
|
<p class="text-gray-500">No notebooks found matching your criteria.</p>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</main>
|
|
|
|
<Footer />
|
|
</div>
|