Add latest events and people refinements

This commit is contained in:
Neeldhara Misra 2026-06-03 14:28:53 +05:30
parent 49fb30cc53
commit 002b164db8
7 changed files with 231 additions and 83 deletions

View file

@ -34,51 +34,38 @@ function initials(name: string) {
.toUpperCase(); .toUpperCase();
} }
function ScholarImage({ scholar }: { scholar: ResearchScholar }) { function InitialsMark({ name }: { name: string }) {
const [failed, setFailed] = useState(false);
if (failed) {
return ( return (
<div className="bg-primary/10 text-primary grid h-full w-full place-items-center text-2xl font-semibold"> <div className="bg-primary/10 text-primary grid size-14 shrink-0 place-items-center rounded-lg text-lg font-semibold">
{initials(scholar.name)} {initials(name)}
</div> </div>
); );
} }
return (
<img
src={scholar.image}
alt={scholar.name}
className="h-full w-full object-cover"
loading="lazy"
referrerPolicy="no-referrer"
onError={() => setFailed(true)}
/>
);
}
function GalleryCard({ scholar }: { scholar: ResearchScholar }) { function GalleryCard({ scholar }: { scholar: ResearchScholar }) {
return ( return (
<Card className="overflow-hidden"> <Card className="flex gap-4 p-4">
<div className="aspect-[4/3] bg-muted"> <InitialsMark name={scholar.name} />
<ScholarImage scholar={scholar} /> <div className="min-w-0 flex-1">
</div> <div className="flex items-start justify-between gap-2">
<div className="p-4">
<div className="flex items-start justify-between gap-3">
<div className="min-w-0"> <div className="min-w-0">
<h3 className="truncate text-base font-semibold"> <h3 className="truncate text-sm font-semibold leading-snug">
{scholar.name} {scholar.name}
</h3> </h3>
<p className="text-muted-foreground mt-1 text-sm"> <p className="text-muted-foreground text-xs">
{PROGRAM_LABELS[scholar.program]} · Joined {scholar.joined} {PROGRAM_LABELS[scholar.program]}
</p>
<p className="text-muted-foreground mt-1 text-xs">
Joined {scholar.joined}
</p> </p>
</div> </div>
<a <a
href={`mailto:${scholar.email}`} href={`mailto:${scholar.email}`}
className="text-muted-foreground hover:text-secondary shrink-0 transition-colors" className="text-muted-foreground hover:text-secondary shrink-0 transition-colors"
aria-label={`Email ${scholar.name}`} aria-label={`Email ${scholar.name}`}
title="Email"
> >
<Mail className="size-4" /> <Mail className="size-3.5" />
</a> </a>
</div> </div>
</div> </div>
@ -89,11 +76,9 @@ function GalleryCard({ scholar }: { scholar: ResearchScholar }) {
function ListRow({ scholar }: { scholar: ResearchScholar }) { function ListRow({ scholar }: { scholar: ResearchScholar }) {
return ( return (
<article className="grid gap-3 border-b py-4 last:border-b-0 md:grid-cols-[1.5fr_1fr_8rem_2rem] md:items-center"> <article className="grid gap-3 border-b py-4 last:border-b-0 md:grid-cols-[1.5fr_1fr_8rem_2rem] md:items-center">
<div className="flex items-center gap-3"> <div className="flex min-w-0 items-center gap-3">
<div className="size-12 shrink-0 overflow-hidden rounded-lg bg-muted"> <InitialsMark name={scholar.name} />
<ScholarImage scholar={scholar} /> <h3 className="truncate text-sm font-semibold">{scholar.name}</h3>
</div>
<h3 className="font-medium">{scholar.name}</h3>
</div> </div>
<p className="text-muted-foreground text-sm">{scholar.program}</p> <p className="text-muted-foreground text-sm">{scholar.program}</p>
<p className="text-muted-foreground text-sm">Joined {scholar.joined}</p> <p className="text-muted-foreground text-sm">Joined {scholar.joined}</p>

View file

@ -17,6 +17,8 @@ export interface DepartmentEvent {
collaborators?: string; collaborators?: string;
description: string; description: string;
source: "CSE events.xlsx" | "CSE archive"; source: "CSE events.xlsx" | "CSE archive";
sourceLabel?: string;
sourceUrl?: string;
featured?: boolean; featured?: boolean;
} }
@ -66,6 +68,22 @@ export const departmentEvents: DepartmentEvent[] = [
source: "CSE events.xlsx", source: "CSE events.xlsx",
featured: true, featured: true,
}, },
{
id: "history-of-science-engineering-india-2026",
title: "Workshop on Doing History of Science and Engineering in India",
category: "workshop",
year: 2026,
displayDate: "23-24 Feb 2026",
startDate: "2026-02-23",
endDate: "2026-02-24",
organizer: "HSS IITGN and History of Mathematics in India (HoMI)",
collaborators: "Neeldhara Misra",
description:
"A workshop on doing history of science and engineering in India from a social-history perspective.",
source: "CSE archive",
sourceLabel: "Event website",
sourceUrl: "https://history-of-science-2026.netlify.app/",
},
{ {
id: "modern-80211-wlans-2025", id: "modern-80211-wlans-2025",
title: "Certificate Course on Modern 802.11 WLANs", title: "Certificate Course on Modern 802.11 WLANs",

View file

@ -7,5 +7,5 @@ import DefaultLayout from "@/layouts/DefaultLayout.astro";
title="Courses" title="Courses"
description="Course catalogue for CSE at IIT Gandhinagar" description="Course catalogue for CSE at IIT Gandhinagar"
> >
<CourseCatalog client:only="react" /> <CourseCatalog client:load />
</DefaultLayout> </DefaultLayout>

View file

@ -1,6 +1,15 @@
--- ---
import { POSTDOCS } from '@/data/postdocs'; import { POSTDOCS } from '@/data/postdocs';
import DefaultLayout from '@/layouts/DefaultLayout.astro'; import DefaultLayout from '@/layouts/DefaultLayout.astro';
const initials = (name: string) =>
name
.replace(/^Dr\.\s+/i, '')
.split(' ')
.map((part) => part[0])
.join('')
.slice(0, 2)
.toUpperCase();
--- ---
<DefaultLayout title="Post-Docs" description="Postdoctoral researchers and fellows."> <DefaultLayout title="Post-Docs" description="Postdoctoral researchers and fellows.">
@ -18,20 +27,25 @@ import DefaultLayout from '@/layouts/DefaultLayout.astro';
<div class="container"> <div class="container">
<div class="grid gap-4 md:grid-cols-2"> <div class="grid gap-4 md:grid-cols-2">
{POSTDOCS.map((postdoc) => ( {POSTDOCS.map((postdoc) => (
<article class="rounded-lg border bg-background p-5"> <article class="flex gap-4 rounded-lg border bg-background p-4">
<h2 class="text-xl font-semibold">{postdoc.name}</h2> <div class="grid size-14 shrink-0 place-items-center rounded-lg bg-primary/10 text-lg font-semibold text-primary">
<p class="text-muted-foreground mt-1 text-sm">{postdoc.period}</p> {initials(postdoc.name)}
<dl class="mt-5 grid gap-2 text-sm"> </div>
<div class="min-w-0 flex-1">
<h2 class="text-sm font-semibold leading-snug">{postdoc.name}</h2>
<p class="text-muted-foreground text-xs">Postdoctoral Researcher</p>
<p class="text-muted-foreground mt-1 text-xs">{postdoc.period}</p>
<dl class="mt-4 grid gap-1.5 text-sm">
<div> <div>
<dt class="text-muted-foreground">Doctorate</dt> <dt class="text-muted-foreground inline">Doctorate: </dt>
<dd>{postdoc.phd}</dd> <dd class="inline">{postdoc.phd}, {postdoc.phdInstitute}</dd>
<dd>{postdoc.phdInstitute}</dd>
</div> </div>
<div> <div>
<dt class="text-muted-foreground">Working with</dt> <dt class="text-muted-foreground inline">Working with: </dt>
<dd>{postdoc.workingWith}</dd> <dd class="inline">{postdoc.workingWith}</dd>
</div> </div>
</dl> </dl>
</div>
</article> </article>
))} ))}
</div> </div>

View file

@ -1,10 +1,11 @@
--- ---
import { CSE_STAFF, CSE_STAFF_SOURCE } from '@/data/staff'; import { CSE_STAFF } from '@/data/staff';
import DefaultLayout from '@/layouts/DefaultLayout.astro'; import DefaultLayout from '@/layouts/DefaultLayout.astro';
import { Mail } from 'lucide-react';
--- ---
<DefaultLayout title="Staff" description="Administrative and technical staff of the CSE department"> <DefaultLayout title="Staff" description="Administrative and technical staff of the CSE department">
<section class="from-primary/5 bg-gradient-to-b to-transparent py-16 md:py-20"> <section class="from-primary/5 bg-gradient-to-b to-transparent pb-8 pt-16 md:pb-8 md:pt-20">
<div class="container"> <div class="container">
<p class="text-secondary text-sm font-medium uppercase tracking-wider">People</p> <p class="text-secondary text-sm font-medium uppercase tracking-wider">People</p>
<h1 class="mt-3 text-3xl md:text-4xl">Staff</h1> <h1 class="mt-3 text-3xl md:text-4xl">Staff</h1>
@ -14,25 +15,38 @@ import DefaultLayout from '@/layouts/DefaultLayout.astro';
</div> </div>
</section> </section>
<section class="section-padding"> <section class="pb-10 pt-6 md:pb-14 md:pt-8 lg:pb-16">
<div class="container"> <div class="container">
<div class="grid gap-4 md:grid-cols-2"> <div class="grid gap-4 md:grid-cols-2">
{CSE_STAFF.map((member) => ( {CSE_STAFF.map((member) => (
<article class="rounded-lg border bg-background p-4"> <article class="flex gap-4 rounded-lg border bg-background p-4">
<div class="flex gap-4">
<img <img
src={member.image} src={member.image}
alt={member.name} alt={member.name}
class="size-24 shrink-0 rounded-lg bg-muted object-cover" class="size-14 shrink-0 rounded-lg bg-muted object-cover"
loading="lazy" loading="lazy"
referrerpolicy="no-referrer" referrerpolicy="no-referrer"
/> />
<div class="min-w-0 flex-1">
<div class="flex items-start justify-between gap-2">
<div class="min-w-0"> <div class="min-w-0">
<h2 class="text-lg font-semibold">{member.name}</h2> <h2 class="text-sm font-semibold leading-snug">
<p class="text-muted-foreground mt-1 text-sm"> {member.name}
</h2>
<p class="text-muted-foreground text-xs">
{member.designation} {member.designation}
</p> </p>
<dl class="mt-4 grid gap-1 text-sm"> </div>
<a
href={`mailto:${member.emailUser}@iitgn.ac.in`}
class="text-muted-foreground hover:text-secondary shrink-0 transition-colors"
aria-label={`Email ${member.name}`}
title="Email"
>
<Mail className="size-3.5" aria-hidden="true" />
</a>
</div>
<dl class="mt-3 grid gap-1 text-sm">
<div> <div>
<dt class="text-muted-foreground inline">Email: </dt> <dt class="text-muted-foreground inline">Email: </dt>
<dd class="inline">{member.emailUser}@iitgn.ac.in</dd> <dd class="inline">{member.emailUser}@iitgn.ac.in</dd>
@ -45,13 +59,9 @@ import DefaultLayout from '@/layouts/DefaultLayout.astro';
)} )}
</dl> </dl>
</div> </div>
</div>
</article> </article>
))} ))}
</div> </div>
<p class="text-muted-foreground mt-6 text-sm">
Source: <a class="underline underline-offset-2" href={CSE_STAFF_SOURCE} target="_blank" rel="noreferrer">IITGN staff directory</a>
</p>
</div> </div>
</section> </section>
</DefaultLayout> </DefaultLayout>

View file

@ -10,6 +10,13 @@ type Project = {
source: string; source: string;
}; };
type GrantAnnouncement = {
scheme: string;
faculty: string;
note: string;
source: string;
};
const projects: Project[] = [ const projects: Project[] = [
{ {
title: 'Approximate Shortest Paths in Graphs', title: 'Approximate Shortest Paths in Graphs',
@ -27,6 +34,22 @@ const projects: Project[] = [
period: 'July-September 2026', period: 'July-September 2026',
source: 'https://iitgn.ac.in/newsletter/projects/q3_2026', source: 'https://iitgn.ac.in/newsletter/projects/q3_2026',
}, },
{
title: 'Scalable Detection of Brick Kilns from Low-Resolution Satellite Imagery for Environmental Compliance',
faculty: 'Nipun Batra',
sponsor: 'Anusandhan National Research Foundation',
category: 'ANRF/SERB',
period: 'Announced in 2026',
source: 'https://www.linkedin.com/school/indian-institute-of-technology-gandhinagar-iitgn-/posts/',
},
{
title: 'iGazeBuddy: Multimodal gaze-controlled learning system for dyslexia support',
faculty: 'Yogesh Kumar Meena',
sponsor: 'Anusandhan National Research Foundation (PMECRG)',
category: 'ANRF/SERB',
period: 'Announced in 2026',
source: 'https://www.linkedin.com/posts/ykmeena_hiring-research-assistivetechnology-activity-7406640584490336256-wDnH',
},
{ {
title: 'Fair Federated Learning Framework in the Presence of Heterogeneous, Strategic, and Malicious Clients', title: 'Fair Federated Learning Framework in the Presence of Heterogeneous, Strategic, and Malicious Clients',
faculty: 'Manisha Padala', faculty: 'Manisha Padala',
@ -126,6 +149,27 @@ const projects: Project[] = [
]; ];
const categories = ['ANRF/SERB', 'International', 'Sponsored', 'Industry/Research Lab', 'Consultancy']; const categories = ['ANRF/SERB', 'International', 'Sponsored', 'Industry/Research Lab', 'Consultancy'];
const recentGrantAnnouncements: GrantAnnouncement[] = [
{
scheme: 'ANRF Prime Minister Early Career Research Grant',
faculty: 'Manisha Padala, Shouvick Mondal, Yogesh Kumar Meena',
note: 'Recent CSE announcement listing department awardees under PMECRG.',
source: 'https://www.linkedin.com/posts/cse-iitgn_anusandhan-national-research-foundation-activity-7419330427775115265-v86v',
},
{
scheme: 'ANRF Advanced Research Grant',
faculty: 'Mayank Singh, Nipun Batra, Abhishek Bichhawat',
note: 'Recent CSE announcement listing department awardees under ARG.',
source: 'https://www.linkedin.com/posts/cse-iitgn_anusandhan-national-research-foundation-activity-7419330427775115265-v86v',
},
{
scheme: 'ANRF ARG MATRICS',
faculty: 'Bireswar Das, Manoj Gupta, Balagopal Komarath',
note: 'Recent CSE announcement listing department awardees under ARG MATRICS.',
source: 'https://www.linkedin.com/posts/cse-iitgn_anusandhan-national-research-foundation-activity-7419330427775115265-v86v',
},
];
--- ---
<DefaultLayout title="Projects" description="Funded research projects, collaborations, and consultancies."> <DefaultLayout title="Projects" description="Funded research projects, collaborations, and consultancies.">
@ -159,7 +203,42 @@ const categories = ['ANRF/SERB', 'International', 'Sponsored', 'Industry/Researc
} }
</div> </div>
<div class="mt-8 grid gap-4 md:grid-cols-2"> <div class="mt-8 rounded-lg border border-border bg-muted/30 p-5">
<div class="max-w-3xl">
<p class="text-sm font-medium text-secondary">Recent ANRF announcements</p>
<h2 class="mt-2 text-2xl font-semibold">
Department faculty have secured multiple recent ANRF grants
</h2>
<p class="mt-3 text-sm leading-relaxed text-muted-foreground">
Recent public announcements list CSE faculty awardees across ANRF
PMECRG, Advanced Research Grant, and ARG MATRICS schemes. Project
titles are included below where they are publicly available.
</p>
</div>
<div class="mt-5 grid gap-4 md:grid-cols-3">
{
recentGrantAnnouncements.map((grant) => (
<article class="rounded-lg border bg-background p-4">
<h3 class="font-semibold">{grant.scheme}</h3>
<p class="mt-3 text-sm font-medium">{grant.faculty}</p>
<p class="mt-2 text-sm leading-relaxed text-muted-foreground">{grant.note}</p>
<a
href={grant.source}
class="mt-4 inline-flex text-sm font-medium text-primary underline-offset-4 hover:underline"
target="_blank"
rel="noreferrer"
>
Announcement -&gt;
</a>
</article>
))
}
</div>
</div>
<h2 class="mt-10 text-2xl font-semibold">Selected project listings</h2>
<div class="mt-5 grid gap-4 md:grid-cols-2">
{ {
projects.map((project) => ( projects.map((project) => (
<article class="rounded-lg border border-border bg-card p-5 shadow-sm"> <article class="rounded-lg border border-border bg-card p-5 shadow-sm">

View file

@ -8,7 +8,7 @@ import {
type EventCategory, type EventCategory,
} from "@/data/events"; } from "@/data/events";
import DefaultLayout from "@/layouts/DefaultLayout.astro"; import DefaultLayout from "@/layouts/DefaultLayout.astro";
import { CalendarDays, Search, Sparkles } from "lucide-react"; import { ArrowRight, CalendarDays, Search, Sparkles } from "lucide-react";
const categoryOrder: EventCategory[] = [ const categoryOrder: EventCategory[] = [
"conference", "conference",
@ -167,6 +167,20 @@ const groupedPastEvents = Object.entries(
<p class="text-muted-foreground mt-2 text-sm"> <p class="text-muted-foreground mt-2 text-sm">
{event.description} {event.description}
</p> </p>
{event.sourceUrl && (
<a
href={event.sourceUrl}
class="group mt-4 inline-flex items-center gap-2 text-sm font-medium text-secondary"
target="_blank"
rel="noreferrer"
>
{event.sourceLabel ?? "Event website"}
<ArrowRight
className="size-4 transition group-hover:translate-x-1"
aria-hidden="true"
/>
</a>
)}
{(event.organizer || event.collaborators) && ( {(event.organizer || event.collaborators) && (
<dl class="mt-4 grid gap-1.5 text-sm"> <dl class="mt-4 grid gap-1.5 text-sm">
{event.organizer && ( {event.organizer && (
@ -238,6 +252,20 @@ const groupedPastEvents = Object.entries(
<p class="text-muted-foreground mt-2 text-sm"> <p class="text-muted-foreground mt-2 text-sm">
{event.description} {event.description}
</p> </p>
{event.sourceUrl && (
<a
href={event.sourceUrl}
class="group mt-4 inline-flex items-center gap-2 text-sm font-medium text-secondary"
target="_blank"
rel="noreferrer"
>
{event.sourceLabel ?? "Event website"}
<ArrowRight
className="size-4 transition group-hover:translate-x-1"
aria-hidden="true"
/>
</a>
)}
</article> </article>
)) ))
} }
@ -298,6 +326,20 @@ const groupedPastEvents = Object.entries(
<p class="text-muted-foreground mt-1 text-sm"> <p class="text-muted-foreground mt-1 text-sm">
{event.description} {event.description}
</p> </p>
{event.sourceUrl && (
<a
href={event.sourceUrl}
class="group mt-3 inline-flex items-center gap-2 text-sm font-medium text-secondary"
target="_blank"
rel="noreferrer"
>
{event.sourceLabel ?? "Event website"}
<ArrowRight
className="size-4 transition group-hover:translate-x-1"
aria-hidden="true"
/>
</a>
)}
</div> </div>
<div class="text-sm"> <div class="text-sm">
{event.organizer && ( {event.organizer && (