diff --git a/frontend/app/api/rmp/route.js b/frontend/app/api/rmp/route.js index 6139675..0df1602 100644 --- a/frontend/app/api/rmp/route.js +++ b/frontend/app/api/rmp/route.js @@ -2,21 +2,22 @@ import { RMPClient } from 'ratemyprofessors-client' import { NextResponse } from 'next/server' const CARLETON_SCHOOL_ID = '1420' -const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000 // 1 week; ratings don't change that fast +const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000 const client = new RMPClient() -const cache = new Map() // name to { data, expiresAt } +const cache = new Map() // name → { data, expiresAt } function getCached(name) { const entry = cache.get(name) if (!entry) return null - if (Date.now() > entry.expiresAt) { - cache.delete(name) - return null - } + if (Date.now() > entry.expiresAt) { cache.delete(name); return null } return entry.data } +function setCached(name, data) { + cache.set(name, { data, expiresAt: Date.now() + CACHE_TTL_MS }) +} + export async function GET(request) { const { searchParams } = new URL(request.url) const name = searchParams.get('name')?.trim() @@ -32,20 +33,41 @@ export async function GET(request) { const result = await client.searchProfessors(name, CARLETON_SCHOOL_ID) const prof = result.professors?.find(p => p.school?.id === CARLETON_SCHOOL_ID) ?? null - const data = prof - ? { - found: true, - name: prof.name, - department: prof.department, - overall_rating: prof.overall_rating, - difficulty: prof.level_of_difficulty, - num_ratings: prof.num_ratings, - would_take_again: prof.percent_take_again >= 0 ? Math.round(prof.percent_take_again) : null, - rmp_url: `https://www.ratemyprofessors.com/professor/${prof.id}`, - } - : { found: false } - - cache.set(name, { data, expiresAt: Date.now() + CACHE_TTL_MS }) + if (!prof) { + const data = { found: false } + setCached(name, data) + return NextResponse.json(data) + } + + // Fetch up to 5 recent ratings + let ratings = [] + try { + const page = await client.getProfessorRatingsPage(prof.id) + ratings = (page.ratings ?? []).slice(0, 5).map(r => ({ + date: r.date, + comment: r.comment, + quality: r.quality, + difficulty: r.difficulty, + course: r.course_raw ?? null, + tags: r.tags ?? [], + })) + } catch { + // ratings are a bonus; don't fail the whole request + } + + const data = { + found: true, + name: prof.name, + department: prof.department, + overall_rating: prof.overall_rating, + difficulty: prof.level_of_difficulty, + num_ratings: prof.num_ratings, + would_take_again: prof.percent_take_again >= 0 ? Math.round(prof.percent_take_again) : null, + rmp_url: `https://www.ratemyprofessors.com/professor/${prof.id}`, + ratings, + } + + setCached(name, data) return NextResponse.json(data) } catch (err) { console.error('RMP lookup failed for', name, err) diff --git a/frontend/app/map/components/CoursePanel.jsx b/frontend/app/map/components/CoursePanel.jsx index 998fdbc..eb6fef9 100644 --- a/frontend/app/map/components/CoursePanel.jsx +++ b/frontend/app/map/components/CoursePanel.jsx @@ -255,7 +255,7 @@ export const CoursePanel = ({ node, onClose, isMobile }) => { {group.term} {group.instructors.map(({ name: profName, rmp }) => ( - + ))} ))} @@ -267,9 +267,15 @@ export const CoursePanel = ({ node, onClose, isMobile }) => { ) } -const ProfCard = ({ name, rmp }) => { +const ProfCard = ({ name, rmp, courseCode }) => { const [showReviews, setShowReviews] = useState(false) - const reviews = rmp?.ratings ?? [] + const allReviews = rmp?.ratings ?? [] + const normalise = s => s?.toLowerCase().replace(/\s+/g, '') ?? '' + const courseKey = normalise(courseCode) + const courseReviews = courseKey + ? allReviews.filter(r => normalise(r.course).includes(courseKey) || courseKey.includes(normalise(r.course).slice(0, 6))) + : [] + const reviews = courseReviews.slice(0, 5) return (
{ fontFamily: 'var(--font-body)', }} > - {showReviews ? 'Hide reviews' : `Show ${reviews.length} recent review${reviews.length !== 1 ? 's' : ''}`} + {showReviews ? 'Hide reviews' : `Show ${reviews.length} review${reviews.length !== 1 ? 's' : ''}`} {showReviews && (