The Society of Aeronautics and Rocketry (SOAR) website is a Next.js application used to present the student club's projects, events, membership info, and media. It uses the Next.js App Router, Tailwind and utility components to render pages and small API routes for project-specific endpoints.
This README documents the purpose of the repository's key files and folders so maintainers and contributors can quickly find where to make changes.
Prerequisites: Node.js (18+ recommended), pnpm/yarn/npm.
Install Node.js: https://nodejs.org/en/download/
Make sure you have npm installed (comes with Node.js). You can also use yarn or pnpm if you prefer.
npm --version- Fork the repo by typing:
git clone https://github.com/usfsoar/soar-usf-website.git- Create a feature branch.
git checkout -b feature/your-feature-name- Run
npm install
npm run dev- Make your changes, ensuring to test locally and fix any TypeScript errors (even though they won't block builds, we want to maintain type safety).
npm run build- Open a PR with a clear description, screenshots, and any relevant details.
git add .
git commit -m "Add your message here"
git push origin feature/your-feature-name-
DO NOT MERGE YOUR OWN PRs. At least one other maintainer must review and merge your PR to ensure code quality and consistency.
-
Do not forget to pull the latest changes from the main branch before starting your work and before pushing your changes to avoid merge conflicts.
git pull origin mainNote: You can also add collaborators who have admin or write access for USF SOAR by going to GitHub Repo -> Settings -> Collaborators and Teams -> Add People.
Environment variables used by social integrations (.env.local):
ROWS_KEY(orROWS_API_KEY): server-side token used for Rows requests.ROWS_LINKEDIN_FIELD: field name to read from the Rows payload (defaultlinkedin).ROWS_SPREADSHEET_ID: Rows spreadsheet id (used whenROWS_LINKEDIN_URLis not set).ROWS_TABLE_ID: Rows table id for the current followers table.ROWS_RANGE: A1 range to read from Rows (defaultA1:E20).INSTAGRAM_USERNAME: Instagram username to scrape via Blastup (defaultusfsoar).INSTAGRAM_FALLBACK_COUNT: optional numeric fallback used only when live Instagram scraping fails in deployment.
The app now exposes GET /api/socials/followers, which powers both the homepage stats and contact social cards.
It caches results for 24 hours and returns the last successful values if an upstream source fails.
Available npm scripts (from package.json):
dev: starts Next.js in development mode (next dev)build: builds the app for production (next build)start: runs the built app (next start)lint: runs ESLint across the projectsocials:smoke: checks local/api/socials/followersand fails if Instagram/LinkedIn are missingsocials:smoke:prod: checks deployed/api/socials/followersonhttps://usfsoar.vercel.appinstagram:sync: uses Playwright to fetch Instagram followers from Blastup and writesdata/instagram-follower-count.jsonbullsconnect:auth: runs a script to authenticate with BullsConnect and save session state (used for the daily member count sync workflow)bullsconnect:sync: runs a script to fetch the latest member count from BullsConnect and updatedata/soar-member-count.json(used by the daily sync workflow)linkedin:sync: runs a script to fetch the latest LinkedIn follower count from Rows and updatedata/linkedin-follower-count.json(used by the daily sync workflow)
Top-level files
package.json: project metadata, dependencies and npm scripts.next.config.mjs: Next.js configuration — this project enables Turbopack root, configures image formats and device sizes, and setstypescript.ignoreBuildErrors: true(so TypeScript build errors won't block production builds).tsconfig.json: TypeScript compiler options (project-wide types/settings).postcss.config.mjs: PostCSS configuration used by Tailwind.components.json: (project-specific) configuration file used by the app for component-level data (if present).
Top-level folders
-
app/— The Next.js App Router source. Key entries:app/layout.tsx— global layout and wrappers (theme provider, header/footer injection)app/page.tsx— the homepage entry componentapp/globals.css— global styles used by the App Routerapp/about/page.tsx— about pageapp/blogs/page.tsx— blogs listing pageapp/current-projects/*— pages for current projects (IREC, TORITO, certifications)app/past-projects/*— pages for past projects (PAST NSL, Hybrid)app/positions/page.tsx— officer positionsapp/shop/page.tsxandapp/success/— shop and checkout flow pagesapp/sponsorships/page.tsx— sponsorship information pageapp/api/— Next.js route handlers; subfolders:app/api/checkout/— checkout API endpointsapp/api/contact/— contact form handler endpointsapp/api/soar-members/— membership-related APIsapp/api/socials/discord/route.ts— an example API route that forwards or handles Discord-related operationsapp/api/socials/followers/route.ts— API route that returns social media follower counts (LinkedIn, Instagram) by reading from the playwright and Instagram scraping results
-
components/— React components used across pages. Key components:about.tsx— About section component used on the About pageblogs.tsx— blogs list / teaser componentcontact.tsx— contact form UI used on contact pageseboard-yearbook.tsx— officer yearbook / roster componentfooter.tsx— site footerhero.tsx— homepage hero/bannerirec.tsx— IREC project overview componentsponsorslideshow.tsx— sponsor slideshow componentmulti-calendar.tsx— combined calendar UI used to show eventsnavbar.tsx— the main navigation bar included inlayout.tsxpage-header.tsx— page header used across pages for consistent title/subtitlesponsorships.tsx— sponsorship informationstats.tsx— site or membership statistics visualization (charts/metrics)theme-provider.tsx— theme context/provider for dark/light mode and persists selectiontorito.tsx,tra-certifications.tsx— project/certification components
UI primitives (under
components/ui/):button.tsx— shared button component with variantscard.tsx— generic card containerinput.tsx,label.tsx,textarea.tsx— form primitives used bycontactand other forms
-
data/— JSON or JS data files used to seed pages (teams, events, sponsors, etc.). Use this to update static content. -
lib/— utility functions and helpers; notable file:lib/utils.ts— shared helper functions used across pages/components
-
public/— static assets (images, icons, downloads). Place images here and reference via/paths. -
scripts/— project-specific scripts (deploy helpers, asset generation, etc.). -
styles/— additional CSS files;styles/globals.csscontains Tailwind and application-level CSS.
-
next.config.mjs:turbopack.rootset: a Turbopack optimization setting used by the Next.js toolchain.typescript.ignoreBuildErrors: true— TypeScript errors do not fail the production build (use with care: fix types locally before merging).imagesconfiguration: declares supported image formats (avif,webp) and device sizes used by Next/Image.
-
tailwindand PostCSS: configured throughpostcss.config.mjsand Tailwind installed indevDependencies.
- Pages and routes: edit files under
app/(each folder'spage.tsxdefines a route). - Global layout & header/footer:
app/layout.tsxandcomponents/navbar.tsx,components/footer.tsx. - Styles: Tailwind config and
styles/globals.cssorapp/globals.css. - Images and static assets:
public/. - Reusable UI:
components/andcomponents/ui/.
This project is Vercel-friendly and uses Next.js defaults. The repository includes a Vercel-deployed instance at the top badge — deploys run npm run build and npm start in production.
This repo includes a workflow at .github/workflows/bullsconnect-sync.yml that runs once per day and updates data/soar-member-count.json.
Run once on your machine:
npm run bullsconnect:auth
npm run bullsconnect:syncAfter login, this creates .auth/bullsconnect-storage.json.
The workflow restores this auth state from a base64 secret named BULLSCONNECT_STORAGE_STATE_B64.
PowerShell command to generate the secret value:
[Convert]::ToBase64String([IO.File]::ReadAllBytes(".auth/bullsconnect-storage.json"))Copy the output and add it in:
GitHub Repo -> Settings -> Secrets and variables -> Actions -> New repository secret
Push this branch, then run the workflow manually once from the Actions tab (workflow_dispatch) to verify it works.
-
Scheduled workflows run from the repository default branch only.
-
The workflow commits changes only when
data/soar-member-count.jsonactually changes. -
If SOAR login expires, refresh local auth and update
BULLSCONNECT_STORAGE_STATE_B64. -
Dependencies and devDependencies are managed in
package.json. Keep versions consistent and update carefully because Next 16 and React 19 are used here. -
The project intentionally sets TypeScript to ignore build-time errors; ensure types are corrected locally before merging.
This repo includes .github/workflows/instagram-sync.yml that runs once per day and updates data/instagram-follower-count.json using Playwright.
- Trigger manually from Actions tab (
workflow_dispatch) for first verification. - The workflow commits only when the Instagram count file changes.
- The social API route uses this synced file as a production fallback when live scraping is blocked.
If live scraping fails, the workflow will log the error and continue using the last successful count, but in development, you can run
npm run instagram:syncto verify the scraping works locally.