diff --git a/src/data/datasetStory.js b/src/data/datasetStory.js
new file mode 100644
index 0000000..088e752
--- /dev/null
+++ b/src/data/datasetStory.js
@@ -0,0 +1,56 @@
+export const datasetScenes = [
+ {
+ scene: 1,
+ title: "The Everyday Mystery",
+ narrative: "Think about the lists you see every day: your phone's contact list, a weekly weather forecast, or a sports league table.",
+
+ },
+ {
+ scene: 2,
+ title: "Naming the Thing",
+ narrative: "When we take those lists and organize them neatly, they transform into a table.",
+
+ },
+ {
+ scene: 3,
+ title: "One Row, One Story",
+ narrative: "In a dataset, every horizontal row is a single, complete storyโlike one individual person, one specific day, or one single transaction.",
+
+ },
+ {
+ scene: 4,
+ title: "Many Shapes of Data",
+ narrative: "Datasets aren't just numbers and text. They can be collections of images, folders of audio files, or libraries of books.",
+
+ },
+ {
+ scene: 5,
+ title: "Where Data Comes From",
+ narrative: "Where do they come from? Everywhere. Weather sensors, online surveys, website clicks, and smartwatches all feed information into datasets.",
+
+ },
+ {
+ scene: 6,
+ title: "Clean vs. Messy",
+ narrative: "Before AI can use data, it has to be cleaned. Real-world data is often messyโfilled with missing values, typos, and duplicates.",
+
+ },
+ {
+ scene: 7,
+ title: "What You Can Do",
+ narrative: "Once you have a clean dataset, the possibilities branch out: you can visualize trends, analyze statistics, or train an AI model.",
+
+ },
+ {
+ scene: 8,
+ title: "A Dataset in the Wild",
+ narrative: "Let's look at a real example: a dataset of house prices. By looking at columns like 'Size' and 'Bedrooms', we can predict 'Price'.",
+
+ },
+ {
+ scene: 9,
+ title: "The Core Definition",
+ narrative: "At its core, a dataset is simply a structured collection of related information used to help humansโand machinesโmake sense of the world.",
+
+ }
+];
diff --git a/src/data/datasetStoryboard.jsx b/src/data/datasetStoryboard.jsx
new file mode 100644
index 0000000..4094067
--- /dev/null
+++ b/src/data/datasetStoryboard.jsx
@@ -0,0 +1,55 @@
+// src/data/DatasetStoryboard.jsx
+
+import { useState } from "react";
+import { datasetScenes } from "./datasetStory";
+import DatasetVisualCues from "./datasetVisualCues";
+
+export default function DatasetStoryboard({ onClose }) {
+ const [currentSceneIdx, setCurrentSceneIdx] = useState(0);
+
+ return (
+
+ {/* Header */}
+
+
+ ๐๏ธ
+
What is a Dataset?
+
+
+ โ Close
+
+
+
+ {/* Visual Canvas Box */}
+
+
+ Scene {datasetScenes[currentSceneIdx].scene} of {datasetScenes.length}
+
+
{datasetScenes[currentSceneIdx].title}
+
+
+
+ {/* Narrative */}
+
+
{datasetScenes[currentSceneIdx].narrative}
+
+
+ {/* Navigation Footer */}
+
+
setCurrentSceneIdx(prev => prev - 1)} className="px-4 py-2 rounded-xl text-sm font-semibold bg-white border border-[rgba(13,13,13,0.1)] text-[var(--ink)] disabled:opacity-40">
+ โ Back
+
+
{Math.round(((currentSceneIdx + 1) / datasetScenes.length) * 100)}% Done
+ {currentSceneIdx < datasetScenes.length - 1 ? (
+
setCurrentSceneIdx(prev => prev + 1)} className="px-4 py-2 rounded-xl text-sm font-semibold bg-[var(--purple)] text-white">
+ Next โ
+
+ ) : (
+
+ Finish ๐
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/data/datasetVisualCues.jsx b/src/data/datasetVisualCues.jsx
new file mode 100644
index 0000000..69572f2
--- /dev/null
+++ b/src/data/datasetVisualCues.jsx
@@ -0,0 +1,108 @@
+import React from 'react';
+
+export default function DatasetVisualCues({ currentSceneIdx }) {
+ return (
+
+
+ {/* Scene 1: The Everyday Mystery */}
+ {currentSceneIdx === 0 && (
+
+
๐
Mon: โ๏ธ 24ยฐC
+
๐ Todo List
+
๐ Team Roster
+
+ )}
+
+ {/* Scene 2: Naming the Thing */}
+ {currentSceneIdx === 1 && (
+
+
Monday
+
Tuesday
+
Wednesday
+
35.8ยฐ C
+
36.2ยฐ C
+
35.9ยฐ C
+
+ )}
+
+ {/* Scene 3: One Row, One Story */}
+ {currentSceneIdx === 2 && (
+
+
ID: 101
+
Name: Alice
+
Age: 24
+
+ )}
+
+ {/* Scene 4: Many Shapes of Data */}
+ {currentSceneIdx === 3 && (
+
+
๐
+
๐ผ๏ธ
+
โซ
+
๐
+
+ )}
+
+ {/* Scene 5: Where Data Comes From */}
+ {currentSceneIdx === 4 && (
+
+ ๐ฐ๏ธ
+ ๐ฑ
+ ๐ฅ
+ ๐ป
+ โฑ๏ธ
+
+ )}
+
+ {/* Scene 6: Clean vs Messy */}
+ {currentSceneIdx === 5 && (
+
+
+ [NULL] undefined NY!!
+
+
๐งน
+
+ "New York"
+
+
+ )}
+
+ {/* Scene 7: What You Can Do */}
+ {currentSceneIdx === 6 && (
+
+
Dataset
+
+
+
๐ Charts
+
๐งฎ Math
+
๐ค Train AI
+
+
+ )}
+
+ {/* Scene 8: A Dataset in the Wild */}
+ {currentSceneIdx === 7 && (
+
+
+ sqft: 1200 beds: 2
+
+
+ Price Estimate:
+
+ โ Calculating...
+
+
+
+ )}
+
+ {/* Scene 9: Core Definition */}
+ {currentSceneIdx === 8 && (
+
+ ๐๏ธ
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/data/storyboardMapping.js b/src/data/storyboardMapping.js
new file mode 100644
index 0000000..9f9ee7a
--- /dev/null
+++ b/src/data/storyboardMapping.js
@@ -0,0 +1,6 @@
+// src/data/storyboardMapping.js
+import DatasetStoryboard from './datasetStoryboard';
+
+export const storyboardComponents = {
+ 6: DatasetStoryboard,
+};
\ No newline at end of file
diff --git a/src/data/storyboards.js b/src/data/storyboards.js
index a90e7ed..39fbee6 100644
--- a/src/data/storyboards.js
+++ b/src/data/storyboards.js
@@ -16,56 +16,61 @@
export const storyboards = [
{
id: 1,
- emoji: '๐ง ',
- title: 'What is Machine Learning?',
- description: 'How computers learn from examples instead of being programmed with rules.',
- difficulty: 'beginner',
- status: 'coming-soon',
- gradient: 'linear-gradient(135deg, var(--purple-dark), var(--purple))',
+ emoji: "๐ง ",
+ title: "What is Machine Learning?",
+ description:
+ "How computers learn from examples instead of being programmed with rules.",
+ difficulty: "beginner",
+ status: "coming-soon",
+ gradient: "linear-gradient(135deg, var(--purple-dark), var(--purple))",
},
{
id: 2,
- emoji: '๐ฎ',
- title: 'How do LLMs work?',
- description: 'The magic behind ChatGPT and other large language models, explained simply.',
- difficulty: 'intermediate',
- status: 'coming-soon',
- gradient: 'linear-gradient(135deg, var(--purple-dark), var(--purple-mid))',
+ emoji: "๐ฎ",
+ title: "How do LLMs work?",
+ description:
+ "The magic behind ChatGPT and other large language models, explained simply.",
+ difficulty: "intermediate",
+ status: "coming-soon",
+ gradient: "linear-gradient(135deg, var(--purple-dark), var(--purple-mid))",
},
{
id: 3,
- emoji: '๐',
- title: 'Classification vs Regression',
- description: 'Two fundamental ways ML models make predictions โ and when to use which.',
- difficulty: 'beginner',
- status: 'coming-soon',
- gradient: 'linear-gradient(135deg, var(--purple-dark), var(--purple))',
+ emoji: "๐",
+ title: "Classification vs Regression",
+ description:
+ "Two fundamental ways ML models make predictions โ and when to use which.",
+ difficulty: "beginner",
+ status: "coming-soon",
+ gradient: "linear-gradient(135deg, var(--purple-dark), var(--purple))",
},
{
id: 4,
- emoji: 'โก',
- title: 'What is a Neural Network?',
- description: 'The building blocks of modern AI โ inspired by the human brain.',
- difficulty: 'beginner',
- status: 'coming-soon',
- gradient: 'linear-gradient(135deg, var(--teal), var(--teal-light))',
+ emoji: "โก",
+ title: "What is a Neural Network?",
+ description:
+ "The building blocks of modern AI โ inspired by the human brain.",
+ difficulty: "beginner",
+ status: "coming-soon",
+ gradient: "linear-gradient(135deg, var(--teal), var(--teal-light))",
},
{
id: 5,
- emoji: '๐ฏ',
- title: 'What is Loss & Training?',
- description: 'How an AI model learns by making mistakes and correcting itself.',
- difficulty: 'intermediate',
- status: 'coming-soon',
- gradient: 'linear-gradient(135deg, var(--amber), var(--amber-light))',
+ emoji: "๐ฏ",
+ title: "What is Loss & Training?",
+ description:
+ "How an AI model learns by making mistakes and correcting itself.",
+ difficulty: "intermediate",
+ status: "coming-soon",
+ gradient: "linear-gradient(135deg, var(--amber), var(--amber-light))",
},
{
id: 6,
- emoji: '๐๏ธ',
- title: 'What is a Dataset?',
- description: 'Why data is the fuel of AI โ and what makes a good dataset.',
- difficulty: 'beginner',
- status: 'coming-soon',
- gradient: 'linear-gradient(135deg, var(--ink-soft), var(--purple))',
+ emoji: "๐๏ธ",
+ title: "What is a Dataset?",
+ description: "Why data is the fuel of AI โ and what makes a good dataset.",
+ difficulty: "beginner",
+ status: "available",
+ gradient: "linear-gradient(135deg, var(--ink-soft), var(--purple))",
},
-]
+];
diff --git a/src/pages/Concepts.jsx b/src/pages/Concepts.jsx
index c5b634c..f3c48a1 100644
--- a/src/pages/Concepts.jsx
+++ b/src/pages/Concepts.jsx
@@ -1,31 +1,47 @@
-import { useState } from 'react'
-import { Link } from 'react-router-dom'
-import { storyboards } from '../data/storyboards'
+import { useState } from "react";
+import { Link } from "react-router-dom";
+import { storyboards } from "../data/storyboards";
+import { storyboardComponents } from "../data/storyboardMapping"; // Dynamic map import
-const difficultyOptions = ['All', 'Beginner', 'Intermediate', 'Advanced']
+const difficultyOptions = ["All", "Beginner", "Intermediate", "Advanced"];
const difficultyStyles = {
- beginner: 'bg-[var(--purple-light)] text-[var(--purple)]',
- intermediate: 'bg-[var(--teal-light)] text-[var(--teal)]',
- advanced: 'bg-[var(--amber-light)] text-[var(--amber)]',
-}
+ beginner: "bg-[var(--purple-light)] text-[var(--purple)]",
+ intermediate: "bg-[var(--teal-light)] text-[var(--teal)]",
+ advanced: "bg-[var(--amber-light)] text-[var(--amber)]",
+};
export default function Concepts() {
- const [filter, setFilter] = useState('All')
- const filteredConcepts = filter === 'All'
- ? storyboards
- : storyboards.filter((item) => item.difficulty.toLowerCase() === filter.toLowerCase())
+ const [filter, setFilter] = useState("All");
+
+ // Stores the mapped component definition to display inside the modal window context
+ const [ActiveStoryboardComponent, setActiveStoryboardComponent] =
+ useState(null);
+
+ const filteredConcepts =
+ filter === "All"
+ ? storyboards
+ : storyboards.filter(
+ (item) => item.difficulty.toLowerCase() === filter.toLowerCase(),
+ );
return (
-
+
AI Concepts
-
+
Explore every concept in one place
-
- Browse the full HerStack concept library with beginner-friendly explainers and visual storyboards.
+
+ Browse the full HerStack concept library with beginner-friendly
+ explainers and visual storyboards.
@@ -36,8 +52,8 @@ export default function Concepts() {
onClick={() => setFilter(option)}
className={`rounded-full border px-4 py-2 text-sm font-semibold transition duration-200 ${
filter === option
- ? 'border-transparent bg-[var(--purple)] text-white shadow-lg'
- : 'border-[rgba(13,13,13,0.08)] bg-white text-[var(--ink)] hover:border-[var(--purple)]'
+ ? "border-transparent bg-[var(--purple)] text-white shadow-lg"
+ : "border-[rgba(13,13,13,0.08)] bg-white text-[var(--ink)] hover:border-[var(--purple)]"
}`}
>
{option}
@@ -48,45 +64,88 @@ export default function Concepts() {
- These concepts are the building blocks of AI literacy. Each card includes a visual explainer, a short summary, and difficulty labeling to help learners choose the right next step.
+ These concepts are the building blocks of AI literacy. Each card
+ includes a visual explainer, a short summary, and difficulty
+ labeling to help learners choose the right next step.
-
+
โ Back to homepage
+ {/* Concept Cards Grid */}
- {filteredConcepts.map((concept) => (
-
- {
+ const TargetComponent = storyboardComponents[concept.id];
+ const isClickable =
+ TargetComponent &&
+ (concept.status === "in-progress" ||
+ concept.status === "available");
+
+ return (
+
{
+ if (isClickable) {
+ setActiveStoryboardComponent(() => TargetComponent);
+ }
+ }}
+ className={`rounded-3xl overflow-hidden border border-[rgba(13,13,13,0.08)] bg-white shadow-sm transition-transform duration-200 ${
+ isClickable
+ ? "cursor-pointer hover:-translate-y-1 hover:border-[var(--purple)] hover:shadow-md"
+ : ""
+ }`}
>
- {concept.emoji}
-
-
-
-
- {concept.status.replace('-', ' ')}
-
-
- {concept.difficulty}
-
+
+ {concept.emoji}
+
+
+
+
+ {concept.status.replace("-", " ")}
+
+
+ {concept.difficulty}
+
+
+
+ {concept.title}
+
+
+ {concept.description}
+
-
- {concept.title}
-
-
- {concept.description}
-
-
-
- ))}
+
+ );
+ })}
+
+ {/* --- FLOATING MODAL TARGET BOX OVERLAY --- */}
+ {ActiveStoryboardComponent && (
+
+
+
+
setActiveStoryboardComponent(null)}
+ />
+
+
+ )}
- )
+ );
}