Welcome back
Here's your evaluation center at a glance.
🩺
Connect Evaluation Data
Choose how to load your Google Form responses

Auto-Connect (Default)

Loads automatically from the configured Google Sheet on every page open.

🔗

Google Sheet Link

Enter any sharable Google Sheet URL to load from a different source.

📄

Upload CSV File

Manually upload an exported CSV file from Google Sheets.

Example: https://docs.google.com/spreadsheets/d/.../edit?usp=sharing

📄
Drop your CSV file here or click to browse
Export from Google Sheets: File → Download → CSV (.csv)
✓ That's all you need — everything below is optional
⚙️ Advanced setup (optional) — merge extra evaluation sheets & link quizzes to rotations

📊 Merge Multiple Evaluation Sheets Optional

Have evaluations split across more than one Google Form / sheet? Add each one here and the dashboard loads them together with your default sheet — all evaluations pooled per resident. Each sheet must use the same evaluation columns and be shared "Anyone with the link".

🎯
Link Quiz Scores to Rotations Optional
If your program gives residents quizzes tied to specific rotations, connect them here. The dashboard will auto-match each quiz to the correct rotation period on every resident's profile so their ITER exam % fills in automatically. Works with any institution's rotation naming — just tell it which rotation codes to look for.
▶ How the mapping works
  1. Load quiz scores — each row is one resident, each column is one quiz (Quiz 1, Quiz 2, …). Up to 5 quizzes supported.
  2. Load the rotation schedule — each row is one resident with 13 blocks for the academic year. Block cells contain whatever rotation codes your program uses (e.g. EM-Main, PICU, Elective).
  3. Tell us which codes are "core" — quizzes are only auto-assigned to blocks matching these codes. The Nth matching block a resident does receives Quiz N. Consecutive matching blocks form a single ITER period whose exam % is the average of its quizzes.
  4. Override anytime — per-resident on the profile page via the Map manually button next to the quiz picker, or skip all of this and enter the exam % by hand.

1📚 Quiz & Exam Scores

Paste a Google Sheet URL (shared as "Anyone with the link") or upload a CSV. Each row is one resident, each column is one quiz/exam (Quiz 1, Quiz 2, …). Column labels can be anything — the app matches on "Quiz N" style.

Tabs:
Leave blank to read only the tab your link points to. Enter the exact tab names (comma-separated) to read every level and merge them all — applies on Load and Refetch. For a hidden tab, enter its gid (the number after #gid= in that tab's URL) instead of its name.
Not loaded yet.

2📅 Rotation Schedule

Your master annual rotation now lives in the Schedules tab (left menu). Load it there once — quiz-to-block matching picks it up automatically. Optional if you only enter exam % by hand.

3🎯 Core Rotation Codes

Which rotation labels in your schedule should receive quizzes? Enter a comma-separated list — partial matches work (e.g. EM-Main matches EM-Main-1). Quizzes are only auto-assigned to blocks whose code matches one of these.

Currently using:
💡 Examples. If your schedule uses EM-Main for in-hospital EM rotations, enter just that. If you have two in-program codes like EM-Adult and EM-Peds, enter both separated by a comma. Rotations that don't match (Electives, Research, External, etc.) are skipped — no quiz is auto-assigned to them.
Program Roster
Your program's residents, per academic year. Only residents listed here will be tracked for long-term progress, assessments, and KPI cards. Rotators and external trainees do not need to be in the roster — they remain visible in daily evaluations.
Name Level Specialty Hospital Email Start date Status Actions
No residents in this year's roster yet. Use Import from Google Sheet names to pull in your current trainees, or Bulk paste from Excel.
💡 Tip: The roster is stored in your account and syncs across your devices. Use the Academic year switcher to view a past year, promote residents to graduated, or start a new intake without losing history.
Assessments
Track every assessment — quizzes, written exams, OSCEs, simulations, case presentations, research, and more. Connect a Google Sheet or upload a CSV.
📄 Assessments Google Sheet
Paste a Google Sheet URL with your assessment results. Two formats work:
Long format: Resident / Type / Date / Score / Max (one row per result)
Wide format: Resident + a column per assessment (e.g. Quiz 1 (%), OSCE, Written Exam) — each column becomes an assessment type.
Make sure the sheet is shared with Anyone with the link.
Tabs:
Leave empty to use whichever tab your URL points to. Enter a comma-separated list of tab names (e.g. R1, R2, R3) to fetch every level at once. The tab name becomes the resident's level label. For a hidden tab, enter its gid (the number after #gid= in its URL) instead.
Not loaded yet.
Resident Level Type Score % Notes
No assessments loaded yet. Connect a Google Sheet or upload a CSV above.
📝 Sheet format tip: Either long (Resident / Type / Score / Max) or wide (Resident + one column per assessment, e.g. Quiz 1 Final (%), OSCE, Written Exam). In wide mode, each column header becomes the assessment type and cell values are treated as percentages. When you list tab names above, the dashboard fetches each tab and tags every row with that tab's name as the resident's level. Preset types: Quiz, Written Exam, OSCE, Simulation, Case Presentation, Research, Chart Review, 360 Feedback — but any column name works.
📧 Email Grades to Residents
Send personalized result emails to each resident with their score table embedded. Edit the draft below, pick recipients, then either compose individually in Gmail or open all selected at once.
Recipient list source: No list loaded yet.
One-click bulk send via Gmail API
Sign in with Google once, then send all selected recipients rich HTML emails in one click.
{{firstname}} {{lastname}} {{fullname}} {{percentage}} {{points}} {{max}} {{email}} {{table}} {{note}} {{myname}} {{mytitle}} {{mycenter}}
Click a placeholder to insert it. {{table}} drops in the score table for that resident; {{note}} is your per-resident custom note. {{myname}} / {{mytitle}} / {{mycenter}} fill in your own name, title, and center from your profile. HTML tags work in the body.
Load a list and select a resident to preview their email here.
All 0 ⚡ ≥75% 0 60–74% 0 50–59% 0 <50% 0
No recipients yet. Upload a ClassMarker CSV or load assessments.
0 selected
Tip: Gmail's mailto: link sends as plain text. For the rich HTML version with the formatted table, click 📄 Copy HTML body on a row, then paste it into the Gmail compose window.

Custom note

Sending emails...

Please keep this window open until all emails are sent.
0 / 0

Gmail API setup — step by step

One-time setup, ~10 minutes, in your own Google Cloud project (create a free one at console.cloud.google.com → if you don't have one, then select it before the steps below).
  1. Go to Gmail API library → and click Enable.
  2. Go to OAuth consent screen →.
    • User type: External (if first time).
    • App name: PD Dashboard
    • User support email + developer contact: your Gmail.
    • Under Scopes, add: .../auth/gmail.send
    • Under Test users, add your own Gmail address. Add any co-admins too.
  3. Go to Credentials →. Click + Create Credentials → OAuth client ID.
    • Application type: Web application.
    • Name: PD Dashboard Web.
    • Authorized JavaScript origins: add https://app.pdashboard.io
    • Authorized redirect URIs: leave empty (we use token flow, not auth code).
    • Click Create.
  4. Copy the Client ID (looks like 1234567890-xxx.apps.googleusercontent.com) and paste it in the Client ID field in the dashboard, then click Save Client ID.
  5. Click Connect Gmail → sign in → approve the Send email on your behalf permission.
  6. Done. Click 🚀 Send all selected via Gmail to send.
Note: While in Testing mode, only users listed as Test Users can sign in. The app will show a "Google hasn't verified this app" warning — that's normal for Testing mode. Click Advanced → Go to PD Dashboard (unsafe) to proceed. Your own app, your own data, safe to use.

Email preview

All Residents Overview
Click any row to view detailed profile. Flagged residents have fewer than 5 evaluations in the selected period.
ResidentLevelEvalsH&PEPres/DDxActivityPunctualityOverallStatus
Find Resident
Search by name to view evaluations and generate ITER scores
Schedules
Two kinds of schedule power the dashboard. Set up whichever you have — you can use one, the other, or both.

📅 Master annual rotation powers profile rotation strip + quiz matching

One row per resident, with the 13 block rotations across the year in columns (e.g. EM-KFMC, PEM-KFMC, Elective, Community). A leading index/number column is fine — the resident name is detected automatically, and title/level header rows (R4, R3…) are skipped. Loading this builds the rotation strip on each resident's profile and auto-matches quiz scores to the right block. Share it "Anyone with the link".

Tabs:
Leave blank to read only the tab your link points to. Enter the exact tab names (comma-separated) to read those tabs and merge all residents together — applies on Load and Refetch. To read a hidden tab, enter its gid (the number after #gid= in that tab's URL) instead of its name.
Not loaded yet.

📎 Per-block schedule workbooks powers name lookup + per-block detail

A workbook with one tab per block (each tab lists residents by level with their rotation and shifts). Paste the workbook URL (shared "Anyone with the link"), then list the block tab names it contains. The lookup reads each tab you list and finds residents by name. Google won't serve hidden tabs by name — to read a hidden block, enter its gid (the number after #gid= in that block tab's URL) in the block-tab box instead of its name. Add one workbook per academic year if you keep them separate. Then search any name below to confirm whether — and in which block — they rotated with you (handy for rotators who aren't in your evaluation data).

No schedule workbooks connected.
Score Trend Over Time
Track performance trajectory across evaluations
Assessment Progress
Quiz and exam results over time — track trajectory across assessments

Scores mapped from daily evaluations (/10) to ITER 1-4 scale. Knowledge-domain criteria can also use an exam score. Final Score is editable — override any value before auto-fill.

🎓 Exam Score (Knowledge Domain)
📄 Bulk upload CSV
Enter exam %: % Applies to criteria: 2, 3, 4, 7, 15, 20, 23

Console Script (Alternative Method)

If bookmarklet doesn't work: Open the ITER form in your browser → F12 → Console → Paste → Enter

Evaluator Comments & Areas for Improvement
Comments are the most valuable part of each evaluation — review carefully before ITER submission.
Batch Export — All Residents ITER Summary
Generate a CSV with ITER scores for every resident in a selected month
Quick ITER Fill
Enter domain percentages to generate an ITER auto-fill — no daily evaluations needed
Clinical
Criteria 1, 5, 6, 8, 9, 14, 16, 17, 18, 19
%
Knowledge
Criteria 2, 3, 4, 7, 15, 20, 23
%
Attitude & Behaviour
Criteria 11, 12, 26
%
Documentation
Criteria 10, 13
%
Punctuality
Criterion 25
%
Attendance
Criterion 21
%
Education
Criteria 22, 24
%
Daily Evaluation (Overall)
Criterion 27
%
≥ 90% → 4 (Exceeds) ≥ 70% → 3 (Meets) ≥ 50% → 2 (Borderline) < 50% → 1 (Does Not Meet)
PDF ITER Auto-Fill
Upload an ITER PDF form, pick a rating + default comment, and download the filled version
Drop PDF here or click to browse
Works with flat PDFs — detects rating rows automatically
Written next to the matching labels on the PDF. Leave any field blank to skip it.
Scale auto-detected from the uploaded PDF (1–5 default)
/ 10
This writes plain text in the Program Director box. You are confirming the ITER after review — the dashboard is only a calculator aid.
PDF preview will appear here after upload
Specialty ITER Templates
Build a custom ITER form per specialty. Each criterion maps to one of your 8 score domains and is auto-filled from daily evaluations or a manual domain %.
Select a template on the left to edit, or create a new one.