diff --git a/data/competitions.schema.json b/data/competitions.schema.json index e23052b..717e953 100644 --- a/data/competitions.schema.json +++ b/data/competitions.schema.json @@ -115,6 +115,11 @@ "type": "string", "pattern": "^https://" }, + "image": { + "type": "string", + "pattern": "^(https?://|/)", + "description": "Optional localized logo or banner for the competition card, e.g. \"/competitions/regeneron-isef.png\"" + }, "cycle_year": { "type": "integer", "minimum": 2020, diff --git a/data/competitions/arts_design.json b/data/competitions/arts_design.json index 27bdcc6..793b4d9 100644 --- a/data/competitions/arts_design.json +++ b/data/competitions/arts_design.json @@ -45,7 +45,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-12-01" + "valid_till": "2026-12-01", + "image": "/competitions/bow-seat-ocean-awareness-contest.png" }, { "id": "doodle-for-google", @@ -106,7 +107,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/doodle-for-google.png" }, { "id": "scholastic-art-and-writing-awards", @@ -176,7 +178,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/scholastic-art-and-writing-awards.png" }, { "id": "toyota-dream-car-art-contest", @@ -254,7 +257,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-01" + "valid_till": "2027-03-01", + "image": "/competitions/toyota-dream-car-art-contest.png" }, { "id": "youngarts-national-arts-competition", @@ -295,7 +299,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-12-01" + "valid_till": "2026-12-01", + "image": "/competitions/youngarts-national-arts-competition.png" }, { "id": "congressional-art-competition", @@ -334,6 +339,7 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/congressional-art-competition.png" } ] diff --git a/data/competitions/business.json b/data/competitions/business.json index 4f8d7da..80596fa 100644 --- a/data/competitions/business.json +++ b/data/competitions/business.json @@ -37,7 +37,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-02-01" + "valid_till": "2027-02-01", + "image": "/competitions/conrad-challenge.png" }, { "id": "deca-icdc", @@ -101,7 +102,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/deca-icdc.png" }, { "id": "diamond-challenge", @@ -140,7 +142,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-01" + "valid_till": "2027-03-01", + "image": "/competitions/diamond-challenge.png" }, { "id": "nfte-world-series-of-innovation", @@ -188,7 +191,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/nfte-world-series-of-innovation.png" }, { "id": "fbla-national-leadership-conference", @@ -229,7 +233,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-07-01" + "valid_till": "2027-07-01", + "image": "/competitions/fbla-national-leadership-conference.png" }, { "id": "bpa-national-leadership-conference", @@ -270,7 +275,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-06-01" + "valid_till": "2027-06-01", + "image": "/competitions/bpa-national-leadership-conference.png" }, { "id": "ja-company-of-the-year", @@ -318,6 +324,7 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2026-12-01" + "valid_till": "2026-12-01", + "image": "/competitions/ja-company-of-the-year.png" } ] diff --git a/data/competitions/coding.json b/data/competitions/coding.json index 8f8e7bf..c9323e4 100644 --- a/data/competitions/coding.json +++ b/data/competitions/coding.json @@ -58,7 +58,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-02-01" + "valid_till": "2027-02-01", + "image": "/competitions/cyberpatriot.png" }, { "id": "international-olympiad-in-informatics", @@ -164,7 +165,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-05" + "valid_till": "2027-03-05", + "image": "/competitions/international-olympiad-in-informatics.png" }, { "id": "meta-hacker-cup", @@ -212,7 +214,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/meta-hacker-cup.png" }, { "id": "picoctf", @@ -252,6 +255,7 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-04-01" + "valid_till": "2027-04-01", + "image": "/competitions/picoctf.png" } ] diff --git a/data/competitions/creative_writing.json b/data/competitions/creative_writing.json index 32f213b..ac9caed 100644 --- a/data/competitions/creative_writing.json +++ b/data/competitions/creative_writing.json @@ -44,7 +44,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-11-01" + "valid_till": "2026-11-01", + "image": "/competitions/foyle-young-poets-of-the-year-award.png" }, { "id": "rattle-poetry-prize", @@ -91,7 +92,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-10-01" + "valid_till": "2026-10-01", + "image": "/competitions/rattle-poetry-prize.png" }, { "id": "river-of-words", @@ -131,6 +133,7 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-04-01" + "valid_till": "2027-04-01", + "image": "/competitions/river-of-words.png" } ] diff --git a/data/competitions/debate_mun.json b/data/competitions/debate_mun.json index ceaaff9..df35fea 100644 --- a/data/competitions/debate_mun.json +++ b/data/competitions/debate_mun.json @@ -45,7 +45,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-01" + "valid_till": "2027-03-01", + "image": "/competitions/harvard-model-united-nations.png" }, { "id": "nsda-national-tournament", @@ -93,7 +94,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-07-01" + "valid_till": "2027-07-01", + "image": "/competitions/nsda-national-tournament.png" }, { "id": "world-scholars-cup", @@ -160,6 +162,7 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-06-01" + "valid_till": "2027-06-01", + "image": "/competitions/world-scholars-cup.png" } ] diff --git a/data/competitions/essay_writing.json b/data/competitions/essay_writing.json index a13f7d4..9ee87f1 100644 --- a/data/competitions/essay_writing.json +++ b/data/competitions/essay_writing.json @@ -53,7 +53,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-10-15" + "valid_till": "2026-10-15", + "image": "/competitions/harvard-crimson-global-essay-competition.png" }, { "id": "jfk-profile-in-courage-essay-contest", @@ -93,7 +94,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-02-01" + "valid_till": "2027-02-01", + "image": "/competitions/jfk-profile-in-courage-essay-contest.png" }, { "id": "john-locke-global-essay-prize", @@ -159,7 +161,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-11-01" + "valid_till": "2026-11-01", + "image": "/competitions/john-locke-global-essay-prize.png" }, { "id": "the-politic-high-school-essay-competition", @@ -215,7 +218,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-10-01" + "valid_till": "2026-10-01", + "image": "/competitions/the-politic-high-school-essay-competition.png" }, { "id": "ayn-rand-institute-essay-contests", @@ -271,7 +275,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-01-15" + "valid_till": "2027-01-15", + "image": "/competitions/ayn-rand-institute-essay-contests.png" }, { "id": "princeton-prize-in-race-relations", @@ -311,7 +316,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-02-01" + "valid_till": "2027-02-01", + "image": "/competitions/princeton-prize-in-race-relations.png" }, { "id": "signet-classics-student-scholarship-essay-contest", @@ -350,6 +356,7 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-05-15" + "valid_till": "2027-05-15", + "image": "/competitions/signet-classics-student-scholarship-essay-contest.png" } ] diff --git a/data/competitions/film_video.json b/data/competitions/film_video.json index d19b36a..a1928e1 100644 --- a/data/competitions/film_video.json +++ b/data/competitions/film_video.json @@ -37,6 +37,7 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-08-01" + "valid_till": "2027-08-01", + "image": "/competitions/all-american-high-school-film-festival.png" } ] diff --git a/data/competitions/finance.json b/data/competitions/finance.json index ddf45f9..307b158 100644 --- a/data/competitions/finance.json +++ b/data/competitions/finance.json @@ -36,7 +36,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-06-01" + "valid_till": "2027-06-01", + "image": "/competitions/national-personal-finance-challenge.png" }, { "id": "new-york-fed-s-high-school-economics-essay", @@ -76,7 +77,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/new-york-fed-s-high-school-economics-essay.png" }, { "id": "wharton-global-high-school-investment-competition", @@ -116,7 +118,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/wharton-global-high-school-investment-competition.png" }, { "id": "wharton-high-school-data-science-competition", @@ -156,7 +159,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/wharton-high-school-data-science-competition.png" }, { "id": "national-economics-challenge", @@ -203,7 +207,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-01-15" + "valid_till": "2027-01-15", + "image": "/competitions/national-economics-challenge.png" }, { "id": "stock-market-game", @@ -243,6 +248,7 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2026-12-01" + "valid_till": "2026-12-01", + "image": "/competitions/stock-market-game.png" } ] diff --git a/data/competitions/history.json b/data/competitions/history.json index 3ab9417..fddf4c0 100644 --- a/data/competitions/history.json +++ b/data/competitions/history.json @@ -45,7 +45,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/concord-review.png" }, { "id": "national-history-bowl", @@ -92,7 +93,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/national-history-bowl.png" }, { "id": "national-history-day", @@ -158,7 +160,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-07-01" + "valid_till": "2027-07-01", + "image": "/competitions/national-history-day.png" }, { "id": "national-history-bee", @@ -197,7 +200,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-05-15" + "valid_till": "2027-05-15", + "image": "/competitions/national-history-bee.png" }, { "id": "we-the-students-essay-contest", @@ -237,6 +241,7 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-05-15" + "valid_till": "2027-05-15", + "image": "/competitions/we-the-students-essay-contest.png" } ] diff --git a/data/competitions/humanities.json b/data/competitions/humanities.json index de25939..0d6c1c0 100644 --- a/data/competitions/humanities.json +++ b/data/competitions/humanities.json @@ -75,7 +75,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-08-01" + "valid_till": "2027-08-01", + "image": "/competitions/international-linguistics-olympiad.png" }, { "id": "national-latin-exam", @@ -123,6 +124,7 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-04-01" + "valid_till": "2027-04-01", + "image": "/competitions/national-latin-exam.png" } ] diff --git a/data/competitions/interdisciplinary.json b/data/competitions/interdisciplinary.json index 603d8d4..db605db 100644 --- a/data/competitions/interdisciplinary.json +++ b/data/competitions/interdisciplinary.json @@ -73,7 +73,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/first-robotics-competition.png" }, { "id": "technovation-girls", @@ -128,7 +129,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-06-01" + "valid_till": "2027-06-01", + "image": "/competitions/technovation-girls.png" }, { "id": "envirothon", @@ -169,7 +171,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-08-01" + "valid_till": "2027-08-01", + "image": "/competitions/envirothon.png" }, { "id": "ecybermission", @@ -211,7 +214,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-03-15" + "valid_till": "2027-03-15", + "image": "/competitions/ecybermission.png" }, { "id": "first-tech-challenge", @@ -260,7 +264,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/first-tech-challenge.png" }, { "id": "igem-high-school", @@ -301,7 +306,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-07-01" + "valid_till": "2027-07-01", + "image": "/competitions/igem-high-school.png" }, { "id": "first-global-challenge", @@ -350,7 +356,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/first-global-challenge.png" }, { "id": "nasa-space-apps-challenge", @@ -416,6 +423,7 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/nasa-space-apps-challenge.png" } ] diff --git a/data/competitions/mathematics.json b/data/competitions/mathematics.json index 8b95a22..ce6e7d4 100644 --- a/data/competitions/mathematics.json +++ b/data/competitions/mathematics.json @@ -52,7 +52,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-01" + "valid_till": "2027-03-01", + "image": "/competitions/hmmt.png" }, { "id": "international-mathematical-olympiad", @@ -146,7 +147,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-05" + "valid_till": "2027-03-05", + "image": "/competitions/international-mathematical-olympiad.png" }, { "id": "math-prize-for-girls", @@ -185,7 +187,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-11-01" + "valid_till": "2026-11-01", + "image": "/competitions/math-prize-for-girls.png" }, { "id": "usamo", @@ -225,7 +228,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-04-01" + "valid_till": "2027-04-01", + "image": "/competitions/usamo.png" }, { "id": "arml", @@ -272,7 +276,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2026-12-01" + "valid_till": "2026-12-01", + "image": "/competitions/arml.png" }, { "id": "mathcounts", @@ -327,7 +332,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-06-01" + "valid_till": "2027-06-01", + "image": "/competitions/mathcounts.png" }, { "id": "purple-comet-math-meet", @@ -374,7 +380,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/purple-comet-math-meet.png" }, { "id": "tournament-of-the-towns", @@ -422,6 +429,7 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2026-11-15" + "valid_till": "2026-11-15", + "image": "/competitions/tournament-of-the-towns.png" } ] diff --git a/data/competitions/research.json b/data/competitions/research.json index da30d9a..fabb906 100644 --- a/data/competitions/research.json +++ b/data/competitions/research.json @@ -39,6 +39,7 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/regeneron-science-talent-search.png" } ] diff --git a/data/competitions/scholarship.json b/data/competitions/scholarship.json index d219a6c..b2db642 100644 --- a/data/competitions/scholarship.json +++ b/data/competitions/scholarship.json @@ -41,6 +41,7 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-01" + "valid_till": "2027-03-01", + "image": "/competitions/davidson-fellows-scholarship.png" } ] diff --git a/data/competitions/stem.json b/data/competitions/stem.json index be2cd26..5beabbe 100644 --- a/data/competitions/stem.json +++ b/data/competitions/stem.json @@ -52,7 +52,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-01-15" + "valid_till": "2027-01-15", + "image": "/competitions/ijso.png" }, { "id": "international-biology-olympiad", @@ -145,7 +146,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-05" + "valid_till": "2027-03-05", + "image": "/competitions/international-biology-olympiad.png" }, { "id": "international-brain-bee", @@ -207,7 +209,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-05-01" + "valid_till": "2027-05-01", + "image": "/competitions/international-brain-bee.png" }, { "id": "international-chemistry-olympiad", @@ -288,7 +291,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-05" + "valid_till": "2027-03-05", + "image": "/competitions/international-chemistry-olympiad.png" }, { "id": "international-physics-olympiad", @@ -381,7 +385,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-03-05" + "valid_till": "2027-03-05", + "image": "/competitions/international-physics-olympiad.png" }, { "id": "ioaa", @@ -444,7 +449,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2026-12-01" + "valid_till": "2026-12-01", + "image": "/competitions/ioaa.png" }, { "id": "regeneron-isef", @@ -515,7 +521,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-06-01" + "valid_till": "2027-06-01", + "image": "/competitions/regeneron-isef.png" }, { "id": "science-olympiad", @@ -563,7 +570,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-06-01" + "valid_till": "2027-06-01", + "image": "/competitions/science-olympiad.png" }, { "id": "world-robot-olympiad", @@ -626,7 +634,8 @@ "by": "yashkewlani", "on": "2026-09-05" }, - "valid_till": "2027-01-01" + "valid_till": "2027-01-01", + "image": "/competitions/world-robot-olympiad.png" }, { "id": "international-earth-science-olympiad", @@ -675,7 +684,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-02-01" + "valid_till": "2027-02-01", + "image": "/competitions/international-earth-science-olympiad.png" }, { "id": "international-olympiad-in-ai", @@ -716,7 +726,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-01-15" + "valid_till": "2027-01-15", + "image": "/competitions/international-olympiad-in-ai.png" }, { "id": "european-physics-olympiad", @@ -763,7 +774,8 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2026-12-01" + "valid_till": "2026-12-01", + "image": "/competitions/european-physics-olympiad.png" }, { "id": "international-biogeneius-challenge", @@ -804,6 +816,7 @@ "by": "yashkewlani", "on": "2026-09-06" }, - "valid_till": "2027-03-01" + "valid_till": "2027-03-01", + "image": "/competitions/international-biogeneius-challenge.png" } ] diff --git a/public/competitions/all-american-high-school-film-festival.png b/public/competitions/all-american-high-school-film-festival.png new file mode 100644 index 0000000..1b37af6 Binary files /dev/null and b/public/competitions/all-american-high-school-film-festival.png differ diff --git a/public/competitions/arml.png b/public/competitions/arml.png new file mode 100644 index 0000000..b018b02 Binary files /dev/null and b/public/competitions/arml.png differ diff --git a/public/competitions/ayn-rand-institute-essay-contests.png b/public/competitions/ayn-rand-institute-essay-contests.png new file mode 100644 index 0000000..1a2c15c Binary files /dev/null and b/public/competitions/ayn-rand-institute-essay-contests.png differ diff --git a/public/competitions/bow-seat-ocean-awareness-contest.png b/public/competitions/bow-seat-ocean-awareness-contest.png new file mode 100644 index 0000000..86aa249 Binary files /dev/null and b/public/competitions/bow-seat-ocean-awareness-contest.png differ diff --git a/public/competitions/bpa-national-leadership-conference.png b/public/competitions/bpa-national-leadership-conference.png new file mode 100644 index 0000000..70b213b Binary files /dev/null and b/public/competitions/bpa-national-leadership-conference.png differ diff --git a/public/competitions/concord-review.png b/public/competitions/concord-review.png new file mode 100644 index 0000000..de5b0f0 Binary files /dev/null and b/public/competitions/concord-review.png differ diff --git a/public/competitions/congressional-art-competition.png b/public/competitions/congressional-art-competition.png new file mode 100644 index 0000000..783c1ae Binary files /dev/null and b/public/competitions/congressional-art-competition.png differ diff --git a/public/competitions/conrad-challenge.png b/public/competitions/conrad-challenge.png new file mode 100644 index 0000000..1406abf Binary files /dev/null and b/public/competitions/conrad-challenge.png differ diff --git a/public/competitions/cyberpatriot.png b/public/competitions/cyberpatriot.png new file mode 100644 index 0000000..768eb4e Binary files /dev/null and b/public/competitions/cyberpatriot.png differ diff --git a/public/competitions/davidson-fellows-scholarship.png b/public/competitions/davidson-fellows-scholarship.png new file mode 100644 index 0000000..c0cffa2 Binary files /dev/null and b/public/competitions/davidson-fellows-scholarship.png differ diff --git a/public/competitions/deca-icdc.png b/public/competitions/deca-icdc.png new file mode 100644 index 0000000..bed2655 Binary files /dev/null and b/public/competitions/deca-icdc.png differ diff --git a/public/competitions/diamond-challenge.png b/public/competitions/diamond-challenge.png new file mode 100644 index 0000000..f992be9 Binary files /dev/null and b/public/competitions/diamond-challenge.png differ diff --git a/public/competitions/doodle-for-google.png b/public/competitions/doodle-for-google.png new file mode 100644 index 0000000..b018b02 Binary files /dev/null and b/public/competitions/doodle-for-google.png differ diff --git a/public/competitions/ecybermission.png b/public/competitions/ecybermission.png new file mode 100644 index 0000000..ed988e3 Binary files /dev/null and b/public/competitions/ecybermission.png differ diff --git a/public/competitions/envirothon.png b/public/competitions/envirothon.png new file mode 100644 index 0000000..2d8e23a Binary files /dev/null and b/public/competitions/envirothon.png differ diff --git a/public/competitions/european-physics-olympiad.png b/public/competitions/european-physics-olympiad.png new file mode 100644 index 0000000..a62521a Binary files /dev/null and b/public/competitions/european-physics-olympiad.png differ diff --git a/public/competitions/fbla-national-leadership-conference.png b/public/competitions/fbla-national-leadership-conference.png new file mode 100644 index 0000000..3aebfd3 Binary files /dev/null and b/public/competitions/fbla-national-leadership-conference.png differ diff --git a/public/competitions/first-global-challenge.png b/public/competitions/first-global-challenge.png new file mode 100644 index 0000000..b5d0763 Binary files /dev/null and b/public/competitions/first-global-challenge.png differ diff --git a/public/competitions/first-robotics-competition.png b/public/competitions/first-robotics-competition.png new file mode 100644 index 0000000..1f94296 Binary files /dev/null and b/public/competitions/first-robotics-competition.png differ diff --git a/public/competitions/first-tech-challenge.png b/public/competitions/first-tech-challenge.png new file mode 100644 index 0000000..1f94296 Binary files /dev/null and b/public/competitions/first-tech-challenge.png differ diff --git a/public/competitions/foyle-young-poets-of-the-year-award.png b/public/competitions/foyle-young-poets-of-the-year-award.png new file mode 100644 index 0000000..a73e441 Binary files /dev/null and b/public/competitions/foyle-young-poets-of-the-year-award.png differ diff --git a/public/competitions/harvard-crimson-global-essay-competition.png b/public/competitions/harvard-crimson-global-essay-competition.png new file mode 100644 index 0000000..b763e4a Binary files /dev/null and b/public/competitions/harvard-crimson-global-essay-competition.png differ diff --git a/public/competitions/harvard-model-united-nations.png b/public/competitions/harvard-model-united-nations.png new file mode 100644 index 0000000..fcaa451 Binary files /dev/null and b/public/competitions/harvard-model-united-nations.png differ diff --git a/public/competitions/hmmt.png b/public/competitions/hmmt.png new file mode 100644 index 0000000..df44530 Binary files /dev/null and b/public/competitions/hmmt.png differ diff --git a/public/competitions/igem-high-school.png b/public/competitions/igem-high-school.png new file mode 100644 index 0000000..0014857 Binary files /dev/null and b/public/competitions/igem-high-school.png differ diff --git a/public/competitions/ijso.png b/public/competitions/ijso.png new file mode 100644 index 0000000..31a3f34 Binary files /dev/null and b/public/competitions/ijso.png differ diff --git a/public/competitions/international-biogeneius-challenge.png b/public/competitions/international-biogeneius-challenge.png new file mode 100644 index 0000000..9c8e073 Binary files /dev/null and b/public/competitions/international-biogeneius-challenge.png differ diff --git a/public/competitions/international-biology-olympiad.png b/public/competitions/international-biology-olympiad.png new file mode 100644 index 0000000..f0e6a42 Binary files /dev/null and b/public/competitions/international-biology-olympiad.png differ diff --git a/public/competitions/international-brain-bee.png b/public/competitions/international-brain-bee.png new file mode 100644 index 0000000..d4bf6ce Binary files /dev/null and b/public/competitions/international-brain-bee.png differ diff --git a/public/competitions/international-chemistry-olympiad.png b/public/competitions/international-chemistry-olympiad.png new file mode 100644 index 0000000..06a8db3 Binary files /dev/null and b/public/competitions/international-chemistry-olympiad.png differ diff --git a/public/competitions/international-earth-science-olympiad.png b/public/competitions/international-earth-science-olympiad.png new file mode 100644 index 0000000..b018b02 Binary files /dev/null and b/public/competitions/international-earth-science-olympiad.png differ diff --git a/public/competitions/international-linguistics-olympiad.png b/public/competitions/international-linguistics-olympiad.png new file mode 100644 index 0000000..8a40f3e Binary files /dev/null and b/public/competitions/international-linguistics-olympiad.png differ diff --git a/public/competitions/international-mathematical-olympiad.png b/public/competitions/international-mathematical-olympiad.png new file mode 100644 index 0000000..b9dcb25 Binary files /dev/null and b/public/competitions/international-mathematical-olympiad.png differ diff --git a/public/competitions/international-olympiad-in-ai.png b/public/competitions/international-olympiad-in-ai.png new file mode 100644 index 0000000..cf8de7d Binary files /dev/null and b/public/competitions/international-olympiad-in-ai.png differ diff --git a/public/competitions/international-olympiad-in-informatics.png b/public/competitions/international-olympiad-in-informatics.png new file mode 100644 index 0000000..b018b02 Binary files /dev/null and b/public/competitions/international-olympiad-in-informatics.png differ diff --git a/public/competitions/international-physics-olympiad.png b/public/competitions/international-physics-olympiad.png new file mode 100644 index 0000000..5c7da9b Binary files /dev/null and b/public/competitions/international-physics-olympiad.png differ diff --git a/public/competitions/ioaa.png b/public/competitions/ioaa.png new file mode 100644 index 0000000..240d676 Binary files /dev/null and b/public/competitions/ioaa.png differ diff --git a/public/competitions/ja-company-of-the-year.png b/public/competitions/ja-company-of-the-year.png new file mode 100644 index 0000000..d67debd Binary files /dev/null and b/public/competitions/ja-company-of-the-year.png differ diff --git a/public/competitions/jfk-profile-in-courage-essay-contest.png b/public/competitions/jfk-profile-in-courage-essay-contest.png new file mode 100644 index 0000000..57a95eb Binary files /dev/null and b/public/competitions/jfk-profile-in-courage-essay-contest.png differ diff --git a/public/competitions/john-locke-global-essay-prize.png b/public/competitions/john-locke-global-essay-prize.png new file mode 100644 index 0000000..9553b81 Binary files /dev/null and b/public/competitions/john-locke-global-essay-prize.png differ diff --git a/public/competitions/math-prize-for-girls.png b/public/competitions/math-prize-for-girls.png new file mode 100644 index 0000000..a0823f8 Binary files /dev/null and b/public/competitions/math-prize-for-girls.png differ diff --git a/public/competitions/mathcounts.png b/public/competitions/mathcounts.png new file mode 100644 index 0000000..d92726e Binary files /dev/null and b/public/competitions/mathcounts.png differ diff --git a/public/competitions/meta-hacker-cup.png b/public/competitions/meta-hacker-cup.png new file mode 100644 index 0000000..58bfd8c Binary files /dev/null and b/public/competitions/meta-hacker-cup.png differ diff --git a/public/competitions/nasa-space-apps-challenge.png b/public/competitions/nasa-space-apps-challenge.png new file mode 100644 index 0000000..4489479 Binary files /dev/null and b/public/competitions/nasa-space-apps-challenge.png differ diff --git a/public/competitions/national-economics-challenge.png b/public/competitions/national-economics-challenge.png new file mode 100644 index 0000000..65a6823 Binary files /dev/null and b/public/competitions/national-economics-challenge.png differ diff --git a/public/competitions/national-history-bee.png b/public/competitions/national-history-bee.png new file mode 100644 index 0000000..c329f2c Binary files /dev/null and b/public/competitions/national-history-bee.png differ diff --git a/public/competitions/national-history-bowl.png b/public/competitions/national-history-bowl.png new file mode 100644 index 0000000..c329f2c Binary files /dev/null and b/public/competitions/national-history-bowl.png differ diff --git a/public/competitions/national-history-day.png b/public/competitions/national-history-day.png new file mode 100644 index 0000000..6a2391c Binary files /dev/null and b/public/competitions/national-history-day.png differ diff --git a/public/competitions/national-latin-exam.png b/public/competitions/national-latin-exam.png new file mode 100644 index 0000000..624b4af Binary files /dev/null and b/public/competitions/national-latin-exam.png differ diff --git a/public/competitions/national-personal-finance-challenge.png b/public/competitions/national-personal-finance-challenge.png new file mode 100644 index 0000000..65a6823 Binary files /dev/null and b/public/competitions/national-personal-finance-challenge.png differ diff --git a/public/competitions/new-york-fed-s-high-school-economics-essay.png b/public/competitions/new-york-fed-s-high-school-economics-essay.png new file mode 100644 index 0000000..c8a9bd4 Binary files /dev/null and b/public/competitions/new-york-fed-s-high-school-economics-essay.png differ diff --git a/public/competitions/nfte-world-series-of-innovation.png b/public/competitions/nfte-world-series-of-innovation.png new file mode 100644 index 0000000..3467e0b Binary files /dev/null and b/public/competitions/nfte-world-series-of-innovation.png differ diff --git a/public/competitions/nsda-national-tournament.png b/public/competitions/nsda-national-tournament.png new file mode 100644 index 0000000..e2464b4 Binary files /dev/null and b/public/competitions/nsda-national-tournament.png differ diff --git a/public/competitions/picoctf.png b/public/competitions/picoctf.png new file mode 100644 index 0000000..b018b02 Binary files /dev/null and b/public/competitions/picoctf.png differ diff --git a/public/competitions/princeton-prize-in-race-relations.png b/public/competitions/princeton-prize-in-race-relations.png new file mode 100644 index 0000000..451af59 Binary files /dev/null and b/public/competitions/princeton-prize-in-race-relations.png differ diff --git a/public/competitions/purple-comet-math-meet.png b/public/competitions/purple-comet-math-meet.png new file mode 100644 index 0000000..4b6b458 Binary files /dev/null and b/public/competitions/purple-comet-math-meet.png differ diff --git a/public/competitions/rattle-poetry-prize.png b/public/competitions/rattle-poetry-prize.png new file mode 100644 index 0000000..40faff2 Binary files /dev/null and b/public/competitions/rattle-poetry-prize.png differ diff --git a/public/competitions/regeneron-isef.png b/public/competitions/regeneron-isef.png new file mode 100644 index 0000000..5ecee48 Binary files /dev/null and b/public/competitions/regeneron-isef.png differ diff --git a/public/competitions/regeneron-science-talent-search.png b/public/competitions/regeneron-science-talent-search.png new file mode 100644 index 0000000..5ecee48 Binary files /dev/null and b/public/competitions/regeneron-science-talent-search.png differ diff --git a/public/competitions/river-of-words.png b/public/competitions/river-of-words.png new file mode 100644 index 0000000..92a64d7 Binary files /dev/null and b/public/competitions/river-of-words.png differ diff --git a/public/competitions/scholastic-art-and-writing-awards.png b/public/competitions/scholastic-art-and-writing-awards.png new file mode 100644 index 0000000..d287dd8 Binary files /dev/null and b/public/competitions/scholastic-art-and-writing-awards.png differ diff --git a/public/competitions/science-olympiad.png b/public/competitions/science-olympiad.png new file mode 100644 index 0000000..47c2b6b Binary files /dev/null and b/public/competitions/science-olympiad.png differ diff --git a/public/competitions/signet-classics-student-scholarship-essay-contest.png b/public/competitions/signet-classics-student-scholarship-essay-contest.png new file mode 100644 index 0000000..5d52190 Binary files /dev/null and b/public/competitions/signet-classics-student-scholarship-essay-contest.png differ diff --git a/public/competitions/stock-market-game.png b/public/competitions/stock-market-game.png new file mode 100644 index 0000000..a33daa6 Binary files /dev/null and b/public/competitions/stock-market-game.png differ diff --git a/public/competitions/technovation-girls.png b/public/competitions/technovation-girls.png new file mode 100644 index 0000000..6e09423 Binary files /dev/null and b/public/competitions/technovation-girls.png differ diff --git a/public/competitions/the-politic-high-school-essay-competition.png b/public/competitions/the-politic-high-school-essay-competition.png new file mode 100644 index 0000000..cca4414 Binary files /dev/null and b/public/competitions/the-politic-high-school-essay-competition.png differ diff --git a/public/competitions/tournament-of-the-towns.png b/public/competitions/tournament-of-the-towns.png new file mode 100644 index 0000000..73f3634 Binary files /dev/null and b/public/competitions/tournament-of-the-towns.png differ diff --git a/public/competitions/toyota-dream-car-art-contest.png b/public/competitions/toyota-dream-car-art-contest.png new file mode 100644 index 0000000..57a3637 Binary files /dev/null and b/public/competitions/toyota-dream-car-art-contest.png differ diff --git a/public/competitions/usamo.png b/public/competitions/usamo.png new file mode 100644 index 0000000..6d5cd37 Binary files /dev/null and b/public/competitions/usamo.png differ diff --git a/public/competitions/we-the-students-essay-contest.png b/public/competitions/we-the-students-essay-contest.png new file mode 100644 index 0000000..4da03dc Binary files /dev/null and b/public/competitions/we-the-students-essay-contest.png differ diff --git a/public/competitions/wharton-global-high-school-investment-competition.png b/public/competitions/wharton-global-high-school-investment-competition.png new file mode 100644 index 0000000..f640ce0 Binary files /dev/null and b/public/competitions/wharton-global-high-school-investment-competition.png differ diff --git a/public/competitions/wharton-high-school-data-science-competition.png b/public/competitions/wharton-high-school-data-science-competition.png new file mode 100644 index 0000000..f640ce0 Binary files /dev/null and b/public/competitions/wharton-high-school-data-science-competition.png differ diff --git a/public/competitions/world-robot-olympiad.png b/public/competitions/world-robot-olympiad.png new file mode 100644 index 0000000..96295ea Binary files /dev/null and b/public/competitions/world-robot-olympiad.png differ diff --git a/public/competitions/world-scholars-cup.png b/public/competitions/world-scholars-cup.png new file mode 100644 index 0000000..e155fe0 Binary files /dev/null and b/public/competitions/world-scholars-cup.png differ diff --git a/public/competitions/youngarts-national-arts-competition.png b/public/competitions/youngarts-national-arts-competition.png new file mode 100644 index 0000000..2a48ab0 Binary files /dev/null and b/public/competitions/youngarts-national-arts-competition.png differ diff --git a/src/components/competitions/competition-card.test.tsx b/src/components/competitions/competition-card.test.tsx index b69afe8..244a5b6 100644 --- a/src/components/competitions/competition-card.test.tsx +++ b/src/components/competitions/competition-card.test.tsx @@ -8,6 +8,17 @@ vi.mock("next/navigation", () => ({ usePathname: () => "/competitions", })); vi.mock("@/lib/supabase/client", () => ({ createClient: () => null })); +// next/image needs a browser image pipeline that jsdom doesn't provide, so +// swap it for a plain in the grid-image tests. +vi.mock("next/image", () => ({ + __esModule: true, + default: (props: React.ImgHTMLAttributes & { fill?: boolean }) => { + const { fill, ...rest } = props; + void fill; + // eslint-disable-next-line @next/next/no-img-element, jsx-a11y/alt-text + return ; + }, +})); import { CompetitionCard } from "@/components/competitions/competition-card"; import type { Competition } from "@/lib/types"; @@ -65,4 +76,26 @@ describe("CompetitionCard", () => { const link = screen.getByRole("link", { name: "View details" }); expect(link.getAttribute("href")).toBe("/competitions/test-competition"); }); + + it("renders the logo in grid view and links it to the official site", () => { + render( + , + ); + + const img = screen.getByRole("img", { name: "Test Competition logo" }); + expect(img.getAttribute("src")).toBe("/competitions/test-competition.png"); + const banner = img.closest("a"); + expect(banner?.getAttribute("href")).toBe("https://example.com"); + expect(banner?.getAttribute("target")).toBe("_blank"); + }); + + it("falls back to a placeholder icon in grid view when no image exists", () => { + render(); + + expect(screen.queryByRole("img", { name: /logo/ })).toBeNull(); + }); }); diff --git a/src/components/competitions/competition-card.tsx b/src/components/competitions/competition-card.tsx index 8a4044d..7a7b722 100644 --- a/src/components/competitions/competition-card.tsx +++ b/src/components/competitions/competition-card.tsx @@ -1,5 +1,6 @@ +import Image from "next/image"; import Link from "next/link"; -import { Calendar, Clock, ExternalLink, MapPin, Users } from "lucide-react"; +import { Calendar, Clock, ExternalLink, MapPin, Trophy, Users } from "lucide-react"; import { DeadlineCountdown } from "@/components/competitions/deadline-countdown"; import { SaveButton } from "@/components/competitions/save-button"; @@ -48,6 +49,34 @@ export function CompetitionCard({ isGrid ? "h-full p-4" : "p-4 sm:p-5", )} > + {/* Grid banner: logo in the top half, links out to the official site */} + {isGrid && ( + + {competition.image ? ( + {`${competition.name} + ) : ( + + + )} + + )} + {/* Header: name, organizer, category */}
diff --git a/src/lib/types.ts b/src/lib/types.ts index c6ef6a9..da563b2 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -200,6 +200,8 @@ export interface Competition { fee: CompetitionFee; prize: string; official_url: string; + /** Optional localized logo or banner for the competition card, e.g. "/competitions/regeneron-isef.png". */ + image?: string; cycle_year: number; dates: CompetitionDateEntry[]; /** Optional. Only present when a real national qualifying pathway exists. */