2025 Aurora Website Update#109
Conversation
…ut us section with new content and image
…and update documentation with 2025 project report links
ChrisYx511
left a comment
There was a problem hiding this comment.
some points, did not review content, will leave this to Luca
There was a problem hiding this comment.
Why don't we just upload these to Flickr instead of temp.
There was a problem hiding this comment.
Yes, I asked Alexis before. He mentioned that will be uploaded much later. So instead we will use temp folder for website update in early stage, later after they process all the photos. We can switch to Flicker.
There was a problem hiding this comment.
See above for comment for temp folder.
WalkthroughAdds a lightbox/modal for Photo clicks in Gallery, updates Home content/assets and styles, introduces an Aurora rocket page and route, adds Aurora to the Rockets grid, and includes a README for temporary images. No exported API signature changes except adding the Aurora component. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant P as Photo (Gallery)
participant D as Document
participant O as Overlay <div>
participant I as <img>
U->>P: Click or Enter
P->>D: createElement('div') as overlay
P->>D: createElement('img') with src/alt
P->>O: Append I
P->>D: Append O to body
Note over O: Full-screen, semi-transparent background<br/>img max 90% viewport
U->>O: Click overlay
O->>D: Remove overlay from body
sequenceDiagram
autonumber
participant U as User
participant R as Router
participant Pg as Page
participant A as Aurora
U->>R: Navigate to /rockets/aurora
R->>Pg: Render Page(title="Aurora")
Pg->>A: Render Aurora component
A-->>U: Static content (specs, details, galleries)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/routes/Home.jsx (1)
69-72: Broken alt text and ignored style on Photo.Photo expects altText and doesn’t consume style; current alt is dropped, harming a11y. Wrap to keep rounding and pass altText.
-<Photo link={aboutUsImage1} alt="About Us 1" style={{ borderRadius: '70%' }} /> +<div style={{ borderRadius: '70%', overflow: 'hidden' }}> + <Photo link={aboutUsImage1} altText="About Us 1" /> +</div>
♻️ Duplicate comments (1)
src/img/temp/README.md (1)
1-3: Clarify retention policy and guard against accidental commits to temp/Add an explicit time-bound policy and a pointer to delete-or-block local images on merge. Also add a folder-scoped .gitignore to only allow README.md.
Apply within this file:
### Temporary Image Storage -This folder temporarily stores images that have not yet been uploaded to Flickr. Once the images are uploaded, update the website to use the Flickr links and remove these local files. +This folder temporarily stores images that have not yet been uploaded to Flickr. Once uploaded to Flickr, update the website to use Flickr links and remove these local files. + +Retention: do not keep images here beyond the duration of a PR. On merge to master, there should be no images left in this folder. +Note: large binaries bloat the repo; prefer Flickr links and remove local copies as soon as possible.New file suggestion (outside this hunk):
# src/img/temp/.gitignore # Block everything except the README * !.gitignore !README.md
🧹 Nitpick comments (10)
src/components/Gallery/Gallery.jsx (2)
49-55: Enable Space key activation and prevent page scrollSupport native button keyboard semantics.
- <div - onClick={handleClick} - onKeyDown={(e) => e.key === 'Enter' && handleClick()} + <div + onClick={handleClick} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + handleClick(); + } + }} role="button" tabIndex={0} style={{ cursor: 'pointer' }} >
18-58: Consider using a React Portal/modal instead of manual DOM manipulationReact state + a portal (or react-bootstrap’s Modal) will simplify cleanup, handle focus trapping, aria attributes, and ESC by default.
I can convert Photo to a small Portal-based lightbox or wire up react-bootstrap Modal if you prefer.
src/routes/Rockets.jsx (1)
19-132: Optional: refactor to a data-driven Rockets listReduce duplication by mapping an array of rocket metadata to RocketCard entries; easier to insert future rockets in order.
I can provide a quick refactor snippet if helpful.
src/routes/css/Home.module.css (2)
44-46: Nice containment; also round embedded videos.Add rounding to iframes so video corners match the container.
.mediaBox { ... overflow: hidden; border-radius: 6px; } + +.mediaBox iframe { + border-radius: 6px; +}
48-56: Respect reduced motion preferences.Disable hover zoom for users with prefers-reduced-motion.
.mediaBox img { width: 100%; max-width: 400px; height: auto; display: block; margin: 0 auto; transition: transform 220ms ease, box-shadow 220ms ease; transform-origin: center center; } + +@media (prefers-reduced-motion: reduce) { + .mediaBox img { + transition: none; + } +}src/index.jsx (1)
80-84: Route added correctly; consider cleaning up v6 “exact”.In React Router v6, exact is a no-op. Consider removing it (here or consistently across the file) in a follow-up.
src/routes/Home.jsx (2)
79-79: Date format consistency.Consider standardizing dates (e.g., “August 24, 2025” or “2025‑08‑24”) across the site.
118-120: Make iframe title more descriptive.“Rocket Launch” is generic. Use a descriptive title to improve a11y.
-<Video link="https://www.youtube.com/embed/vRShaLdex7Q?si=k5kqdmuP8fEYu2LC" title="Rocket Launch" /> +<Video link="https://www.youtube.com/embed/vRShaLdex7Q?si=k5kqdmuP8fEYu2LC" title="Aurora — Launch Canada 2025" />src/routes/rocketPages/Aurora.jsx (2)
43-56: Specs: consider adding metric equivalents.Adding SI alongside imperial improves clarity for a broader audience.
Example: Diameter: 8" (203 mm); Length: 16 ft (4.88 m); Wet Mass: ~253 lb (~115 kg); Apogee: ~38,000 ft (~11.6 km).
194-205: Photos: good alt texts; consider lazy-loading.Optional: add loading="lazy" to non-critical images (component-level) to improve performance.
I can update the Gallery Photo component to pass loading="lazy" and keep the modal behavior.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
public/pdfs/2025_project_report.pdfis excluded by!**/*.pdf
📒 Files selected for processing (7)
src/components/Gallery/Gallery.jsx(1 hunks)src/img/temp/README.md(1 hunks)src/index.jsx(2 hunks)src/routes/Home.jsx(4 hunks)src/routes/Rockets.jsx(2 hunks)src/routes/css/Home.module.css(1 hunks)src/routes/rocketPages/Aurora.jsx(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
src/index.jsx (2)
src/components/Page.jsx (1)
Page(5-14)src/routes/rocketPages/Aurora.jsx (1)
Aurora(16-226)
src/routes/Rockets.jsx (1)
src/components/RocketCard/RocketCard.jsx (1)
RocketCard(13-32)
src/routes/css/Home.module.css (1)
src/components/ImageBox/ImageBox.jsx (1)
div(7-15)
src/routes/rocketPages/Aurora.jsx (6)
src/components/RocketPageOutline/RocketPageOutline.jsx (1)
RocketPageOutline(8-39)src/components/Content/Content.jsx (1)
Content(6-16)src/components/SpecsComponent/SpecsComponent.jsx (1)
SpecsComponent(49-80)src/components/DividerLine/DividerLine.jsx (1)
DividerLine(6-10)src/components/TwoColumns/TwoColumns.jsx (1)
TwoColumns(6-16)src/components/Gallery/Gallery.jsx (3)
Gallery(71-96)Photo(18-59)Video(61-69)
src/routes/Home.jsx (2)
src/components/Gallery/Gallery.jsx (2)
Photo(18-59)Video(61-69)src/routes/Competition.jsx (1)
CoverPhoto(13-55)
🔇 Additional comments (8)
src/routes/Rockets.jsx (2)
6-6: Asset exists and size acceptable
aurora-2025.webp found at src/img/rocket/aurora-2025.webp (85 010 bytes), which is within acceptable limits.
24-32: LGTM: Aurora card wiring verified
Route "rockets/aurora" is registered in src/index.jsx (lines 82–84) and renders<Aurora />correctly.src/index.jsx (1)
27-27: Aurora import looks good.src/routes/Home.jsx (4)
21-21: Asset swap to Aurora image: OK.
23-23: Press image swap: OK.
50-64: Content update reads well; verify factual claims.Claims like “first-ever liquid engine rocket” (2024) and “more than doubled the Canadian altitude record” (2025) should be confirmed against current records before publishing.
95-97: Double-check event date.“Thursday, August 21st” aligns with 2025 calendars, but please verify it matches Launch Canada’s official schedule.
src/routes/rocketPages/Aurora.jsx (1)
25-38: Overview copy: fact-check key stats.Verify height, thrust, apogee, and “doubling last year’s apogee” before publishing.
| const handleClick = () => { | ||
| const modal = document.createElement('div'); | ||
| modal.style.position = 'fixed'; | ||
| modal.style.top = '0'; | ||
| modal.style.left = '0'; | ||
| modal.style.width = '100vw'; | ||
| modal.style.height = '100vh'; | ||
| modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; | ||
| modal.style.display = 'flex'; | ||
| modal.style.justifyContent = 'center'; | ||
| modal.style.alignItems = 'center'; | ||
| modal.style.zIndex = '1000'; | ||
|
|
||
| const img = document.createElement('img'); | ||
| img.src = link; | ||
| img.alt = altText; | ||
| img.style.maxWidth = '90%'; | ||
| img.style.maxHeight = '90%'; | ||
| img.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)'; | ||
|
|
||
| modal.appendChild(img); | ||
|
|
||
| modal.addEventListener('click', () => { | ||
| document.body.removeChild(modal); | ||
| }); | ||
|
|
||
| document.body.appendChild(modal); | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Lightbox a11y: add Escape-to-close, focus return, aria-modal, and body scroll lock
Current modal cannot be closed via keyboard and doesn’t manage focus or background scroll.
Apply:
const Photo = ({ link, altText }) => {
- const handleClick = () => {
+ const handleClick = () => {
const modal = document.createElement('div');
+ const originalOverflow = document.body.style.overflow;
+ const previouslyFocused = document.activeElement;
modal.style.position = 'fixed';
modal.style.top = '0';
modal.style.left = '0';
modal.style.width = '100vw';
modal.style.height = '100vh';
modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
modal.style.display = 'flex';
modal.style.justifyContent = 'center';
modal.style.alignItems = 'center';
modal.style.zIndex = '1000';
+ modal.setAttribute('role', 'dialog');
+ modal.setAttribute('aria-modal', 'true');
+ modal.setAttribute('aria-label', altText);
+ modal.tabIndex = -1;
const img = document.createElement('img');
img.src = link;
img.alt = altText;
img.style.maxWidth = '90%';
img.style.maxHeight = '90%';
img.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)';
- modal.appendChild(img);
-
- modal.addEventListener('click', () => {
- document.body.removeChild(modal);
- });
-
- document.body.appendChild(modal);
+ modal.appendChild(img);
+ let onEsc;
+ const close = () => {
+ document.removeEventListener('keydown', onEsc);
+ document.body.style.overflow = originalOverflow;
+ if (document.body.contains(modal)) document.body.removeChild(modal);
+ if (previouslyFocused && previouslyFocused.focus) previouslyFocused.focus();
+ };
+ onEsc = (e) => { if (e.key === 'Escape') close(); };
+ modal.addEventListener('click', close);
+ document.addEventListener('keydown', onEsc);
+ document.body.style.overflow = 'hidden';
+ document.body.appendChild(modal);
+ if (modal.focus) modal.focus();
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleClick = () => { | |
| const modal = document.createElement('div'); | |
| modal.style.position = 'fixed'; | |
| modal.style.top = '0'; | |
| modal.style.left = '0'; | |
| modal.style.width = '100vw'; | |
| modal.style.height = '100vh'; | |
| modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; | |
| modal.style.display = 'flex'; | |
| modal.style.justifyContent = 'center'; | |
| modal.style.alignItems = 'center'; | |
| modal.style.zIndex = '1000'; | |
| const img = document.createElement('img'); | |
| img.src = link; | |
| img.alt = altText; | |
| img.style.maxWidth = '90%'; | |
| img.style.maxHeight = '90%'; | |
| img.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)'; | |
| modal.appendChild(img); | |
| modal.addEventListener('click', () => { | |
| document.body.removeChild(modal); | |
| }); | |
| document.body.appendChild(modal); | |
| }; | |
| const handleClick = () => { | |
| const modal = document.createElement('div'); | |
| const originalOverflow = document.body.style.overflow; | |
| const previouslyFocused = document.activeElement; | |
| modal.style.position = 'fixed'; | |
| modal.style.top = '0'; | |
| modal.style.left = '0'; | |
| modal.style.width = '100vw'; | |
| modal.style.height = '100vh'; | |
| modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; | |
| modal.style.display = 'flex'; | |
| modal.style.justifyContent = 'center'; | |
| modal.style.alignItems = 'center'; | |
| modal.style.zIndex = '1000'; | |
| modal.setAttribute('role', 'dialog'); | |
| modal.setAttribute('aria-modal', 'true'); | |
| modal.setAttribute('aria-label', altText); | |
| modal.tabIndex = -1; | |
| const img = document.createElement('img'); | |
| img.src = link; | |
| img.alt = altText; | |
| img.style.maxWidth = '90%'; | |
| img.style.maxHeight = '90%'; | |
| img.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)'; | |
| - modal.appendChild(img); | |
| - | |
| - modal.addEventListener('click', () => { | |
| - document.body.removeChild(modal); | |
| - }); | |
| - | |
| modal.appendChild(img); | |
| let onEsc; | |
| const close = () => { | |
| document.removeEventListener('keydown', onEsc); | |
| document.body.style.overflow = originalOverflow; | |
| if (document.body.contains(modal)) document.body.removeChild(modal); | |
| if (previouslyFocused && previouslyFocused.focus) previouslyFocused.focus(); | |
| }; | |
| onEsc = (e) => { if (e.key === 'Escape') close(); }; | |
| modal.addEventListener('click', close); | |
| document.addEventListener('keydown', onEsc); | |
| document.body.style.overflow = 'hidden'; | |
| document.body.appendChild(modal); | |
| if (modal.focus) modal.focus(); | |
| }; |
| .mediaBox img:hover, | ||
| .mediaBox img:focus { | ||
| transform: scale(1.03); /* smaller zoom */ | ||
| box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Keyboard focus state won’t fire on the img.
The Photo component makes the wrapper div focusable, not the img. Update selectors so focus styles apply when the wrapper has focus.
-.mediaBox img:hover,
-.mediaBox img:focus {
+.mediaBox div:hover img,
+.mediaBox div:focus img,
+.mediaBox :focus-visible img {
transform: scale(1.03); /* smaller zoom */
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .mediaBox img:hover, | |
| .mediaBox img:focus { | |
| transform: scale(1.03); /* smaller zoom */ | |
| box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08); | |
| .mediaBox div:hover img, | |
| .mediaBox div:focus img, | |
| .mediaBox :focus-visible img { | |
| transform: scale(1.03); /* smaller zoom */ | |
| box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08); | |
| } |
🤖 Prompt for AI Agents
In src/routes/css/Home.module.css around lines 58 to 61, the focus selector
targets the img but the wrapper div is focusable, so the focus styles never
apply; update the selectors so the styles apply when the wrapper has focus
(e.g., change .mediaBox img:focus to .mediaBox:focus img or add .mediaBox:focus,
.mediaBox:focus img) so the transform and box-shadow activate when the wrapper
receives keyboard focus.
| link="https://www.youtube.com/embed/vRShaLdex7Q?si=G7P1eL1YxY9YqCTD" | ||
| title="Aurora — Launch Canada 2025" | ||
| /> | ||
| <Video | ||
| link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7" | ||
| altText="Eridium - Static Fire #4" | ||
| /> | ||
| <Video | ||
| link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx" | ||
| altText="Playing Music from Portal on a Liquid Rocket Engine" | ||
| /> |
There was a problem hiding this comment.
Bug: Video uses altText prop; iframe gets no title.
Video expects title, not altText. As-is, the iframe title is undefined, hurting accessibility.
- <Video
- link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7"
- altText="Eridium - Static Fire #4"
- />
+ <Video
+ link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7"
+ title="Eridium — Static Fire #4"
+ />
- <Video
- link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx"
- altText="Playing Music from Portal on a Liquid Rocket Engine"
- />
+ <Video
+ link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx"
+ title="Playing Music from Portal on a Liquid Rocket Engine"
+ />📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| link="https://www.youtube.com/embed/vRShaLdex7Q?si=G7P1eL1YxY9YqCTD" | |
| title="Aurora — Launch Canada 2025" | |
| /> | |
| <Video | |
| link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7" | |
| altText="Eridium - Static Fire #4" | |
| /> | |
| <Video | |
| link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx" | |
| altText="Playing Music from Portal on a Liquid Rocket Engine" | |
| /> | |
| <Video | |
| link="https://www.youtube.com/embed/vRShaLdex7Q?si=G7P1eL1YxY9YqCTD" | |
| title="Aurora — Launch Canada 2025" | |
| /> | |
| <Video | |
| link="https://www.youtube.com/embed/65qts5k77M0?si=RCxH2PzIcWDhgeF7" | |
| title="Eridium — Static Fire #4" | |
| /> | |
| <Video | |
| link="https://www.youtube.com/embed/iuZ5-Du1UfI?si=smPblQNGyaFRywxx" | |
| title="Playing Music from Portal on a Liquid Rocket Engine" | |
| /> |
🤖 Prompt for AI Agents
In src/routes/rocketPages/Aurora.jsx around lines 212 to 222 the Video
components use the prop altText instead of the expected title prop, which
results in the iframe receiving no title and breaks accessibility; change each
Video instance to pass a title prop (e.g., title="Eridium - Static Fire #4",
title="Playing Music from Portal on a Liquid Rocket Engine") instead of altText
so the iframe gets a proper title, and run a quick test or linter to confirm
prop types and a11y warnings are resolved.
This pull request updates the Home page to highlight Waterloo Rocketry's 2025 Aurora rocket milestone, improves the press release and About Us sections, and enhances the user experience for the gallery and media display. The most significant changes are grouped below.
Content and Press Release Updates:
Media and Gallery UI Improvements:
Photocomponent inGallery.jsxto open images in a modal overlay on click or keyboard activation, improving accessibility and user experience.Home.module.cssfor images in the media box, adding a hover/focus zoom effect, border radius, and better layout.This change is
Summary by CodeRabbit
New Features
Content
Style
Documentation