Skip to content

edbrsk/uoc-planner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

5 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ“š UOC Planner

Weekly planner view

A weekly planner for UOC (Universitat Oberta de Catalunya) students. Visualize your courses, deadlines, and weekly tasks in a modern interface with a full semester roadmap.

Developed by Edgar @edbrsk

โœจ Features

  • ๐Ÿ“… Weekly planning โ€” Tasks organized by week and course
  • ๐Ÿ“Š Visual roadmap โ€” Swimlane timeline of all semester deliverables
  • ๐Ÿ”ฅ Real-time sync โ€” Firebase-backed, works across devices
  • ๐Ÿ’พ Offline mode โ€” Works without an account using browser localStorage
  • ๐Ÿ”’ Self-hosted data โ€” Each user connects their own Firebase project
  • โšก Upcoming deadline highlights โ€” Deliverables due within 15 days are flagged
  • โฌ†๏ธ JSON import โ€” Paste LLM-generated planning data directly into the app
  • โฌ‡๏ธ JSON export โ€” Export your modified data to share or back up
  • ๐Ÿ“ฒ Installable PWA โ€” Add to home screen on iOS and Android for a native app experience
  • ๐Ÿ–จ๏ธ Print-ready โ€” Optimized layout for printing
  • ๐Ÿ“ฑ Responsive โ€” Works on desktop and mobile

๐Ÿ“ฒ Install as App

UOC Planner is a Progressive Web App (PWA) โ€” you can install it on your phone for a native app look and feel, no app store needed.

iOS (Safari)

  1. Open the app in Safari
  2. Tap the Share button (โฌ†๏ธ)
  3. Select "Add to Home Screen"
  4. Tap "Add"

Android (Chrome)

  1. Open the app in Chrome
  2. Tap the three-dot menu (โ‹ฎ)
  3. Select "Add to Home Screen" or "Install App"
  4. Tap "Install"

The app will appear on your home screen with its own icon and launch in full-screen mode, just like a native app.


๐ŸŽฎ Quick Demo (no setup required)

Want to try the app without any configuration?

  1. Open the app and click ๐Ÿ’พ Usar sin cuenta (offline)
  2. Click your profile avatar (top-right) โ†’ โฌ†๏ธ Importar JSON
  3. Copy the contents of demo/uoc_planner_2025-2.json and paste it
  4. Click Validar JSON โ†’ Importar semestre
  5. Explore the full app with 18 weeks, 5 courses, and 30+ deadlines!

๐Ÿš€ Setup

Option 1: Offline mode (no account)

Just click ๐Ÿ’พ Usar sin cuenta (offline) on the login screen. Your data is stored in the browser's localStorage โ€” no Firebase, no Google account needed.

Option 2: Firebase (cloud sync)

  1. Go to console.firebase.google.com
  2. Create a new project (free Spark plan)
  3. Add a Web app and copy the firebaseConfig object
  4. Enable Authentication โ†’ Google as a sign-in provider
  5. Create a Firestore Database in test mode
  6. On the setup screen, paste your firebaseConfig JSON

Running locally

git clone https://github.com/edbrsk/uoc-planner.git
cd uoc-planner
npm install
npm run dev

๐Ÿ“Š Generating Your Data with AI

The power of UOC Planner is that an LLM (Claude, ChatGPT, etc.) can automatically generate your entire weekly plan by analyzing your virtual campus.

Recommended: Claude + Canvas LMS MCP

  1. Install the Canvas MCP server โ€” mcp-canvas-lms
  2. Generate an access token from your campus:
  3. Configure the MCP in Claude Desktop with your token and Canvas base URL
  4. Use the prompt below to generate your planning data

Alternative: without the MCP

If you don't have the Canvas MCP, you can manually copy the syllabus, calendar, and deliverable schedule from each course in your virtual campus, then paste it into a chat with your preferred LLM alongside the prompt and JSON schema below.

Prompt

You have access to my Canvas LMS courses for the current semester using the mcp-canvas-lms. Build a comprehensive weekly study plan following ALL the rules below exactly.

STEP 1 โ€” COURSE DISCOVERY:

โ€ข Use canvas_list_courses to find all active courses for the current semester term. Ignore any courses from previous terms (check enrollment_term_id). โ€ข For each active course, call canvas_list_assignments and capture for every assignment: name, due_at, unlock_at, html_url, submission_types, points_possible.

STEP 2 โ€” TIMEZONE CONVERSION (CRITICAL):

Canvas stores all timestamps in UTC. My timezone is Spain: โ€ข CET = UTC+1 โ†’ applies before the last Sunday of March โ€ข CEST = UTC+2 โ†’ applies from the last Sunday of March onward For 2026: CET before March 29; CEST from March 29 onward.

Convert EVERY unlock_at and due_at to Spain local time before using them > anywhere. Key rule: an unlock_at of 23:00 UTC on day D becomes 00:00 local time on > day D+1. โ†’ Display as "abre D+1 mmm", never "abre D mmm". Example: unlock_at 2026-03-19T23:00:00Z โ†’ 2026-03-20 00:00 CET โ†’ "abre 20 mar"

STEP 3 โ€” UNLOCK-DATE RULE:

โ€ข Never schedule a task to start working on an assignment before its unlock_at (converted to Spain local time). โ€ข For weeks before unlock: use study/reading preparation tasks instead, with "(preparacion NombreTarea, abre DD mmm)" in the task text. โ€ข If an assignment unlocks mid-week: it may appear in that week with "(abre DD mmm)".

STEP 4 โ€” TASK GRANULARITY (CRITICAL):

โ€ข ONE task per deliverable per week. Never merge multiple separate deliverables into a single task. โœ— WRONG: "Hacer Q1, Q2, Q3 y empezar R1 (vencen 13 mar)" โœ“ RIGHT: Three separate tasks โ€” Q1 in week 1, Q2 in week 2, Q3 in week 3

โ€ข For courses with weekly cuestionarios (e.g., AL), place exactly ONE cuestionario per week following the course's intended weekly schedule, even if they all share the same final deadline.

โ€ข Reading/study tasks must also be split per chapter or unit, one per week, mirroring the course's own weekly structure.

โ€ข For each Reto in AL: create separate tasks for (1) reading/preparation, (2) Preparar Reto, (3) Entregar Reto, and (4) Subir Video โ€” each in its own week.

STEP 5 โ€” VIDEO SUBMISSION TASKS:

โ€ข Video submissions have very short unlock windows (3โ€“5 days). Place video tasks ONLY in the week they actually unlock โ€” never earlier. โ€ข Task text format: "Subir Video Reto 1 (abre 20 mar, entrega: 23 mar)" โ€ข Set "urgent": true for video deadlines with โ‰ค 3 days window.

STEP 6 โ€” COMBINED TASK RULE:

When a deadline and the start of the next assignment fall in the same week but the new assignment is still locked: create two separate entries โ€” one for the delivery, one for study/preparation. Never write "Entregar X. Empezar Y" if Y is not yet unlocked.

STEP 7 โ€” WEEK-BY-WEEK PLAN:

โ€ข Cover all active courses simultaneously, interleaved by urgency and workload. โ€ข Each week: 3โ€“8 tasks across multiple courses. โ€ข Within each week, order tasks by priority (most urgent / closest deadline first). โ€ข Use these course abbreviations exactly: AL, Prob, Prog, Redes, Lab (not "LabPyR" or any other variant).

STEP 8 โ€” CANVAS URLs:

โ€ข For every task that maps to a specific Canvas assignment, include: "url": <html_url from canvas_get_assignment> โ€ข For generic study/preparation tasks with no direct Canvas assignment, omit the "url" field entirely. Do not include null or empty strings.

STEP 9 โ€” NOTES AND taskId (CRITICAL):

The "tasks" array is 0-indexed. The taskId in each note must be "task_N" where N is the 0-BASED position of that task in the tasks array. โ†’ tasks[0] = "task_0", tasks[1] = "task_1", tasks[38] = "task_38", etc.

NEVER use an empty string "", null, or undefined for taskId. Every note must be linked to a specific task โ€” for general/calendar notes, choose the most relevant task (e.g., the delivery task it warns about).

Before writing the final JSON: verify each note's taskId by counting the 0-based position of the intended task in the tasks array and confirm the text at that index matches your intent.

STEP 10 โ€” SELF-VERIFICATION BEFORE OUTPUT:

Before writing the final JSON, run these checks:

  1. All unlock_at dates have been converted to Spain local time (CET/CEST).
  2. No task appears in a week before its unlock date.
  3. No week has merged cuestionarios that should be separate weekly tasks.
  4. Every note's taskId resolves to tasks[N] where tasks[N].text matches what the note is referring to.
  5. No taskId uses "", null, or a non-existent index.

OUTPUT SCHEMA (exact โ€” do not deviate):

{ "semester": { "name": "2025-2", "label": "Semestre 2025-2", "startDate": "2026-02-17", "endDate": "2026-06-22" }, "weeks": { "1": { "dates": "17 feb โ€“ 23 feb", "title": "Arranque del semestre" } }, "tasks": [ { "weekNum": 1, "course": "AL", "text": "Hacer Cuestionario 1 (Q1) โ€” entrega: 13 mar", "order": 0, "done": false, "url": "https://aula.uoc.edu/courses/..." } ], "deadlines": [ { "date": "2026-03-13", "label": "AL โ€” Reto 1 + Q1+Q2+Q3", "course": "AL", "urgent": false, "order": 0 } ], "notes": [ { "taskId": "task_3", "text": "Note text โ€” taskId is the 0-based index of the task in the tasks array." } ] }

Additional output rules: โ€ข All dates in YYYY-MM-DD format. โ€ข "urgent": true only for deliverables with โ‰ค 3 days between unlock and due date. โ€ข "done": false for all tasks. โ€ข tasks array ordered chronologically (weekNum ASC, then order ASC within each week). โ€ข Output only the raw JSON โ€” no markdown code fences, no explanations.


