Skip to content

usfsoar/soar-usf-website

Repository files navigation

SOAR USF Website

image

Deployed on Vercel

Overview

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.


Quick Start

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

Contributing

  1. Fork the repo by typing:
git clone https://github.com/usfsoar/soar-usf-website.git
  1. Create a feature branch.
git checkout -b feature/your-feature-name
  1. Run
npm install
npm run dev
  1. 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
  1. 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
  1. DO NOT MERGE YOUR OWN PRs. At least one other maintainer must review and merge your PR to ensure code quality and consistency.

  2. 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 main

Note: 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 (or ROWS_API_KEY): server-side token used for Rows requests.
  • ROWS_LINKEDIN_FIELD: field name to read from the Rows payload (default linkedin).
  • ROWS_SPREADSHEET_ID: Rows spreadsheet id (used when ROWS_LINKEDIN_URL is not set).
  • ROWS_TABLE_ID: Rows table id for the current followers table.
  • ROWS_RANGE: A1 range to read from Rows (default A1:E20).
  • INSTAGRAM_USERNAME: Instagram username to scrape via Blastup (default usfsoar).
  • 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 project
  • socials:smoke: checks local /api/socials/followers and fails if Instagram/LinkedIn are missing
  • socials:smoke:prod: checks deployed /api/socials/followers on https://usfsoar.vercel.app
  • instagram:sync: uses Playwright to fetch Instagram followers from Blastup and writes data/instagram-follower-count.json
  • bullsconnect: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 update data/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 update data/linkedin-follower-count.json (used by the daily sync workflow)

Project structure and key files

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 sets typescript.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 component
    • app/globals.css — global styles used by the App Router
    • app/about/page.tsx — about page
    • app/blogs/page.tsx — blogs listing page
    • app/current-projects/* — pages for current projects (IREC, TORITO, certifications)
    • app/past-projects/* — pages for past projects (PAST NSL, Hybrid)
    • app/positions/page.tsx — officer positions
    • app/shop/page.tsx and app/success/ — shop and checkout flow pages
    • app/sponsorships/page.tsx — sponsorship information page
    • app/api/ — Next.js route handlers; subfolders:
      • app/api/checkout/ — checkout API endpoints
      • app/api/contact/ — contact form handler endpoints
      • app/api/soar-members/ — membership-related APIs
      • app/api/socials/discord/route.ts — an example API route that forwards or handles Discord-related operations
      • app/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 page
    • blogs.tsx — blogs list / teaser component
    • contact.tsx — contact form UI used on contact pages
    • eboard-yearbook.tsx — officer yearbook / roster component
    • footer.tsx — site footer
    • hero.tsx — homepage hero/banner
    • irec.tsx — IREC project overview component
    • sponsorslideshow.tsx — sponsor slideshow component
    • multi-calendar.tsx — combined calendar UI used to show events
    • navbar.tsx — the main navigation bar included in layout.tsx
    • page-header.tsx — page header used across pages for consistent title/subtitle
    • sponsorships.tsx — sponsorship information
    • stats.tsx — site or membership statistics visualization (charts/metrics)
    • theme-provider.tsx — theme context/provider for dark/light mode and persists selection
    • torito.tsx, tra-certifications.tsx — project/certification components

    UI primitives (under components/ui/):

    • button.tsx — shared button component with variants
    • card.tsx — generic card container
    • input.tsx, label.tsx, textarea.tsx — form primitives used by contact and 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.css contains Tailwind and application-level CSS.


Configuration highlights

  • next.config.mjs:

    • turbopack.root set: 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).
    • images configuration: declares supported image formats (avif, webp) and device sizes used by Next/Image.
  • tailwind and PostCSS: configured through postcss.config.mjs and Tailwind installed in devDependencies.


Where to edit content

  • Pages and routes: edit files under app/ (each folder's page.tsx defines a route).
  • Global layout & header/footer: app/layout.tsx and components/navbar.tsx, components/footer.tsx.
  • Styles: Tailwind config and styles/globals.css or app/globals.css.
  • Images and static assets: public/.
  • Reusable UI: components/ and components/ui/.

Deployment

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.

Daily BullsConnect Sync with GitHub Actions

This repo includes a workflow at .github/workflows/bullsconnect-sync.yml that runs once per day and updates data/soar-member-count.json.

1) Create local auth session

Run once on your machine:

npm run bullsconnect:auth
npm run bullsconnect:sync

After login, this creates .auth/bullsconnect-storage.json.

2) Add GitHub secret

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

3) Push and run

Push this branch, then run the workflow manually once from the Actions tab (workflow_dispatch) to verify it works.

Notes

  • Scheduled workflows run from the repository default branch only.

  • The workflow commits changes only when data/soar-member-count.json actually 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.

Daily Instagram Sync with GitHub Actions

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:sync

to verify the scraping works locally.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors