A next-generation student learning dashboard built with Next.js 15, Supabase, Tailwind CSS, and Framer Motion.
Nexus Learning OS is a dark-mode learning dashboard that surfaces real course data from a Supabase database alongside activity tracking, goal management, achievement badges, and AI-powered study suggestions. The focus is clean architecture, readable code, and a polished but professional UI — not visual spectacle.
- Real Supabase integration — Course cards are fetched server-side and rendered dynamically
- Bento grid layout — Responsive 4-column desktop, 2-column tablet, single-column mobile
- Framer Motion animations — Staggered card entrances, progress bar fills, animated charts
- Activity heatmap — GitHub-style contribution grid with hover tooltips
- AI study suggestions — Personalized recommendations panel
- Goal tracker — Daily and weekly progress bars with animated progress ring
- Achievement badges — Unlock-style badge grid
- Accessibility — ARIA labels, keyboard navigation, visible focus states, semantic HTML
- Loading skeletons — Shimmer placeholders match the live layout
- Error boundary — Graceful fallback with retry button
| Layer | Technology |
|---|---|
| Framework | Next.js 15 App Router |
| Language | TypeScript (strict) |
| Styling | Tailwind CSS |
| Animation | Framer Motion |
| Database | Supabase |
| Icons | Lucide React |
| Fonts | Geist (Next.js font) |
| Deployment | Vercel |
nexus-learning-os/
├── app/
│ ├── layout.tsx # Root layout, fonts, metadata
│ ├── page.tsx # Dashboard page (Server Component)
│ ├── loading.tsx # Full-page skeleton
│ └── error.tsx # Error boundary
├── components/
│ ├── sidebar/
│ │ └── Sidebar.tsx # Desktop nav (Client)
│ ├── dashboard/
│ │ ├── HeroCard.tsx # Welcome tile with stats
│ │ ├── CourseGrid.tsx # Server Component — Supabase fetch
│ │ ├── CourseCard.tsx # Individual course tile (Client)
│ │ ├── ActivityCard.tsx # Heatmap (Client)
│ │ ├── AIAssistantCard.tsx # Study suggestions (Client)
│ │ ├── AnalyticsCard.tsx # SVG line chart (Client)
│ │ ├── GoalCard.tsx # Goal tracker (Client)
│ │ ├── AchievementCard.tsx # Badge grid (Client)
│ │ └── DashboardHeader.tsx # Page header (Client)
│ └── ui/
│ ├── MobileNav.tsx # Bottom nav bar
│ ├── ProgressRing.tsx # SVG ring component
│ ├── SkeletonCard.tsx # Shimmer placeholder
│ └── SectionLabel.tsx # Section heading
├── lib/
│ └── supabase/
│ └── server.ts # Supabase SSR client
├── hooks/ # Reserved for custom hooks
├── types/
│ └── index.ts # TypeScript interfaces
├── .env.example
└── README.md
CREATE TABLE courses (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT NOT NULL,
progress INTEGER NOT NULL DEFAULT 0,
icon_name TEXT NOT NULL DEFAULT 'BookOpen',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);BookOpen, Cpu, Brain, Cloud, Code, Database, Globe, Layers, Palette, Zap, BarChart, Lock
CourseGrid is a React Server Component. It calls createClient() from lib/supabase/server.ts, runs the query, and returns rendered CourseCard elements. A <Suspense> boundary in app/page.tsx shows skeleton cards while the fetch resolves.
- Entrance animations —
opacity: 0 → 1,y: 24 → 0, staggered viadelayper card - Spring config —
type: "spring",stiffness: 300,damping: 24 - Progress bars —
scaleX: 0 → progress%usingtransformOrigin: "left" - Progress rings —
strokeDashoffsetanimated from full to partial - Heatmap cells — Scale + opacity entrance, staggered by index
- GPU safety — Only
transformandopacityare animated; no layout properties
- Semantic HTML:
<nav>,<main>,<header>,<section>,<article>,<ul>,<li> aria-labelon all interactive and landmark elementsaria-current="page"on active nav itemrole="progressbar"witharia-valuenow,aria-valuemin,aria-valuemaxon progress barsrole="alert"andaria-live="polite"on error and empty states- Visible
:focus-visibleoutline usingoutline: 2px solid #6366f1 - Keyboard navigable sidebar and mobile nav
- Animations use
transformandopacityonly — no layout-triggering properties will-change: transformapplied to hover targets- Images avoided entirely — icon-based UI only
- Fonts loaded via
next/font/googlewith display swap - Course data fetched once server-side, no client waterfall
# 1. Clone and install
git clone <your-repo-url>
cd nexus-learning-os
npm install
# 2. Set environment variables
cp .env.example .env.local
# Fill in your Supabase URL and publishable key
# 3. Run dev server
npm run devVisit http://localhost:3000.
- Push the project to a GitHub repository.
- Import the repository in Vercel.
- Add environment variables in the Vercel project settings:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
- Deploy. Vercel auto-detects Next.js; no extra config needed.