Add Day 1 session notes and meeting link

This commit is contained in:
Neeldhara Misra 2026-07-16 11:13:03 +05:30
parent c4bb7512d5
commit 64abe3451a
4 changed files with 423 additions and 5 deletions

View file

@ -1,5 +1,6 @@
--- ---
import type { ScheduleDay } from "../data/events"; import type { ScheduleDay } from "../data/events";
import SessionNotesModal from "./SessionNotesModal.astro";
type Props = { type Props = {
schedule: ScheduleDay[]; schedule: ScheduleDay[];
@ -52,7 +53,7 @@ const { schedule, asTabs = false } = Astro.props;
{day.moderator && <p>{day.moderator}</p>} {day.moderator && <p>{day.moderator}</p>}
</div> </div>
<ol> <ol>
{day.items.map((item) => ( {day.items.map((item, itemIndex) => (
<li class:list={["schedule-item", item.kind && `schedule-item--${item.kind}`]}> <li class:list={["schedule-item", item.kind && `schedule-item--${item.kind}`]}>
<time>{item.time}</time> <time>{item.time}</time>
<div> <div>
@ -65,6 +66,9 @@ const { schedule, asTabs = false } = Astro.props;
{item.links.map((link) => <a href={link.href}>{link.label}</a>)} {item.links.map((link) => <a href={link.href}>{link.label}</a>)}
</div> </div>
)} )}
{item.notes && (
<SessionNotesModal id={`session-notes-${index}-${itemIndex}`} notes={item.notes} />
)}
</div> </div>
</li> </li>
))} ))}
@ -75,7 +79,7 @@ const { schedule, asTabs = false } = Astro.props;
</div> </div>
) : ( ) : (
<div class="schedule-grid"> <div class="schedule-grid">
{schedule.map((day) => ( {schedule.map((day, dayIndex) => (
<article class="schedule-day"> <article class="schedule-day">
<div class="schedule-day__head"> <div class="schedule-day__head">
<h3>{day.label}</h3> <h3>{day.label}</h3>
@ -83,7 +87,7 @@ const { schedule, asTabs = false } = Astro.props;
{day.moderator && <p>{day.moderator}</p>} {day.moderator && <p>{day.moderator}</p>}
</div> </div>
<ol> <ol>
{day.items.map((item) => ( {day.items.map((item, itemIndex) => (
<li class:list={["schedule-item", item.kind && `schedule-item--${item.kind}`]}> <li class:list={["schedule-item", item.kind && `schedule-item--${item.kind}`]}>
<time>{item.time}</time> <time>{item.time}</time>
<div> <div>
@ -96,6 +100,9 @@ const { schedule, asTabs = false } = Astro.props;
{item.links.map((link) => <a href={link.href}>{link.label}</a>)} {item.links.map((link) => <a href={link.href}>{link.label}</a>)}
</div> </div>
)} )}
{item.notes && (
<SessionNotesModal id={`session-notes-${dayIndex}-${itemIndex}`} notes={item.notes} />
)}
</div> </div>
</li> </li>
))} ))}

View file

@ -0,0 +1,96 @@
---
import type { SessionNotes } from "../data/events";
type Props = {
id: string;
notes: SessionNotes;
};
const { id, notes } = Astro.props;
---
<button
class="session-notes-trigger"
type="button"
aria-haspopup="dialog"
data-session-notes-open={id}
>
View session notes
</button>
<dialog class="session-notes-dialog" id={id} aria-labelledby={`${id}-title`}>
<div class="session-notes-dialog__surface">
<header class="session-notes-dialog__header">
<div>
<p class="eyebrow">Day 1 · Session 1</p>
<h2 id={`${id}-title`}>{notes.title}</h2>
</div>
<button
class="session-notes-dialog__close"
type="button"
aria-label="Close session notes"
data-session-notes-close
>
<span aria-hidden="true">×</span>
</button>
</header>
<div class="session-notes-dialog__body">
{notes.sections.map((section) => (
<section>
<h3>{section.heading}</h3>
<ul>
{section.bullets.map((bullet) => (
<li>
{bullet.detail ? <strong>{bullet.text}</strong> : bullet.text}
{bullet.detail && <p>{bullet.detail}</p>}
{bullet.children && (
<ul>
{bullet.children.map((child) => <li>{child}</li>)}
</ul>
)}
</li>
))}
</ul>
</section>
))}
</div>
</div>
</dialog>
<script>
const activeTriggers = new WeakMap<HTMLDialogElement, HTMLElement>();
document.querySelectorAll<HTMLElement>("[data-session-notes-open]").forEach((trigger) => {
if (trigger.dataset.sessionNotesReady === "true") return;
trigger.dataset.sessionNotesReady = "true";
trigger.addEventListener("click", () => {
const dialogId = trigger.getAttribute("data-session-notes-open");
const dialog = dialogId ? document.getElementById(dialogId) : null;
if (!(dialog instanceof HTMLDialogElement)) return;
activeTriggers.set(dialog, trigger);
dialog.showModal();
dialog.querySelector<HTMLElement>("[data-session-notes-close]")?.focus();
});
});
document.querySelectorAll<HTMLDialogElement>(".session-notes-dialog").forEach((dialog) => {
if (dialog.dataset.sessionNotesReady === "true") return;
dialog.dataset.sessionNotesReady = "true";
dialog.querySelector<HTMLElement>("[data-session-notes-close]")?.addEventListener("click", () => {
dialog.close();
});
dialog.addEventListener("click", (event) => {
if (event.target === dialog) dialog.close();
});
dialog.addEventListener("close", () => {
activeTriggers.get(dialog)?.focus();
activeTriggers.delete(dialog);
});
});
</script>

View file

@ -10,6 +10,19 @@ export type ScheduleItem = {
kind?: "session" | "break" | "keynote" | "social" | "note"; kind?: "session" | "break" | "keynote" | "social" | "note";
detail?: string; detail?: string;
links?: { label: string; href: string }[]; links?: { label: string; href: string }[];
notes?: SessionNotes;
};
export type SessionNotes = {
title: string;
sections: {
heading: string;
bullets: {
text: string;
children?: string[];
detail?: string;
}[];
}[];
}; };
export type ScheduleDay = { export type ScheduleDay = {
@ -389,10 +402,180 @@ export const events: Event[] = [
date: "July 16, 2026", date: "July 16, 2026",
items: [ items: [
{ time: "09:30", title: "Settle in and configure screen sharing on the 'smart' TV 😬", kind: "note" }, { time: "09:30", title: "Settle in and configure screen sharing on the 'smart' TV 😬", kind: "note" },
{ time: "10:00", title: "Opening remarks", kind: "session" }, {
time: "10:00",
title: "Opening remarks",
kind: "session",
notes: {
title: "Session 1 notes",
sections: [
{
heading: "Attendees and Context",
bullets: [
{
text: "Four-day working session to develop NCERT computer science textbooks for grades 11 and 12",
},
{
text: "Team: mix of IIT faculty, school teachers, industry practitioners, and curriculum developers",
},
],
},
{
heading: "Curriculum Scope and Design Principles",
bullets: [
{
text: "Core question: what should a student know after two years of CS, independent of market/job value?",
},
{
text: "70/30 split agreed after comparing CS and AI curricula:",
children: [
"70% core CS concepts: programming principles, complexity, basic data structures, algorithms",
"30% new and contemporary topics",
],
},
{
text: "Computational thinking identified as a major emphasis that was lost in recent drafts; needs restoration",
},
{
text: "Two flavors of computational thinking to balance:",
children: [
"Greek/algorithmic: abstract a real-world problem into a mathematical model, solve with defined steps",
"Data-centric (Indian tradition): observe data, find patterns, iterate toward conclusions (underpins AI/ML)",
],
},
{
text: "Procedural and data-centric approaches are not mutually exclusive; both need representation",
},
],
},
{
heading: "Programming Pedagogy: The Core Debate",
bullets: [
{
text: "Target audience is highly heterogeneous: some students arrive with coding experience, many have none",
},
{
text: "Current failure mode: students memorize code for exams rather than understanding it",
},
{
text: "Root cause: syntax and cryptic compiler errors overwhelm beginners before they can think about problems",
},
{
text: "Desired sequence: problem articulation → solution design → only then, code implementation",
},
{
text: "Key principle: thinking must precede execution, not the reverse",
},
],
},
{
heading: "Block-Based Editing as a Bridge",
bullets: [
{
text: "Block-based visual programming (Scratch/Snap) proposed as the bridge between thinking and writing code",
},
{
text: "Rationale: removes syntax friction so students can focus on problem-solving logic",
},
{
text: "Precedent: Harvard CS50 opens with Scratch for one week at undergraduate level",
},
{
text: "Snap (Berkeley) preferred over Scratch: more features, closer to real language constructs, smoother transition to Python",
},
{
text: "Sriram and Viraj (now resigned) were strong advocates; their exit has left the decision somewhat fluid",
},
{
text: "Risk flagged: teachers and students may perceive block-based coding as “dumbing down”",
children: [
"Reframe needed: this is not easier programming, it is a different entry point for thinking",
"The chapter itself must convey this through its structure, not through two pages of theory",
],
},
],
},
{
heading: "Snap vs. Python: Current State",
bullets: [
{
text: "Decision on Snap vs. Python-first is still open following departure of key advocates",
},
{
text: "Next step: review the programming learning path (how students begin, grow, and deepen)",
},
{
text: "Anup joining to share flowchart experience as one alternative/complement to block-based editing",
},
{
text: "Other options on the table: pseudocode, English-language description, flowcharts, unplugged activities",
},
{
text: "Goal: whichever path is chosen, more students should choose CS by interest, not just salary prospects",
},
],
},
{
heading: "Writing the Textbook: Key Challenges",
bullets: [
{
text: "Chapter structure must implicitly convey pedagogical motivation, not state it explicitly",
},
{
text: "Start each lesson with a problem; find a solution; then introduce the tool or syntax",
},
{
text: "Avoid leading with interface instructions (e.g., “here is where to find the block in Scratch”)",
},
{
text: "Examples should move beyond classical formula-substitution problems toward open-ended, data-rich scenarios",
children: [
"Concern raised: students coming from 10th standard may struggle with ill-defined, multi-solution problems",
"Counterpoint: this can be scaffolded carefully; school teachers input is essential here",
],
},
{
text: "Collective wisdom of the group is the intended mechanism; no single person covers all aspects",
},
],
},
{
heading: "Next Steps",
bullets: [
{
text: "Reach out to Berkeley Snap team for support",
detail: "Explore whether they can provide resources or collaboration for curriculum integration.",
},
{
text: "Anup to present flowchart experience to the group",
detail: "Share findings on pitfalls and benefits to inform the decision on flowchart-based exposition.",
},
{
text: "Finalize programming learning path decision (Snap, Python, or hybrid)",
detail: "Review options as a group over the four days; resolve what was left fluid after Sriram and Biraj's departure.",
},
{
text: "Develop school-level examples for the data-centric computational thinking strand",
detail: "School teachers to contribute examples that are accessible to students coming from 10th standard.",
},
],
},
],
},
},
{ time: "10:30", title: "Review and recap of what we have so far", kind: "session" }, { time: "10:30", title: "Review and recap of what we have so far", kind: "session" },
{ time: "11:00", title: "Coffee at Nescafe", kind: "break" }, { time: "11:00", title: "Coffee at Nescafe", kind: "break" },
{ time: "11:30", title: "Anup's presentation on flowcharts", kind: "session" }, {
time: "11:30",
title: "Anup's presentation on flowcharts",
kind: "session",
links: [
{
label: "Join Zoom",
href: "https://events.neeldhara.com/2026/ncert/",
},
],
},
{ time: "12:30", title: "Discussion: finalizing the plan ahead", kind: "session" }, { time: "12:30", title: "Discussion: finalizing the plan ahead", kind: "session" },
{ time: "13:00", title: "Lunch back at the guest house", kind: "break" }, { time: "13:00", title: "Lunch back at the guest house", kind: "break" },
{ time: "14:30", title: "Small-group discussions / breakout rooms", kind: "session" }, { time: "14:30", title: "Small-group discussions / breakout rooms", kind: "session" },

View file

@ -1377,6 +1377,121 @@ button.event-badge::before {
margin-top: 0.65rem; margin-top: 0.65rem;
} }
.session-notes-trigger {
min-height: 44px;
margin-top: 0.65rem;
border: var(--border-hairline) solid color-mix(in oklch, var(--primary) 30%, var(--border));
border-radius: 999px;
background: var(--card);
color: var(--primary);
cursor: pointer;
font: inherit;
font-size: 0.9rem;
font-weight: 700;
padding: 0.45rem 0.85rem;
}
.session-notes-dialog {
width: min(760px, calc(100% - 2rem));
max-height: min(88dvh, 900px);
margin: auto;
overflow: hidden;
border: 0;
border-radius: 12px;
background: var(--card);
color: var(--foreground);
padding: 0;
box-shadow: 0 24px 80px rgba(20, 29, 25, 0.24);
}
.session-notes-dialog::backdrop {
background: rgba(24, 31, 27, 0.62);
}
.session-notes-dialog__surface {
display: grid;
max-height: min(88dvh, 900px);
grid-template-rows: auto minmax(0, 1fr);
}
.session-notes-dialog__header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1rem;
border-bottom: var(--border-hairline) solid var(--border);
background: color-mix(in oklch, var(--primary) 8%, white);
padding: 1.2rem 1.25rem;
}
.session-notes-dialog__header > div {
display: grid;
gap: 0.25rem;
}
.session-notes-dialog__header h2 {
font-size: 1.65rem;
}
.session-notes-dialog__close {
display: inline-grid;
width: 44px;
min-width: 44px;
height: 44px;
place-items: center;
border: var(--border-hairline) solid var(--border);
border-radius: 999px;
background: var(--card);
color: var(--foreground);
cursor: pointer;
font: inherit;
font-size: 1.65rem;
line-height: 1;
}
.session-notes-dialog__body {
display: grid;
gap: 1.6rem;
overflow-y: auto;
overscroll-behavior: contain;
padding: 1.25rem 1.4rem 1.6rem;
}
.session-notes-dialog__body section {
display: grid;
gap: 0.7rem;
}
.session-notes-dialog__body h3 {
font-size: 1.18rem;
}
.session-notes-dialog__body ul {
display: grid;
gap: 0.5rem;
padding-left: 1.25rem;
}
.session-notes-dialog__body ul ul {
gap: 0.35rem;
padding-top: 0.35rem;
}
.session-notes-dialog__body li,
.session-notes-dialog__body p {
color: color-mix(in oklch, var(--foreground) 84%, white);
font-size: 0.96rem;
line-height: 1.55;
}
.session-notes-dialog__body li::marker {
color: var(--primary);
}
.session-notes-dialog__body li > p {
margin-top: 0.2rem;
}
.people-list { .people-list {
column-count: 2; column-count: 2;
column-gap: 2rem; column-gap: 2rem;
@ -2301,6 +2416,23 @@ button.event-badge::before {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.session-notes-dialog {
width: calc(100% - 1rem);
max-height: 92dvh;
}
.session-notes-dialog__surface {
max-height: 92dvh;
}
.session-notes-dialog__header {
padding: 1rem;
}
.session-notes-dialog__body {
padding: 1rem 1.1rem 1.35rem;
}
.gallery-grid { .gallery-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }