Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified public/pdfs/2025_project_report.pdf
Binary file not shown.
37 changes: 36 additions & 1 deletion src/components/Gallery/Gallery.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,43 @@ const MoreButton = ({ link }) => {
};

const Photo = ({ link, altText }) => {
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);
};
Comment on lines +19 to +46

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ 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.

Suggested change
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();
};


return (
<div>
<div
onClick={handleClick}
onKeyDown={(e) => e.key === 'Enter' && handleClick()}
role="button"
tabIndex={0}
style={{ cursor: 'pointer' }}
>
<img src={link} alt={altText} className={styles.photo} />
</div>
);
Expand Down
Binary file added src/img/home/aurora-logo.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/img/home/borealis.webp
Binary file not shown.
Binary file modified src/img/home/cover_home.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/img/rocket/aurora-2025.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/img/rocket/borealis.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/img/rocketPhotos/aurora_upright.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/img/temp/2025_team_photo.webp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we just upload these to Flickr instead of temp.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/img/temp/README.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above for comment for temp folder.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### 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.
Binary file added src/img/temp/aurora_launch.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/img/temp/rise_tower.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Documentation from './routes/Documentation';

import Footer from './components/Footer/Footer';

import Aurora from './routes/rocketPages/Aurora';
import Borealis from './routes/rocketPages/Borealis';
import LeviathanOfTheSky from './routes/rocketPages/LeviathanOfTheSky';
import KrakenOfTheSky from './routes/rocketPages/KrakenOfTheSky';
Expand Down Expand Up @@ -76,6 +77,11 @@ ReactDOM.render(
path="rockets"
element={<Page title="Rockets"><Rockets /></Page>}
/>
<Route
exact
path="rockets/aurora"
element={<Page title="Aurora"><Aurora /></Page>}
/>
<Route
exact
path="rockets/borealis"
Expand Down
72 changes: 37 additions & 35 deletions src/routes/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import rocketsCoverImage from '../img/home/link_to_rockets.webp';
import sponsorsCoverImage from '../img/home/link_to_sponsors.webp';
import galleryCoverImage from '../img/home/link_to_gallery.webp';

import aboutUsImage1 from '../img/rocket/leviathan-of-the-sky.webp';
import aboutUsImage1 from '../img/rocket/aurora-2025.webp';

import pressReleasePhotoA from '../img/home/borealis.webp';
import pressReleasePhotoA from '../img/home/aurora-logo.webp';

const Home = () => {
const aboutUsRef = useRef(null);
Expand All @@ -47,14 +47,21 @@ const Home = () => {
<Col md={7}>
<div>
<HomeContent title="ABOUT US">
Waterloo Rocketry is a student design team from the University of Waterloo in
Waterloo, Ontario. We currently have around 50 members, primarily
undergraduate students in engineering, science, and mathematics. We design,
build, and launch rockets each year at Launch Canada, most recently having
launched Canada&apos;s first ever liquid engine rocket in 2024! Our team&apos;s
primary objective is to provide students with hands-on learning opportunities in
research, design, analysis, fabrication, and testing throughout the entire
engineering design cycle.
<p>
Waterloo Rocketry is a student design team from the University of Waterloo in
Waterloo, Ontario. With a membership of around 50 students—primarily
undergraduates in engineering, science, and mathematics— the team is dedicated to
advancing rocketry in Canada while providing exceptional experiential learning
opportunities.
</p>
<p>
Each year, the team designs, builds, and launches rockets at Launch Canada,
the nation&apos;s premier rocketry competition.
In 2024, Waterloo Rocketry proudly made history with Borealis, Canada&apos;s
first-ever liquid engine rocket.
In 2025, the team followed up with Aurora, which more than doubled the Canadian
altitude record for liquid bi-propellant rockets.
</p>
</HomeContent>
</div>
</Col>
Expand All @@ -69,7 +76,7 @@ const Home = () => {
<Row>
<Col md={8} className={styles.pressReleaseBox}>
<p>
<strong>FOR IMMEDIATE RELEASE: 08/23/24</strong>
<strong>FOR IMMEDIATE RELEASE: 08/24/25</strong>
</p>
<div className={styles.contactInfo}>
<p>Waterloo Rocketry</p>
Expand All @@ -79,42 +86,37 @@ const Home = () => {
</p>
</div>
<h2>
Waterloo Rocketry Soars to New Heights with Canada’s First Liquid Engine Rocket Launch
Waterloo Rocketry&apos;s Aurora Rocket Shatters Records at Launch Canada 2025
</h2>
<p>
<strong>Timmins, Ontario:</strong>
{' '}
Waterloo Rocketry, a student design team from the University of Waterloo,
proudly announces a historic milestone in Canadian
aerospace with the successful launch of
‘Borealis,’ the first-ever Canadian liquid bi-propellant rocket.
The launch occurred on August 20, 2024,
during the third annual Launch Canada event held just outside Timmins, ON.
is excited to announce the successful launch of Aurora, the team&apos;s 2025 liquid
bi-propellant rocket, at Launch Canada on Thursday, August 21st.
</p>
<p>
The ‘Borealis’ rocket, powered by a bi-propellant
mixture of ethanol and nitrous oxide,
reached an altitude of 5,855 metres
(19,212 feet) and achieved a top speed of 1646 km/h before
falling back to the ground under its own parachute. Designed entirely by students,
building on years of team history, this rocket showcases the culmination of the
advanced engineering capabilities developed by the team throughout its past 13 years.
Aurora soared to an altitude of about 38,000 feet at around Mach 2,
more than doubling the team&apos;s standing Canadian altitude record for liquid
bi-propellant rockets. Although the recovery system&apos;s parachutes did not
survive—meaning the rocket could not be retrieved from the forest and is likely at
the bottom of a lake—the team is immensely proud of this year&apos;s achievement.
</p>
<p>
This accomplishment positions the University of Waterloo
as a leading institution in Canadian student rocketry,
joining a select group of universities globally that have
successfully launched liquid engine rockets.
In years to come, the team plans to continue building bigger
and better liquid bi-propellant rockets,
with sights set for higher altitudes, more complex payloads,
and continued learning to further propel
Canada into the global aerospace arena.
Designed and built entirely by students, Aurora represents a year of dedication,
innovation, and teamwork. With this milestone, Waterloo Rocketry secured 2nd place
in Launch Canada&apos;s Advanced category.
</p>
<p>
The team extends a huge thank you to its sponsors for their generous support—this
launch would not have been possible without them. Gratitude also goes to the
University of Waterloo and the Sedra Student Design Centre for enabling the team
to pursue ambitious projects like Aurora.
</p>
</Col>
<Col md={4} className={styles.mediaBox}>
<Photo link={pressReleasePhotoA} altText="Placeholder 1" />
<Video link="https://www.youtube.com/embed/Z126ZESX3uA?si=K_Zxes8V2nKABoGa" title="Rocket Launch" />
<Photo link={pressReleasePhotoA} altText="Aurora Logo" />
<Video link="https://www.youtube.com/embed/vRShaLdex7Q?si=k5kqdmuP8fEYu2LC" title="Rocket Launch" />
</Col>
</Row>
</Container>
Expand Down
10 changes: 10 additions & 0 deletions src/routes/Rockets.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Col, Container, Row } from 'react-bootstrap';
import RocketCard from '../components/RocketCard/RocketCard';
import styles from './css/rocket.module.css';

import rocketAurora from '../img/rocket/aurora-2025.webp';
import rocketBorealis from '../img/rocket/borealis.webp';
import rocketLeviathanOfTheSky from '../img/rocket/leviathan-of-the-sky.webp';
import rocketKrakenOfTheSky from '../img/rocket/kraken-of-the-sky.webp';
Expand All @@ -20,6 +21,15 @@ const Rockets = () => {
<Container fluid>
<div className={styles.flex__wrapper}>
<Row xl={3} md={2} sm={1}>
<Col>
<RocketCard
url="/rockets/aurora"
title="AURORA"
date="2025"
image={rocketAurora}
imagePosition="25% 40%"
/>
</Col>
<Col>
<RocketCard
url="/rockets/borealis"
Expand Down
18 changes: 18 additions & 0 deletions src/routes/css/Home.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@
flex-direction: column;
justify-content: space-between;
align-items: center;
overflow: hidden;
border-radius: 6px;
}

.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;
}

.mediaBox img:hover,
.mediaBox img:focus {
transform: scale(1.03); /* smaller zoom */
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
Comment on lines +58 to +61

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ 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.

Suggested change
.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.

}

.landingContainer {
Expand Down
Loading