Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
32fa916
updated cmd-f portal to view statement
marlotea Jun 2, 2026
4d1d8cb
fix: node.js setup failed
marlotea Jun 2, 2026
e2f5a36
fix: node.js build failed-- upgraded pnpm/action-setup version
marlotea Jun 2, 2026
e604abb
fix: node.js build failed-- removed pnpm cache (likely unnoticeable p…
marlotea Jun 2, 2026
4d5fff2
fix: add packages field to pnpm-workspace.yaml
marlotea Jun 3, 2026
9f5b915
updated pnpm/action-setup to v3 to match PR workflow file
marlotea Jun 4, 2026
1ebf934
removed and untracked .idea/
marlotea Jun 4, 2026
0ea0174
Merge pull request #60 from nwplus/leia/remove_cmd-f_references
marlotea Jun 4, 2026
e7f2531
fix: remove cmd-f from VALID_HACKATHONS and fix portal selection bugs
dakshshahani Jul 9, 2026
8a45dea
feat(my-ticket): add Google Wallet pass button
dakshshahani Aug 2, 2026
39824ae
fix(my-ticket): use dbCollectionName for Google Wallet pass
dakshshahani Aug 2, 2026
37ec12e
style(my-ticket): use native Google Wallet button look
dakshshahani Aug 2, 2026
413fc8e
feat(my-ticket): add hacker pass to Apple Wallet
dakshshahani Aug 3, 2026
df15395
fix(wallet): resolve private storage path for Apple Wallet pass
dakshshahani Aug 3, 2026
7a47cb1
feat(wallet): use condensed add-to-wallet badge and stack buttons
dakshshahani Aug 5, 2026
bb9ab45
fix():typesafety fixes
dakshshahani Aug 5, 2026
2c2de7f
Merge pull request #62 from nwplus/wallet
dakshshahani Aug 5, 2026
950e47d
fix: use node 24, pnpm 11, edit workflow files
geoff-jiang Aug 6, 2026
a3141da
Merge branch 'dev' into geoff/ci-standardization
geoff-jiang Aug 6, 2026
0637aca
Merge pull request #63 from nwplus/geoff/ci-standardization
geoff-jiang Aug 13, 2026
152177a
Merge branch 'main' into dev
geoff-jiang Aug 26, 2026
0c0d9ce
(fix): restore cmd-f
geoff-jiang Aug 27, 2026
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
70 changes: 70 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: CI

on:
pull_request:
branches: [main, dev]

permissions:
contents: read

jobs:
validate:
name: Validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v6
with:
run_install: false

- name: Set up Node
uses: actions/setup-node@v7
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Check formatting and lint
run: pnpm check

- name: Check types and build
run: pnpm build

lighthouse:
name: Lighthouse
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v6
with:
run_install: false

- name: Set up Node
uses: actions/setup-node@v7
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build staging application
run: pnpm build
env:
VITE_FIREBASE_API_KEY: ${{ secrets.DEV_FIREBASE_API_KEY }}
VITE_FIREBASE_AUTH_DOMAIN: ${{ secrets.DEV_FIREBASE_AUTH_DOMAIN }}
VITE_FIREBASE_DATABASE_URL: ${{ secrets.DEV_FIREBASE_DATABASE_URL }}
VITE_FIREBASE_PROJECT_ID: ${{ secrets.DEV_FIREBASE_PROJECT_ID }}
VITE_FIREBASE_STORAGE_BUCKET: ${{ secrets.DEV_FIREBASE_STORAGE_BUCKET }}
VITE_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.DEV_FIREBASE_MESSAGING_SENDER_ID }}
VITE_FIREBASE_APP_ID: ${{ secrets.DEV_FIREBASE_APP_ID }}
VITE_FIREBASE_MEASUREMENT_ID: ${{ secrets.DEV_FIREBASE_MEASUREMENT_ID }}

- name: Run Lighthouse CI
run: pnpm exec lhci autorun
67 changes: 30 additions & 37 deletions .github/workflows/firebase-hosting-merge.yml
Original file line number Diff line number Diff line change
@@ -1,62 +1,55 @@
name: Deploy to Firebase Hosting on merge
name: Deploy Firebase Hosting

on:
push:
branches: [main, dev]

permissions:
contents: read

jobs:
build_and_deploy:
name: Build and deploy
runs-on: ubuntu-latest
concurrency:
group: portal-v2-${{ github.ref_name }}
cancel-in-progress: false
env:
IS_PRODUCTION: ${{ endsWith(github.ref, 'main') }}
IS_PRODUCTION: ${{ github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v6
with:
version: 9.12.3
run_install: false

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'

- name: Set up firebase
run: pnpm add -g firebase-tools
- name: Set up Node
uses: actions/setup-node@v7
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build with dev env variables
if: ${{ env.IS_PRODUCTION != 'true' }}
- name: Build application
run: pnpm build
env:
VITE_FIREBASE_API_KEY: ${{ secrets.DEV_FIREBASE_API_KEY }}
VITE_FIREBASE_AUTH_DOMAIN: ${{ secrets.DEV_FIREBASE_AUTH_DOMAIN }}
VITE_FIREBASE_DATABASE_URL: ${{ secrets.DEV_FIREBASE_DATABASE_URL }}
VITE_FIREBASE_PROJECT_ID: ${{ secrets.DEV_FIREBASE_PROJECT_ID }}
VITE_FIREBASE_STORAGE_BUCKET: ${{ secrets.DEV_FIREBASE_STORAGE_BUCKET }}
VITE_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.DEV_FIREBASE_MESSAGING_SENDER_ID }}
VITE_FIREBASE_APP_ID: ${{ secrets.DEV_FIREBASE_APP_ID }}
VITE_FIREBASE_MEASUREMENT_ID: ${{ secrets.DEV_FIREBASE_MEASUREMENT_ID }}

- name: Build with prod env variables
if: ${{ env.IS_PRODUCTION == 'true' }}
run: pnpm build
env:
VITE_FIREBASE_API_KEY: ${{ secrets.FIREBASE_API_KEY }}
VITE_FIREBASE_AUTH_DOMAIN: ${{ secrets.FIREBASE_AUTH_DOMAIN }}
VITE_FIREBASE_DATABASE_URL: ${{ secrets.FIREBASE_DATABASE_URL }}
VITE_FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }}
VITE_FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }}
VITE_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.FIREBASE_MESSAGING_SENDER_ID }}
VITE_FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}
VITE_FIREBASE_MEASUREMENT_ID: ${{ secrets.FIREBASE_MEASUREMENT_ID }}
VITE_FIREBASE_API_KEY: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_API_KEY || secrets.DEV_FIREBASE_API_KEY }}
VITE_FIREBASE_AUTH_DOMAIN: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_AUTH_DOMAIN || secrets.DEV_FIREBASE_AUTH_DOMAIN }}
VITE_FIREBASE_DATABASE_URL: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_DATABASE_URL || secrets.DEV_FIREBASE_DATABASE_URL }}
VITE_FIREBASE_PROJECT_ID: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_PROJECT_ID || secrets.DEV_FIREBASE_PROJECT_ID }}
VITE_FIREBASE_STORAGE_BUCKET: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_STORAGE_BUCKET || secrets.DEV_FIREBASE_STORAGE_BUCKET }}
VITE_FIREBASE_MESSAGING_SENDER_ID: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_MESSAGING_SENDER_ID || secrets.DEV_FIREBASE_MESSAGING_SENDER_ID }}
VITE_FIREBASE_APP_ID: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_APP_ID || secrets.DEV_FIREBASE_APP_ID }}
VITE_FIREBASE_MEASUREMENT_ID: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_MEASUREMENT_ID || secrets.DEV_FIREBASE_MEASUREMENT_ID }}

- name: Deploy to Firebase
uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ env.IS_PRODUCTION == 'true' && secrets.FIREBASE_SERVICE_ACCOUNT_NWPLUS_UBC || secrets.FIREBASE_SERVICE_ACCOUNT_NWPLUS_UBC_DEV }}
projectId: ${{ env.IS_PRODUCTION == 'true' && 'nwplus-ubc' || 'nwplus-ubc-dev' }}
channelId: live
projectId: ${{ env.IS_PRODUCTION == 'true' && 'nwplus-ubc' || 'nwplus-ubc-dev' }}
target: ${{ env.IS_PRODUCTION == 'true' && 'nwplus-ubc' || 'nwplus-ubc-dev' }}
35 changes: 24 additions & 11 deletions .github/workflows/firebase-hosting-pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
name: Deploy to Firebase Hosting on PR
on: pull_request
name: Deploy Firebase Hosting Preview

on:
pull_request:
branches: [main, dev]

permissions:
checks: write
contents: read
pull-requests: write

jobs:
build_and_preview:
name: Deploy preview
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v6
with:
version: 9.12.3
run_install: false

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- name: Set up Node
uses: actions/setup-node@v7
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build
- name: Build preview
run: pnpm build
env:
VITE_FIREBASE_API_KEY: ${{ secrets.DEV_FIREBASE_API_KEY }}
Expand All @@ -36,6 +48,7 @@ jobs:
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_NWPLUS_UBC_DEV }}
channelId: pr${{ github.event.pull_request.number }}-${{ github.run_id }}
expires: 10d
projectId: nwplus-ubc-dev
target: nwplus-ubc-dev
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
node_modules
.lighthouseci
.DS_Store
dist
dist-ssr
*.local
.claude

.env
.env
.idea/
6 changes: 3 additions & 3 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
if ! pnpm biome check; then
echo "To apply the suggested fixes, run the command: pnpm lint"
if ! pnpm check; then
echo "To apply the suggested fixes, run the command: pnpm check:write"
exit 1
fi
fi
30 changes: 30 additions & 0 deletions .lighthouserc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"ci": {
"collect": {
"staticDistDir": "./dist",
"isSinglePageApplication": true
},
"assert": {
"assertions": {
"first-contentful-paint": ["warn", { "minScore": 0.1 }],
"largest-contentful-paint": ["warn", { "minScore": 0.5 }],
"document-title": ["error", { "minScore": 0.9 }],
"meta-description": ["warn", { "minScore": 0.9 }],
"is-crawlable": ["error", { "minScore": 0.9 }],
"color-contrast": "off",
"service-worker": "off",
"uses-http2": "off",
"works-offline": "off",
"offline-start-url": "off",
"unminified-javascript": "off",
"unused-javascript": "off",
"render-blocking-resources": "off",
"uses-long-cache-ttl": "off",
"bf-cache": "off"
}
},
"upload": {
"target": "temporary-public-storage"
}
}
}
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All-in-one platform to support nwPlus' hackathons 🚀
## Development instructions

### Setup
1. Install [pnpm](https://pnpm.io/installation)
1. Install Node 24 (`nvm use` if you use nvm) and pnpm 11.10.0.
2. Add a `.env` file with the Firebase config (use the dev secrets)
```bash
VITE_FIREBASE_API_KEY=your_api_key
Expand Down Expand Up @@ -57,6 +57,7 @@ When adding a new component from shadcn or another component library, replace al
This project uses [Biome](https://biomejs.dev/) for linting and formatting. The following scripts are available:

```bash
pnpm check # verifies formatting and lint without changing files
pnpm check:write # applies safe formatting and lint fixes
```

Expand Down
74 changes: 40 additions & 34 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,63 +1,69 @@
{
"name": "portal-v2",
"private": true,
"packageManager": "pnpm@11.10.0",
"engines": {
"node": ">=24 <25"
},
"type": "module",
"scripts": {
"dev": "vite --port 3000",
"start": "vite --port 3000",
"build": "vite build && tsc",
"serve": "vite preview",
"lint": "biome check --write",
"prepare": "husky",
"preinstall": "npx only-allow pnpm"
"check": "biome check",
"check:write": "biome check --write",
"lint": "biome lint",
"prepare": "husky"
},
"dependencies": {
"@base-ui-components/react": "1.0.0-beta.6",
"@hookform/resolvers": "^5.2.2",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tailwindcss/vite": "^4.0.6",
"@tanstack/react-router": "^1.114.3",
"@tanstack/react-router-devtools": "^1.114.3",
"@tanstack/react-virtual": "^3.13.12",
"@tanstack/router-plugin": "^1.114.3",
"@hookform/resolvers": "^5.5.7",
"@radix-ui/react-accordion": "^1.2.20",
"@radix-ui/react-avatar": "^1.2.6",
"@radix-ui/react-checkbox": "^1.3.11",
"@radix-ui/react-dialog": "^1.1.23",
"@radix-ui/react-label": "^2.1.15",
"@radix-ui/react-radio-group": "^1.4.7",
"@radix-ui/react-separator": "^1.1.15",
"@radix-ui/react-slot": "^1.3.3",
"@radix-ui/react-tabs": "^1.1.21",
"@radix-ui/react-tooltip": "^1.2.16",
"@tailwindcss/vite": "^4.3.3",
"@tanstack/react-router": "^1.170.18",
"@tanstack/react-router-devtools": "^1.167.0",
"@tanstack/react-virtual": "^3.14.9",
"@tanstack/router-plugin": "^1.168.23",
"canvas-confetti": "^1.9.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"firebase": "^11.9.1",
"firebase": "^11.10.0",
"html-to-image": "^1.11.13",
"lucide-react": "^0.476.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-draggable": "^4.4.6",
"react-hook-form": "^7.66.0",
"react": "^19.2.8",
"react-dom": "^19.2.8",
"react-draggable": "^4.7.1",
"react-hook-form": "^7.83.0",
"react-markdown": "^10.1.0",
"react-pageflip": "^2.0.3",
"react-qr-code": "^2.0.18",
"react-qr-code": "^2.2.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.0.2",
"tailwindcss": "^4.0.6",
"tailwind-merge": "^3.6.0",
"tailwindcss": "^4.3.3",
"tailwindcss-animate": "^1.0.7",
"zod": "^4.1.5",
"zustand": "^5.0.5"
"zod": "^4.4.3",
"zustand": "^5.0.14"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@lhci/cli": "0.15.1",
"@types/canvas-confetti": "^1.9.0",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"@vitejs/plugin-react": "^4.3.4",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^4.7.0",
"husky": "^9.1.7",
"typescript": "^5.7.2",
"vite": "^6.1.0",
"typescript": "^5.9.3",
"vite": "^6.4.3",
"web-vitals": "^4.2.4"
}
}
Loading