From d46985d0745cf6d6e4ac5f503ea497112d457809 Mon Sep 17 00:00:00 2001 From: Rayan Date: Tue, 6 Oct 2026 14:15:18 +1100 Subject: [PATCH 1/6] feat: updates sponsors section --- src/assets/sponsor-logos/jump.png | Bin 0 -> 25996 bytes src/assets/sponsor-logos/nine-mile.svg | 1 + src/assets/sponsor-logos/qrt.svg | 1 + src/components/Footer/Footer.jsx | 10 ++++++++++ src/routes/LandingPage/LandingPage.jsx | 2 ++ .../SponsorshipSection/SponsorshipSection.jsx | 16 +++++++++++----- src/routes/LandingPage/index.less | 5 +++++ 7 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 src/assets/sponsor-logos/jump.png create mode 100644 src/assets/sponsor-logos/nine-mile.svg create mode 100644 src/assets/sponsor-logos/qrt.svg diff --git a/src/assets/sponsor-logos/jump.png b/src/assets/sponsor-logos/jump.png new file mode 100644 index 0000000000000000000000000000000000000000..f384901b24e9432b888ebe0e8032fbcaf1194ed9 GIT binary patch literal 25996 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 literal 0 HcmV?d00001 diff --git a/src/assets/sponsor-logos/nine-mile.svg b/src/assets/sponsor-logos/nine-mile.svg new file mode 100644 index 00000000..4f3b318f --- /dev/null +++ b/src/assets/sponsor-logos/nine-mile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/sponsor-logos/qrt.svg b/src/assets/sponsor-logos/qrt.svg new file mode 100644 index 00000000..5cda590a --- /dev/null +++ b/src/assets/sponsor-logos/qrt.svg @@ -0,0 +1 @@ +qrt \ No newline at end of file diff --git a/src/components/Footer/Footer.jsx b/src/components/Footer/Footer.jsx index 8d6f1555..72158041 100644 --- a/src/components/Footer/Footer.jsx +++ b/src/components/Footer/Footer.jsx @@ -44,6 +44,16 @@ const Footer = () => { Resources +
  • + + Workshop Materials + +
  • Board Login diff --git a/src/routes/LandingPage/LandingPage.jsx b/src/routes/LandingPage/LandingPage.jsx index bef47e97..d5872d7c 100644 --- a/src/routes/LandingPage/LandingPage.jsx +++ b/src/routes/LandingPage/LandingPage.jsx @@ -3,6 +3,7 @@ import HeroSection from './HeroSection/HeroSection'; import SponsorshipSection from './SponsorshipSection/SponsorshipSection'; // import AboutUsPage from 'routes/AboutUsPage'; import GamesSection from 'components/GamesSection/GameSection'; +import WorkshopsSection from 'components/WorkshopsSection/WorkshopsSection'; import './index.less'; @@ -21,6 +22,7 @@ const LandingPage = () => {
    + See More β†’
    diff --git a/src/routes/LandingPage/SponsorshipSection/SponsorshipSection.jsx b/src/routes/LandingPage/SponsorshipSection/SponsorshipSection.jsx index 2a1bbef7..1b2abb7c 100644 --- a/src/routes/LandingPage/SponsorshipSection/SponsorshipSection.jsx +++ b/src/routes/LandingPage/SponsorshipSection/SponsorshipSection.jsx @@ -9,6 +9,9 @@ import vivcourtLogo from '../../../assets/sponsor-logos/vivcourt.svg'; import citadelLogo from '../../../assets/sponsor-logos/citadel.svg'; import janestreetLogo from '../../../assets/sponsor-logos/JS_horizontal_black.png'; import sigLogo from '../../../assets/sponsor-logos/sig.png'; +import jumpLogo from '../../../assets/sponsor-logos/jump.png'; +import nineMileLogo from '../../../assets/sponsor-logos/nine-mile.svg'; +import qrtLogo from '../../../assets/sponsor-logos/qrt.svg'; // Inverted lgoos import optiverLogoInv from '../../../assets/sponsor-logos/optiver-alt.svg'; @@ -31,19 +34,22 @@ const SponsorshipSection = () => {
    - +
    - - + + - + + + +

    Want to sponsor us? Get in touch with our team and we would be more than delighted to discuss partnership opportunities and potential collaborations!

    -
    Sponsor Us diff --git a/src/routes/LandingPage/index.less b/src/routes/LandingPage/index.less index 4944c8da..a8d39459 100644 --- a/src/routes/LandingPage/index.less +++ b/src/routes/LandingPage/index.less @@ -28,6 +28,11 @@ } +// Leave room for the "See More" link, which is pulled up by its negative margin +#resources .workshops-section { + margin-bottom: 3.5rem; +} + .more-resources-button { display:block; width: 100%; From 47692aac4b6513e32765253c90c3057fb1f102a8 Mon Sep 17 00:00:00 2001 From: Rayan Date: Tue, 6 Oct 2026 14:15:41 +1100 Subject: [PATCH 2/6] Added workshop github repo to the webstie --- .../WorkshopsSection/WorkshopsSection.jsx | 29 +++++++++ src/components/WorkshopsSection/index.less | 64 +++++++++++++++++++ src/routes/ResourcesPage/ResourcesPage.jsx | 5 +- 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/components/WorkshopsSection/WorkshopsSection.jsx create mode 100644 src/components/WorkshopsSection/index.less diff --git a/src/components/WorkshopsSection/WorkshopsSection.jsx b/src/components/WorkshopsSection/WorkshopsSection.jsx new file mode 100644 index 00000000..028d53ca --- /dev/null +++ b/src/components/WorkshopsSection/WorkshopsSection.jsx @@ -0,0 +1,29 @@ +import { BsGithub } from 'react-icons/bs'; +import './index.less'; + +const WORKSHOP_MATERIALS_URL = 'https://github.com/QuantSoc/workshop-materials'; + +const WorkshopsSection = ({ className = '', showHeader = true }) => { + return ( +
    + {showHeader &&

    Workshops

    } + + +
    +
    Workshop Materials
    +
    + Slides, notebooks and code from our workshops, all on GitHub. +
    +
    + View on GitHub β†’ +
    +
    + ); +}; + +export default WorkshopsSection; diff --git a/src/components/WorkshopsSection/index.less b/src/components/WorkshopsSection/index.less new file mode 100644 index 00000000..a8e32a8d --- /dev/null +++ b/src/components/WorkshopsSection/index.less @@ -0,0 +1,64 @@ +@import '../../styles/constants.less'; + +.workshops-section__header { + margin-bottom: 1rem; +} + +.workshops-card { + display: flex; + align-items: center; + gap: 1.5rem; + margin: 10px; + padding: 2rem; + border-radius: 15px; + background: linear-gradient(130deg, @black-purple, @darkest-purple); + color: white; + text-decoration: none; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); + transition: box-shadow 0.3s ease, transform 0.3s ease-out; + + &:hover { + color: white; + box-shadow: inset 0 0 20px @quantsoc-primary, 0 0 20px @quantsoc-primary; + transform: scale(1.02); + } +} + +// Override the global `svg { height: 20px }` rule from the sponsorship section +.workshops-card svg.workshops-card__icon { + flex-shrink: 0; + width: 64px; + height: 64px; +} + +.workshops-card__text { + flex: 1; + text-align: left; +} + +.workshops-card__title { + font-size: 28px; + font-weight: 500; + font-family: 'Consolas', 'Courier New', Courier, monospace; +} + +.workshops-card__subtext { + margin-top: 0.25rem; + color: @quantsoc-primary; +} + +.workshops-card__cta { + flex-shrink: 0; + font-weight: 500; +} + +@media (max-width: 768px) { + .workshops-card { + flex-direction: column; + text-align: center; + } + + .workshops-card__text { + text-align: center; + } +} diff --git a/src/routes/ResourcesPage/ResourcesPage.jsx b/src/routes/ResourcesPage/ResourcesPage.jsx index de2faf46..fb88f7d8 100644 --- a/src/routes/ResourcesPage/ResourcesPage.jsx +++ b/src/routes/ResourcesPage/ResourcesPage.jsx @@ -2,6 +2,7 @@ import HeroSection from './HeroSection/HeroSection'; import JobListings from './JobListingsSection/JobListings'; import GamesSection from 'components/GamesSection/GameSection'; +import WorkshopsSection from 'components/WorkshopsSection/WorkshopsSection'; import './index.less'; @@ -13,7 +14,9 @@ const ResourcesPage = () => { {/* separate div to ensure universal focusability of anchor */} - {/* */} +
    + +
    From 1824d7b80bb96b56dd9bc9e9ad54e4d108cb1f84 Mon Sep 17 00:00:00 2001 From: Rayan Date: Tue, 6 Oct 2026 14:18:16 +1100 Subject: [PATCH 3/6] updated README.md --- .github/workflows/production_check.yml | 24 ++++--- README.md | 86 +++++++++++++++++++------- 2 files changed, 77 insertions(+), 33 deletions(-) diff --git a/.github/workflows/production_check.yml b/.github/workflows/production_check.yml index 4e8bdca6..2e03a015 100644 --- a/.github/workflows/production_check.yml +++ b/.github/workflows/production_check.yml @@ -1,21 +1,25 @@ name: Production test on: - pull_request: # run only on created pull request on main - branches: + pull_request: # run on pull requests into the deployed branch (dev) and main + branches: + - dev - main - + jobs: build: - name: run lint and tests + name: run lint and production build runs-on: ubuntu-latest steps: - - name: check out code - uses: actions/checkout@v2 + - name: check out code + uses: actions/checkout@v4 - name: setup node - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm - name: install dependencies - run: npm install + run: npm ci - name: running lint run: npm run lint - - name: run eslint - run: npm run alltests \ No newline at end of file + - name: production build + run: npm run build diff --git a/README.md b/README.md index 3f5a7f5e..ace33c78 100644 --- a/README.md +++ b/README.md @@ -8,36 +8,76 @@ [![Production test](https://github.com/QuantSoc/website/actions/workflows/production_check.yml/badge.svg)](https://github.com/QuantSoc/website/actions/workflows/production_check.yml) -This repo contains the source code for the frontend of the main website of the πŸ“ˆUNSW Quantitative Finance and Trading Society (Quantsoc), powered by [ReactJs](https://reactjs.org/). +This repo contains the source code for the main website of the πŸ“ˆ UNSW Quantitative Finance and Trading Society (QuantSoc), live at **[quantsoc.org](https://quantsoc.org)**. +It is a single-page [React](https://reactjs.org/) app built with [Vite](https://vitejs.dev/). Articles and job listings are read from a [Firebase Firestore](https://firebase.google.com/docs/firestore) database; everything else is static. - +**Deploying:** Read [DEPLOYMENT.md](DEPLOYMENT.md) first. The live site is built from the `dev` branch. ## Quick start -Once you have a rather recent version of `npm` installed on a (preferably) Unix based system, simply run: -``` -$ npm install -$ npm run prepare -``` -Then you may run a development setting via: -``` -$ npm run start -``` -## Tests and linting -The cleansing process will run before each push, however, you can run the linting and test manually by doing: -``` -$ npm run lint -$ npm run test +You need [Node.js](https://nodejs.org/) 20 or newer (the dev container uses Node 20) and `npm`. + +```bash +npm ci # install the exact dependency versions from package-lock.json +npm run prepare # install the git hooks (husky) - only needed once per clone +npm run start # start the dev server at http://localhost:5173 ``` -## Running in production -To run a quick production build, simply do: +The dev server reloads automatically when you save a file. Nothing you do locally affects the live website. + +**Note:** the site reads articles and job listings from the **real** Firestore database, even locally. The site only ever *reads* data, so this is safe, but anything you see in those sections is live data. + +## Scripts + +| Command | What it does | +| ----------------- | ------------------------------------------------------------------------------------- | +| `npm run start` | Dev server at http://localhost:5173 | +| `npm run build` | Production build into `dist/` | +| `npm run preview` | Serves the `dist/` build at http://localhost:4173 - use this to check a build locally | +| `npm run lint` | Runs ESLint | +| `npm run prepare` | Installs the husky git hooks | + +There is currently **no automated test suite** (there is no `npm run test`). Testing is done by building and checking the site by hand - see [DEPLOYMENT.md](DEPLOYMENT.md#testing-a-change-safely). + +## Project structure + ``` -$ npm run build -$ npm run serve +src/ +β”œβ”€β”€ App.jsx # Routes: /, /articles, /resources, /contact, /mathsprint +β”œβ”€β”€ firebase.config.js # Firebase/Firestore client setup (see below) +β”œβ”€β”€ assets/ # Images; sponsor logos live in assets/sponsor-logos/ +β”œβ”€β”€ components/ # Components shared by more than one page (NavBar, Footer, ...) +β”œβ”€β”€ routes/ # One folder per page. Components used by only one page live in that page's folder +β”œβ”€β”€ hooks/ +└── styles/ # Global .less styles and colour constants (styles/constants.less) +legacy/ # Old Python backend - not used by the current site ``` -## Resources -For conventions, module structure, advanced configuration or cooler stuff, check out the [wiki](https://github.com/QuantSoc/website/wiki) page. -To learn React, check out the [React documentation](https://reactjs.org/). +Import aliases (`components/...`, `routes/...`, `assets/...`, `styles/...`, `hooks/...`) are defined in `vite.config.js`. + +## Common tasks + +### Updating sponsors + +Sponsors are hard-coded in `src/routes/LandingPage/SponsorshipSection/SponsorshipSection.jsx`. + +1. Put the logo in `src/assets/sponsor-logos/`. Prefer an SVG, otherwise a PNG with a transparent background. The site has a **white background**, so use a dark/coloured version of the logo, not a white one. +2. Import the logo at the top of `SponsorshipSection.jsx`. +3. Add a `` line under the right tier (`principal` or `major`). Logos appear in the order they are listed. +4. Run `npm run start` and check the Sponsors section on both desktop and a narrow (mobile) window. + +### Workshop materials + +Workshop slides and code are published in the [QuantSoc/workshop-materials](https://github.com/QuantSoc/workshop-materials) repo. + +### Updating Jobs Listings & Articles + +All the Job Listings are stored in the [Firebase Firestore](https://firebase.google.com/docs/firestore) database. Simply log into Firebase Hosting using quantsoc email OAuth, and then end it manually from there. + +## Firebase + +`src/firebase.config.js` connects the site to the `quantsoc-website-admin` Firebase project. It is only used to **read** the `articles` and `jobs` Firestore collections. The site is **not** hosted on Firebase (see [DEPLOYMENT.md](DEPLOYMENT.md)). + +The API key in that file is a public client identifier, not a secret (every visitor's browser downloads it). What actually protects the data is the project's Firestore security rules, which are managed in the Firebase console. They should allow public reads of `articles` and `jobs` only, and no public writes. + From 2c711cf25c8dfe4441ce2cd2defda43229ba125c Mon Sep 17 00:00:00 2001 From: Rayan Date: Tue, 6 Oct 2026 14:37:14 +1100 Subject: [PATCH 4/6] feat: removed Board Login from the fotter --- src/components/Footer/Footer.jsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/Footer/Footer.jsx b/src/components/Footer/Footer.jsx index 72158041..777e5c5c 100644 --- a/src/components/Footer/Footer.jsx +++ b/src/components/Footer/Footer.jsx @@ -54,11 +54,6 @@ const Footer = () => { Workshop Materials
  • -
  • - - Board Login - -
  • From 878ff8039410f90560e1f6f1f003b3f8c847de41 Mon Sep 17 00:00:00 2001 From: Rayan Date: Tue, 6 Oct 2026 14:37:54 +1100 Subject: [PATCH 5/6] feat: made citadel securities logo bigger --- .../SponsorshipSection/Sponsor/Sponsor.jsx | 4 ++-- .../LandingPage/SponsorshipSection/Sponsor/index.less | 11 +++++++++++ .../SponsorshipSection/SponsorshipSection.jsx | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/routes/LandingPage/SponsorshipSection/Sponsor/Sponsor.jsx b/src/routes/LandingPage/SponsorshipSection/Sponsor/Sponsor.jsx index 37fa66f4..b703aed9 100644 --- a/src/routes/LandingPage/SponsorshipSection/Sponsor/Sponsor.jsx +++ b/src/routes/LandingPage/SponsorshipSection/Sponsor/Sponsor.jsx @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; import "./index.less"; -const Sponsor = ({ logoSrc, sponsorLink, logoSrcInv }) => { +const Sponsor = ({ logoSrc, sponsorLink, logoSrcInv, wide = false }) => { const [isDarkMode, setIsDarkMode] = useState(false); useEffect(() => { @@ -15,7 +15,7 @@ const Sponsor = ({ logoSrc, sponsorLink, logoSrcInv }) => { }, []); return ( -
    +

    Want to sponsor us? Get in touch with our team and we would be more than delighted to discuss partnership opportunities and potential collaborations! From c60b40f60a148841998c649e14a77df5984e15b8 Mon Sep 17 00:00:00 2001 From: Rayan Date: Tue, 6 Oct 2026 14:41:06 +1100 Subject: [PATCH 6/6] chore: pushed a deployment.md file, detailing how deployments work --- DEPLOYMENT.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 DEPLOYMENT.md diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 00000000..8a037897 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,80 @@ +# Deployment & Testing + +## Where the site is hosted + +| Domain | Points to | What it serves | +| ---------------------------------------------- | ----------------------------- | -------------------------------------------------------------- | +| [quantsoc.org](https://quantsoc.org) | `dev.website-dk1.pages.dev` | **The live site** - the latest build of the `dev` branch | +| [staging.quantsoc.org](https://staging.quantsoc.org) | `dev.website-dk1.pages.dev` | The same as quantsoc.org - **not** a separate staging site | +| [dev.quantsoc.org](https://dev.quantsoc.org) | `website-dk1.pages.dev` | An old, outdated build (Cloudflare's "production" deployment) | +| [mtg.quantsoc.org](https://mtg.quantsoc.org) | | The Mock Trading Game - a separate app, not in this repo | + +The live site at quantsoc.org is a build (`npm run build`) of the **`dev` branch**. The `main` branch is 100s of commits out of date and is not what's live. + +> ⚠️ **Pushing or merging to `dev` deploys straight to the live site.** + +**Firebase Hosting:** The repo uses Firebase only for the Firestore database. Do **not** run `firebase init` or `firebase deploy`, at best it does nothing, at worst it creates a second, copy of the site. + +### Cloudflare Pages setup + +Found in the Cloudflare dashboard -> Compute -> Workers & Pages -> the project -> Settings. + +| Setting | Value | +| ---------------------- | ----------------------------------------------- | +| Project name | `quantsoc-dev` (to confirm, see below) | +| Pages address | `website-dk1.pages.dev` | +| Automatic deployments | Enabled (every push to GitHub triggers a build) | +| Production branch | `main` (see below) | +| Build command | `npm run build` | +| Build output directory | `dist` | +| Root directory | (empty - the repo root) | +| Build comments | Enabled (preview links are posted on PRs) | + +### How `dev` ends up live + +Cloudflare treats `main` as the production branch, and every other branch gets its own preview deployment at `.website-dk1.pages.dev`. quantsoc.org is not attached to the production deployment. Instead, its DNS record points at the `dev` branch's preview address, `dev.website-dk1.pages.dev`, which always serves the newest build of `dev`. So: + +- **Pushing to `dev`** updates `quantsoc.org` (and `staging.quantsoc.org`). +- **Pushing to `main`** only updates `website-dk1.pages.dev` and `dev.quantsoc.org`. It does not affect the live site. +- **Pushing any other branch** creates a preview at `.website-dk1.pages.dev`. Branch names are shortened and made lowercase in the address, and `/` becomes `-`. + +## Testing a change safely + +There is no automated test suite, so testing means building the site and looking at it. + +1. **Work on a branch**, never directly on `dev`: + ```bash + git checkout dev && git pull + git checkout -b feat/no-ref/short-description + ``` +2. **Develop** with `npm run start` (http://localhost:5173). +3. **Check the production build**, because this is what actually gets deployed: + ```bash + npm run build # must finish with no errors + npm run preview # serves the build at http://localhost:4173 + ``` + Click through every page you touched, and also check: + - a narrow window (or your browser's device toolbar) for mobile layout + - every link and button you added + - the browser console for errors +4. **Lint the files you changed**: `npx eslint path/to/File.jsx`. +5. **Push the branch and open a pull request into `dev`.** The GitHub Actions check (`.github/workflows/production_check.yml`) runs lint and a production build on every PR into `dev`. Cloudflare Pages will also build the branch and comment a **preview URL** on the PR (staging.quantsoc.org can't be used for this - it shows the live site). That URL is a real deployment that is *not* the live site - the best place for a final check, and to share with the exec. +6. **Merge into `dev`** once someone else has reviewed it. This is the step that goes live. + +## Deploying + +**Merging the PR into `dev` is the deployment** - Cloudflare builds and publishes it automatically. Watch the build in the Cloudflare dashboard (the project -> Deployments), then check https://quantsoc.org. You may need a hard refresh (Cmd/Ctrl + Shift + R) to see changes. + +There is no need to build or upload anything by hand. + +## Rolling back + +Revert the bad commit on `dev` and push: + +```bash +git checkout dev && git pull +git revert +git push +``` + +Cloudflare rebuilds the live site within a few minutes. You can find the `` of the bad commit with `git log`, or in the Cloudflare dashboard -> the project -> Deployments.