โฌ†๏ธ Import & โฌ‡๏ธ Export

Both features are accessible from the profile menu (click your avatar in the top-right corner).

Importing JSON

  1. Click your profile avatar โ†’ โฌ†๏ธ Importar JSON
  2. Paste the complete JSON (from an LLM, an export, or the demo file)
  3. Click Validar JSON โ€” a preview shows courses, task count, and deadline count
  4. Click Importar semestre

Exporting JSON

  1. Click your profile avatar โ†’ โฌ‡๏ธ Exportar JSON
  2. A .json file downloads with the exact same schema used for import
  3. Share it, back it up, or re-import it later

This means you can: generate data with AI โ†’ import โ†’ modify in the app โ†’ export โ†’ share with classmates.


๐Ÿ“‹ JSON Schema Reference

Field Type Description
semester.name string Unique identifier (e.g., "2025-2")
semester.label string Display name (e.g., "Semester 2025-2")
semester.startDate string Start date in YYYY-MM-DD format
semester.endDate string End date in YYYY-MM-DD format
weeks.N.dates string Human-readable date range (e.g., "Feb 17 โ€“ 23")
weeks.N.title string Week summary / theme
tasks[].weekNum number Week number (1, 2, 3...)
tasks[].course string Course abbreviation (e.g., "AL")
tasks[].text string Task description
tasks[].order number Sort order within the week (0, 1, 2...)
tasks[].done boolean Completion status โ€” default false
tasks[].url string (optional) Direct Canvas URL to the assignment/quiz (html_url from Canvas API)
deadlines[].date string Due date in YYYY-MM-DD format
deadlines[].label string Deliverable description
deadlines[].course string Course abbreviation
deadlines[].urgent boolean true for extremely short submission windows
deadlines[].order number Display order
notes[].taskId string ID of the task this note belongs to (optional on import if mapped during generation)
notes[].text string The note content

๐Ÿ—๏ธ Tech Stack

Technology Purpose
React 19 UI components
Vite 6 Build tool + dev server
TailwindCSS v4 Styling
Firebase Firestore Real-time database (optional)
Firebase Auth Google sign-in (optional)
localStorage Offline data storage
GitHub Pages Deployment

๐Ÿ“ฆ Deployment

The app deploys automatically to GitHub Pages via GitHub Actions on every push to main. See .github/workflows/deploy.yml.

๐Ÿ› ๏ธ Development

npm run dev      # Dev server (http://localhost:5173)
npm run build    # Production build
npm run preview  # Preview production build

๐Ÿ“ Project Structure

โ”œโ”€โ”€ demo/
โ”‚   โ””โ”€โ”€ uoc_planner_2025-2.json   # Demo data for quick testing
src/
โ”œโ”€โ”€ App.jsx                        # Main application component
โ”œโ”€โ”€ main.jsx                       # Entry point
โ”œโ”€โ”€ index.css                      # Global styles + Tailwind
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ firebase.js                # Dynamic Firebase initialization
โ”‚   โ”œโ”€โ”€ constants.js               # Colors, date helpers
โ”‚   โ””โ”€โ”€ store.js                   # Offline localStorage data layer
โ”œโ”€โ”€ hooks/
โ”‚   โ”œโ”€โ”€ useAuth.js                 # Authentication (Firebase + offline)
โ”‚   โ”œโ”€โ”€ useSemesters.js            # Semester CRUD (Firebase + offline)
โ”‚   โ”œโ”€โ”€ useTasks.js                # Task CRUD (Firebase + offline)
โ”‚   โ””โ”€โ”€ useDeadlines.js            # Deadline CRUD (Firebase + offline)
โ””โ”€โ”€ components/
    โ”œโ”€โ”€ AuthScreen.jsx             # Login screen (Google + offline)
    โ”œโ”€โ”€ SetupScreen.jsx            # Firebase / offline mode selection
    โ”œโ”€โ”€ Header.jsx                 # Header + profile dropdown
    โ”œโ”€โ”€ CoursePills.jsx            # Course filter pills
    โ”œโ”€โ”€ WeekCard.jsx               # Collapsible week card
    โ”œโ”€โ”€ TaskItem.jsx               # Individual task item
    โ”œโ”€โ”€ DeadlinesSection.jsx       # Deadline table
    โ”œโ”€โ”€ RoadmapView.jsx            # Swimlane roadmap
    โ”œโ”€โ”€ ImportModal.jsx            # JSON import modal
    โ”œโ”€โ”€ Modal.jsx                  # Reusable modal shell
    โ”œโ”€โ”€ TaskModal.jsx              # Task form
    โ”œโ”€โ”€ DeadlineModal.jsx          # Deadline form
    โ”œโ”€โ”€ SemesterModal.jsx          # Semester + week forms
    โ””โ”€โ”€ Toast.jsx                  # Toast notifications

๐Ÿ“„ License

MIT

About

A weekly planner for UOC using LLM & mcp-canvas-lms

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages