diff --git a/.env.example b/.env.example index 68b512594..169405d68 100644 --- a/.env.example +++ b/.env.example @@ -19,7 +19,6 @@ DISCORD_DEV_VERIFY_CHANNEL_ID="52872856278050172988890" DISCORD_PROD_SERVER_ID="528728562780501729853789" DISCORD_PROD_VERIFY_CHANNEL_ID="5287378262780501729853789" DISCORD_SECRET_TOKEN="FHBAHJABDhbHSUeyi7398.S72ljd.HKBVAfug73gifa-74gfwiyB-BHJBDHV07hAJf83" -NODE_ENV="development" INTERNAL_AUTH_KEY="bwgybgidbsi-4784gyfgs-475hhkdsbfs-bwgybgidbsi-4784gyfgs-475hhkdsbfs-bwgybgidbsi-4784gyfgs-475hhkdsbfs-fbnauib4783-bhfbsjfbs" NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_YRGIBHSBIbabffjdhvbuYGI7BK" NEXT_PUBLIC_CLERK_SIGN_IN_URL="/sign-in" @@ -39,5 +38,5 @@ R2_BUCKET_NAME="your-org-name-userdata" R2_SECRET_ACCESS_KEY="279y45g79tgbjsbfhbsiufhbs89hg487hsiufs" TURSO_AUTH_TOKEN="dhbBDSUGFBSUYGBSIUGRBIGBSIYBS7495w8y97w.bivsb7478wGYIFGDSUGFS48y39975y3gtyugysjgs7ugu.BHFBSYUFBSV476guysfuw78gfuy3buybfshbfYUFSGVBYFIBVEIUSBVJSBANIBA74y597bvs6gfusg&gsyjgbfshgbyIGBYUS" TURSO_DATABASE_URL="libsql:hackkit-orgname.turso.io" -UPSTASH_REDIS_REST_TOKEN="BKFSHBSIY7g9347385gBJFDBSJYFGBSIYFUSIBISUYHGOSHIYtusvufdbsfiubfsibYBG" -UPSTASH_REDIS_REST_URL="https://giant-worm-78102.upstash.io" +# UPSTASH_REDIS_REST_TOKEN="BKFSHBSIY7g9347385gBJFDBSJYFGBSIYFUSIBISUYHGOSHIYtusvufdbsfiubfsibYBG" +# UPSTASH_REDIS_REST_URL="https://giant-worm-78102.upstash.io" diff --git a/apps/web/.gitignore b/apps/web/.gitignore index 867448ea4..53f894294 100644 --- a/apps/web/.gitignore +++ b/apps/web/.gitignore @@ -36,4 +36,6 @@ next-env.d.ts # react-email .react-email/ -certificates \ No newline at end of file +certificates +.open-next/ +.wrangler/ \ No newline at end of file diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs index f98177b11..4f154cd7a 100644 --- a/apps/web/next.config.mjs +++ b/apps/web/next.config.mjs @@ -21,6 +21,11 @@ const nextConfig = { ], }, experimental: { + outputFileTracingIncludes: { + "/*": [ + "../../node_modules/.pnpm/@libsql+isomorphic-ws@0.1.5/node_modules/@libsql/isomorphic-ws/**/*", + ], + }, serverActions: { allowedOrigins: ["localhost:3000"], }, diff --git a/apps/web/open-next.config.ts b/apps/web/open-next.config.ts new file mode 100644 index 000000000..ffd988785 --- /dev/null +++ b/apps/web/open-next.config.ts @@ -0,0 +1,3 @@ +import { defineCloudflareConfig } from "@opennextjs/cloudflare"; + +export default defineCloudflareConfig(); diff --git a/apps/web/package.json b/apps/web/package.json index 55eed01f9..9a6529e8f 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -7,6 +7,10 @@ "build": "pnpm with-env next build", "start": "pnpm with-env next start", "lint": "next lint", + "preview": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare preview", + "deploy": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare deploy", + "upload": "opennextjs-cloudflare build --dangerouslyUseUnsupportedNextVersion && opennextjs-cloudflare upload", + "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts", "with-env": "dotenv -e ../../.env --" }, "dependencies": { @@ -15,6 +19,7 @@ "@clerk/nextjs": "^6.12.12", "@hookform/resolvers": "^3.9.0", "@internationalized/date": "^3.5.4", + "@opennextjs/cloudflare": "^1.20.0", "@planetscale/database": "^1.18.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.1.1", @@ -47,6 +52,7 @@ "embla-carousel": "8.1.7", "embla-carousel-react": "8.1.7", "lucide-react": "^0.411.0", + "motion": "^12.38.0", "nanoid": "^5.0.7", "next": "14.2.35", "next-safe-action": "^7.9.3", @@ -83,6 +89,7 @@ "postcss": "8.4.39", "tailwindcss": "3.4.6", "tailwindcss-animate": "1.0.7", - "typescript": "5.5.3" + "typescript": "5.5.3", + "wrangler": "^4.105.0" } -} +} \ No newline at end of file diff --git a/apps/web/public/img/assets/about/about.webp b/apps/web/public/img/assets/about/about.webp new file mode 100644 index 000000000..19b91989e Binary files /dev/null and b/apps/web/public/img/assets/about/about.webp differ diff --git a/apps/web/public/img/assets/about/about1.webp b/apps/web/public/img/assets/about/about1.webp new file mode 100644 index 000000000..0afca06b5 Binary files /dev/null and b/apps/web/public/img/assets/about/about1.webp differ diff --git a/apps/web/public/img/assets/about/about2.webp b/apps/web/public/img/assets/about/about2.webp new file mode 100644 index 000000000..a55928f2b Binary files /dev/null and b/apps/web/public/img/assets/about/about2.webp differ diff --git a/apps/web/public/img/assets/about/about_photos.webp b/apps/web/public/img/assets/about/about_photos.webp new file mode 100644 index 000000000..b10703b25 Binary files /dev/null and b/apps/web/public/img/assets/about/about_photos.webp differ diff --git a/apps/web/public/img/assets/about/confidential.svg b/apps/web/public/img/assets/about/confidential.svg new file mode 100644 index 000000000..3be79477c --- /dev/null +++ b/apps/web/public/img/assets/about/confidential.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/public/img/assets/background.webp b/apps/web/public/img/assets/background.webp new file mode 100644 index 000000000..78588958f Binary files /dev/null and b/apps/web/public/img/assets/background.webp differ diff --git a/apps/web/public/img/assets/buttons/blank-tape-stickers1.webp b/apps/web/public/img/assets/buttons/blank-tape-stickers1.webp new file mode 100644 index 000000000..a216030dd Binary files /dev/null and b/apps/web/public/img/assets/buttons/blank-tape-stickers1.webp differ diff --git a/apps/web/public/img/assets/buttons/blank-tape-stickers2.webp b/apps/web/public/img/assets/buttons/blank-tape-stickers2.webp new file mode 100644 index 000000000..69ebe0066 Binary files /dev/null and b/apps/web/public/img/assets/buttons/blank-tape-stickers2.webp differ diff --git a/apps/web/public/img/assets/dash/have-questions-background.webp b/apps/web/public/img/assets/dash/have-questions-background.webp new file mode 100644 index 000000000..65954cb1d Binary files /dev/null and b/apps/web/public/img/assets/dash/have-questions-background.webp differ diff --git a/apps/web/public/img/assets/dash/lable-vertical.webp b/apps/web/public/img/assets/dash/lable-vertical.webp new file mode 100644 index 000000000..c2d02e6b7 Binary files /dev/null and b/apps/web/public/img/assets/dash/lable-vertical.webp differ diff --git a/apps/web/public/img/assets/dash/lable.webp b/apps/web/public/img/assets/dash/lable.webp new file mode 100644 index 000000000..1d2608a15 Binary files /dev/null and b/apps/web/public/img/assets/dash/lable.webp differ diff --git a/apps/web/public/img/assets/dash/lable1.webp b/apps/web/public/img/assets/dash/lable1.webp new file mode 100644 index 000000000..b347c78a3 Binary files /dev/null and b/apps/web/public/img/assets/dash/lable1.webp differ diff --git a/apps/web/public/img/assets/dash/lable2.webp b/apps/web/public/img/assets/dash/lable2.webp new file mode 100644 index 000000000..e1e84660a Binary files /dev/null and b/apps/web/public/img/assets/dash/lable2.webp differ diff --git a/apps/web/public/img/assets/dash/time-background.webp b/apps/web/public/img/assets/dash/time-background.webp new file mode 100644 index 000000000..299aeeeb2 Binary files /dev/null and b/apps/web/public/img/assets/dash/time-background.webp differ diff --git a/apps/web/public/img/assets/faq/FAQ.svg b/apps/web/public/img/assets/faq/FAQ.svg new file mode 100644 index 000000000..d81364c37 --- /dev/null +++ b/apps/web/public/img/assets/faq/FAQ.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/web/public/img/assets/faq/classified.svg b/apps/web/public/img/assets/faq/classified.svg new file mode 100644 index 000000000..3c28ea320 --- /dev/null +++ b/apps/web/public/img/assets/faq/classified.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/public/img/assets/faq/finger-print.svg b/apps/web/public/img/assets/faq/finger-print.svg new file mode 100644 index 000000000..0621837d8 --- /dev/null +++ b/apps/web/public/img/assets/faq/finger-print.svg @@ -0,0 +1,3233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/public/img/assets/faq/marker-circle4.svg b/apps/web/public/img/assets/faq/marker-circle4.svg new file mode 100644 index 000000000..a7ffd681d --- /dev/null +++ b/apps/web/public/img/assets/faq/marker-circle4.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/apps/web/public/img/assets/footer/discord_icon.svg b/apps/web/public/img/assets/footer/discord_icon.svg new file mode 100644 index 000000000..7f9a31f02 --- /dev/null +++ b/apps/web/public/img/assets/footer/discord_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/web/public/img/assets/footer/rh-city-logo-black.svg b/apps/web/public/img/assets/footer/rh-city-logo-black.svg new file mode 100644 index 000000000..e19810763 --- /dev/null +++ b/apps/web/public/img/assets/footer/rh-city-logo-black.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/web/public/img/assets/hero/hero.webp b/apps/web/public/img/assets/hero/hero.webp new file mode 100644 index 000000000..233f3bf79 Binary files /dev/null and b/apps/web/public/img/assets/hero/hero.webp differ diff --git a/apps/web/public/img/assets/hero/logo-background.webp b/apps/web/public/img/assets/hero/logo-background.webp new file mode 100644 index 000000000..8c5252af0 Binary files /dev/null and b/apps/web/public/img/assets/hero/logo-background.webp differ diff --git a/apps/web/public/img/assets/hero/marker-circle3.svg b/apps/web/public/img/assets/hero/marker-circle3.svg new file mode 100644 index 000000000..42ee55847 --- /dev/null +++ b/apps/web/public/img/assets/hero/marker-circle3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/web/public/img/assets/hero/register/blank-tape-stickers3.webp b/apps/web/public/img/assets/hero/register/blank-tape-stickers3.webp new file mode 100644 index 000000000..1fc26a561 Binary files /dev/null and b/apps/web/public/img/assets/hero/register/blank-tape-stickers3.webp differ diff --git a/apps/web/public/img/assets/hero/rh-logo.svg b/apps/web/public/img/assets/hero/rh-logo.svg new file mode 100644 index 000000000..e19810763 --- /dev/null +++ b/apps/web/public/img/assets/hero/rh-logo.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/web/public/img/assets/hero/top-secret.svg b/apps/web/public/img/assets/hero/top-secret.svg new file mode 100644 index 000000000..9c6497885 --- /dev/null +++ b/apps/web/public/img/assets/hero/top-secret.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/web/public/img/assets/logo_stamp.webp b/apps/web/public/img/assets/logo_stamp.webp new file mode 100644 index 000000000..c6216b40f Binary files /dev/null and b/apps/web/public/img/assets/logo_stamp.webp differ diff --git a/apps/web/public/img/assets/map/SP1.webp b/apps/web/public/img/assets/map/SP1.webp new file mode 100644 index 000000000..1256d12e6 Binary files /dev/null and b/apps/web/public/img/assets/map/SP1.webp differ diff --git a/apps/web/public/img/assets/map/main-campus.webp b/apps/web/public/img/assets/map/main-campus.webp new file mode 100644 index 000000000..ede72a3f2 Binary files /dev/null and b/apps/web/public/img/assets/map/main-campus.webp differ diff --git a/apps/web/public/img/assets/map/map-background.webp b/apps/web/public/img/assets/map/map-background.webp new file mode 100644 index 000000000..f21f2d98a Binary files /dev/null and b/apps/web/public/img/assets/map/map-background.webp differ diff --git a/apps/web/public/img/assets/map/pin4.webp b/apps/web/public/img/assets/map/pin4.webp new file mode 100644 index 000000000..6e743e0ca Binary files /dev/null and b/apps/web/public/img/assets/map/pin4.webp differ diff --git a/apps/web/public/img/assets/map/pin5.webp b/apps/web/public/img/assets/map/pin5.webp new file mode 100644 index 000000000..43c3f3988 Binary files /dev/null and b/apps/web/public/img/assets/map/pin5.webp differ diff --git a/apps/web/public/img/assets/map/red-circle1.svg b/apps/web/public/img/assets/map/red-circle1.svg new file mode 100644 index 000000000..2115c8d6c --- /dev/null +++ b/apps/web/public/img/assets/map/red-circle1.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/apps/web/public/img/assets/menu/menu.webp b/apps/web/public/img/assets/menu/menu.webp new file mode 100644 index 000000000..15773359c Binary files /dev/null and b/apps/web/public/img/assets/menu/menu.webp differ diff --git a/apps/web/public/img/assets/menu/pin1.webp b/apps/web/public/img/assets/menu/pin1.webp new file mode 100644 index 000000000..e65003604 Binary files /dev/null and b/apps/web/public/img/assets/menu/pin1.webp differ diff --git a/apps/web/public/img/assets/red-thread.svg b/apps/web/public/img/assets/red-thread.svg new file mode 100644 index 000000000..941cb588f --- /dev/null +++ b/apps/web/public/img/assets/red-thread.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/web/public/img/assets/silver-pin.svg b/apps/web/public/img/assets/silver-pin.svg new file mode 100644 index 000000000..79e8976d7 --- /dev/null +++ b/apps/web/public/img/assets/silver-pin.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/public/img/assets/team/Abrar Ahmed.webp b/apps/web/public/img/assets/team/Abrar Ahmed.webp new file mode 100644 index 000000000..5aedaf95a Binary files /dev/null and b/apps/web/public/img/assets/team/Abrar Ahmed.webp differ diff --git a/apps/web/public/img/assets/team/Alekzander Brysch.webp b/apps/web/public/img/assets/team/Alekzander Brysch.webp new file mode 100644 index 000000000..a45580e6c Binary files /dev/null and b/apps/web/public/img/assets/team/Alekzander Brysch.webp differ diff --git a/apps/web/public/img/assets/team/Anam Sultana.webp b/apps/web/public/img/assets/team/Anam Sultana.webp new file mode 100644 index 000000000..1e6c49515 Binary files /dev/null and b/apps/web/public/img/assets/team/Anam Sultana.webp differ diff --git a/apps/web/public/img/assets/team/Anh Doan.webp b/apps/web/public/img/assets/team/Anh Doan.webp new file mode 100644 index 000000000..5bf2170b9 Binary files /dev/null and b/apps/web/public/img/assets/team/Anh Doan.webp differ diff --git a/apps/web/public/img/assets/team/Ash Hernandez.webp b/apps/web/public/img/assets/team/Ash Hernandez.webp new file mode 100644 index 000000000..c137f02eb Binary files /dev/null and b/apps/web/public/img/assets/team/Ash Hernandez.webp differ diff --git a/apps/web/public/img/assets/team/Blessy Kalluri.webp b/apps/web/public/img/assets/team/Blessy Kalluri.webp new file mode 100644 index 000000000..903164efe Binary files /dev/null and b/apps/web/public/img/assets/team/Blessy Kalluri.webp differ diff --git a/apps/web/public/img/assets/team/Camille Hart.webp b/apps/web/public/img/assets/team/Camille Hart.webp new file mode 100644 index 000000000..9874235c2 Binary files /dev/null and b/apps/web/public/img/assets/team/Camille Hart.webp differ diff --git a/apps/web/public/img/assets/team/Cayden Hutcheson.webp b/apps/web/public/img/assets/team/Cayden Hutcheson.webp new file mode 100644 index 000000000..3f5644f0e Binary files /dev/null and b/apps/web/public/img/assets/team/Cayden Hutcheson.webp differ diff --git a/apps/web/public/img/assets/team/Diego Medina.webp b/apps/web/public/img/assets/team/Diego Medina.webp new file mode 100644 index 000000000..6dded570b Binary files /dev/null and b/apps/web/public/img/assets/team/Diego Medina.webp differ diff --git a/apps/web/public/img/assets/team/Dyshana Torres Rivera.webp b/apps/web/public/img/assets/team/Dyshana Torres Rivera.webp new file mode 100644 index 000000000..6dded570b Binary files /dev/null and b/apps/web/public/img/assets/team/Dyshana Torres Rivera.webp differ diff --git a/apps/web/public/img/assets/team/Elisa Moran.webp b/apps/web/public/img/assets/team/Elisa Moran.webp new file mode 100644 index 000000000..6dded570b Binary files /dev/null and b/apps/web/public/img/assets/team/Elisa Moran.webp differ diff --git a/apps/web/public/img/assets/team/Eric Lee.webp b/apps/web/public/img/assets/team/Eric Lee.webp new file mode 100644 index 000000000..c478514fa Binary files /dev/null and b/apps/web/public/img/assets/team/Eric Lee.webp differ diff --git a/apps/web/public/img/assets/team/Evelynn Donaldson.webp b/apps/web/public/img/assets/team/Evelynn Donaldson.webp new file mode 100644 index 000000000..dd488412b Binary files /dev/null and b/apps/web/public/img/assets/team/Evelynn Donaldson.webp differ diff --git a/apps/web/public/img/assets/team/Francisco Epinoza.webp b/apps/web/public/img/assets/team/Francisco Epinoza.webp new file mode 100644 index 000000000..4c2279de7 Binary files /dev/null and b/apps/web/public/img/assets/team/Francisco Epinoza.webp differ diff --git a/apps/web/public/img/assets/team/Josie Sauceda.webp b/apps/web/public/img/assets/team/Josie Sauceda.webp new file mode 100644 index 000000000..df0cc998b Binary files /dev/null and b/apps/web/public/img/assets/team/Josie Sauceda.webp differ diff --git a/apps/web/public/img/assets/team/Layla Mendiola.webp b/apps/web/public/img/assets/team/Layla Mendiola.webp new file mode 100644 index 000000000..6dded570b Binary files /dev/null and b/apps/web/public/img/assets/team/Layla Mendiola.webp differ diff --git a/apps/web/public/img/assets/team/Martin Llano.webp b/apps/web/public/img/assets/team/Martin Llano.webp new file mode 100644 index 000000000..d19e39645 Binary files /dev/null and b/apps/web/public/img/assets/team/Martin Llano.webp differ diff --git a/apps/web/public/img/assets/team/Maryna Korolova.webp b/apps/web/public/img/assets/team/Maryna Korolova.webp new file mode 100644 index 000000000..9ffab9652 Binary files /dev/null and b/apps/web/public/img/assets/team/Maryna Korolova.webp differ diff --git a/apps/web/public/img/assets/team/Miguel Oseguera.webp b/apps/web/public/img/assets/team/Miguel Oseguera.webp new file mode 100644 index 000000000..9172229f6 Binary files /dev/null and b/apps/web/public/img/assets/team/Miguel Oseguera.webp differ diff --git a/apps/web/public/img/assets/team/Paula Com.webp b/apps/web/public/img/assets/team/Paula Com.webp new file mode 100644 index 000000000..0faf72410 Binary files /dev/null and b/apps/web/public/img/assets/team/Paula Com.webp differ diff --git a/apps/web/public/img/assets/team/Reese Sylvester.webp b/apps/web/public/img/assets/team/Reese Sylvester.webp new file mode 100644 index 000000000..fc0a9785b Binary files /dev/null and b/apps/web/public/img/assets/team/Reese Sylvester.webp differ diff --git a/apps/web/public/img/assets/team/Rufat Niftaliyev.webp b/apps/web/public/img/assets/team/Rufat Niftaliyev.webp new file mode 100644 index 000000000..85bfb80a3 Binary files /dev/null and b/apps/web/public/img/assets/team/Rufat Niftaliyev.webp differ diff --git a/apps/web/public/img/assets/team/Savanah Schaefer.webp b/apps/web/public/img/assets/team/Savanah Schaefer.webp new file mode 100644 index 000000000..73fbd969b Binary files /dev/null and b/apps/web/public/img/assets/team/Savanah Schaefer.webp differ diff --git a/apps/web/public/img/assets/team/Scherly Ramirez.webp b/apps/web/public/img/assets/team/Scherly Ramirez.webp new file mode 100644 index 000000000..6dded570b Binary files /dev/null and b/apps/web/public/img/assets/team/Scherly Ramirez.webp differ diff --git a/apps/web/public/img/assets/team/Shaun Philippe.webp b/apps/web/public/img/assets/team/Shaun Philippe.webp new file mode 100644 index 000000000..a9f5fdfd6 Binary files /dev/null and b/apps/web/public/img/assets/team/Shaun Philippe.webp differ diff --git a/apps/web/public/img/assets/team/Tochi Kalu.webp b/apps/web/public/img/assets/team/Tochi Kalu.webp new file mode 100644 index 000000000..6dded570b Binary files /dev/null and b/apps/web/public/img/assets/team/Tochi Kalu.webp differ diff --git a/apps/web/public/img/assets/team/Tri Nguyen.webp b/apps/web/public/img/assets/team/Tri Nguyen.webp new file mode 100644 index 000000000..0bf8c32c8 Binary files /dev/null and b/apps/web/public/img/assets/team/Tri Nguyen.webp differ diff --git a/apps/web/public/img/assets/team/Victoria Rivas.webp b/apps/web/public/img/assets/team/Victoria Rivas.webp new file mode 100644 index 000000000..6dded570b Binary files /dev/null and b/apps/web/public/img/assets/team/Victoria Rivas.webp differ diff --git a/apps/web/public/img/logo/rh-logo-black.png b/apps/web/public/img/logo/rh-logo-black.png new file mode 100644 index 000000000..61d7a6a3a Binary files /dev/null and b/apps/web/public/img/logo/rh-logo-black.png differ diff --git a/apps/web/public/img/logo/rh-logo-black.svg b/apps/web/public/img/logo/rh-logo-black.svg new file mode 100644 index 000000000..6f130b5e3 --- /dev/null +++ b/apps/web/public/img/logo/rh-logo-black.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/web/public/img/partner-logos/HEB.svg b/apps/web/public/img/partner-logos/HEB.svg new file mode 100644 index 000000000..0a43d02b7 --- /dev/null +++ b/apps/web/public/img/partner-logos/HEB.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/apps/web/public/img/powered-by-vercel.svg b/apps/web/public/img/powered-by-vercel.svg deleted file mode 100644 index 877828684..000000000 --- a/apps/web/public/img/powered-by-vercel.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/apps/web/public/img/sponsors/empty-paper.svg b/apps/web/public/img/sponsors/empty-paper.svg new file mode 100644 index 000000000..bd7b012cb --- /dev/null +++ b/apps/web/public/img/sponsors/empty-paper.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/public/img/sponsors/sponsors-background.png b/apps/web/public/img/sponsors/sponsors-background.png new file mode 100644 index 000000000..72e17df98 Binary files /dev/null and b/apps/web/public/img/sponsors/sponsors-background.png differ diff --git a/apps/web/public/img/sponsors/sponsors-background.svg b/apps/web/public/img/sponsors/sponsors-background.svg new file mode 100644 index 000000000..b1220ae65 --- /dev/null +++ b/apps/web/public/img/sponsors/sponsors-background.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/public/img/sponsors/sponsors-header-background.svg b/apps/web/public/img/sponsors/sponsors-header-background.svg new file mode 100644 index 000000000..35ccf396d --- /dev/null +++ b/apps/web/public/img/sponsors/sponsors-header-background.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/actions/admin/modify-nav-item.ts b/apps/web/src/actions/admin/modify-nav-item.ts deleted file mode 100644 index 354075255..000000000 --- a/apps/web/src/actions/admin/modify-nav-item.ts +++ /dev/null @@ -1,111 +0,0 @@ -"use server"; - -import { z } from "zod"; -import { adminAction } from "@/lib/safe-action"; -import { redisSAdd, redisHSet, removeNavItem } from "@/lib/utils/server/redis"; -import { revalidatePath } from "next/cache"; - -import { Redis } from "@upstash/redis"; -import { userHasPermission } from "@/lib/utils/server/admin"; -import { PermissionType } from "@/lib/constants/permission"; - -const redis = Redis.fromEnv(); - -const metadataSchema = z.object({ - name: z.string().min(1), - url: z.string().min(1), -}); - -const editMetadataSchema = metadataSchema.extend({ - existingName: z.string().min(1), - enabled: z.boolean(), -}); - -// Maybe a better way to do this for revalidation? Who knows. -const navAdminPage = "/admin/toggles/landing"; - -export const setItem = adminAction - .schema(metadataSchema) - .action(async ({ parsedInput: { name, url }, ctx: { user, userId } }) => { - if (!userHasPermission(user, PermissionType.MANAGE_NAVLINKS)) { - throw new Error( - "You do not have permission to manage navigation links.", - ); - } - - await redisSAdd("config:navitemslist", encodeURIComponent(name)); - await redisHSet(`config:navitems:${encodeURIComponent(name)}`, { - url, - name, - enabled: true, - }); - revalidatePath(navAdminPage); - return { success: true }; - }); - -export const editItem = adminAction - .schema(editMetadataSchema) - .action( - async ({ parsedInput: { name, url, existingName }, ctx: { user } }) => { - if (!userHasPermission(user, PermissionType.MANAGE_NAVLINKS)) { - throw new Error( - "You do not have permission to manage navigation links.", - ); - } - - const pipe = redis.pipeline(); - - if (existingName != name) { - pipe.srem( - "config:navitemslist", - encodeURIComponent(existingName), - ); - } - - pipe.sadd("config:navitemslist", encodeURIComponent(name)); - pipe.hset(`config:navitems:${encodeURIComponent(name)}`, { - url, - name, - enabled: true, - }); - - await pipe.exec(); - - revalidatePath(navAdminPage); - return { success: true }; - }, - ); - -export const removeItem = adminAction - .schema(z.string()) - .action(async ({ parsedInput: name, ctx: { user, userId } }) => { - if (!userHasPermission(user, PermissionType.MANAGE_NAVLINKS)) { - throw new Error( - "You do not have permission to manage navigation links.", - ); - } - await removeNavItem(name); - // await new Promise((resolve) => setTimeout(resolve, 1500)); - revalidatePath(navAdminPage); - return { success: true }; - }); - -export const toggleItem = adminAction - .schema(z.object({ name: z.string(), statusToSet: z.boolean() })) - .action( - async ({ - parsedInput: { name, statusToSet }, - ctx: { user, userId }, - }) => { - if (!userHasPermission(user, PermissionType.MANAGE_NAVLINKS)) { - throw new Error( - "You do not have permission to manage navigation links.", - ); - } - await redisHSet(`config:navitems:${encodeURIComponent(name)}`, { - enabled: statusToSet, - }); - revalidatePath(navAdminPage); - return { success: true, itemStatus: statusToSet }; - }, - ); diff --git a/apps/web/src/actions/admin/registration-actions.ts b/apps/web/src/actions/admin/registration-actions.ts deleted file mode 100644 index e62d70d4f..000000000 --- a/apps/web/src/actions/admin/registration-actions.ts +++ /dev/null @@ -1,75 +0,0 @@ -"use server"; - -import { z } from "zod"; -import { adminAction } from "@/lib/safe-action"; -import { redisSet } from "@/lib/utils/server/redis"; -import { revalidatePath } from "next/cache"; -import { userHasPermission } from "@/lib/utils/server/admin"; -import { PermissionType } from "@/lib/constants/permission"; - -const defaultRegistrationToggleSchema = z.object({ - enabled: z.boolean(), -}); - -const defaultRSVPLimitSchema = z.object({ - rsvpLimit: z.number(), -}); - -export const toggleRegistrationEnabled = adminAction - .schema(defaultRegistrationToggleSchema) - .action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => { - if (!userHasPermission(user, PermissionType.MANAGE_REGISTRATION)) { - throw new Error( - "You do not have permission to manage registration settings.", - ); - } - - await redisSet("config:registration:registrationEnabled", enabled); - revalidatePath("/admin/toggles/registration"); - return { success: true, statusSet: enabled }; - }); - -export const toggleRegistrationMessageEnabled = adminAction - .schema(defaultRegistrationToggleSchema) - .action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => { - if (!userHasPermission(user, PermissionType.MANAGE_REGISTRATION)) { - throw new Error( - "You do not have permission to manage registration settings.", - ); - } - - await redisSet( - "config:registration:registrationMessageEnabled", - enabled, - ); - revalidatePath("/admin/toggles/registration"); - return { success: true, statusSet: enabled }; - }); - -export const toggleRSVPs = adminAction - .schema(defaultRegistrationToggleSchema) - .action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => { - if (!userHasPermission(user, PermissionType.MANAGE_REGISTRATION)) { - throw new Error( - "You do not have permission to manage registration settings.", - ); - } - - await redisSet("config:registration:allowRSVPs", enabled); - revalidatePath("/admin/toggles/registration"); - return { success: true, statusSet: enabled }; - }); - -export const setRSVPLimit = adminAction - .schema(defaultRSVPLimitSchema) - .action(async ({ parsedInput: { rsvpLimit }, ctx: { user, userId } }) => { - if (!userHasPermission(user, PermissionType.MANAGE_REGISTRATION)) { - throw new Error( - "You do not have permission to manage registration settings.", - ); - } - - await redisSet("config:registration:maxRSVPs", rsvpLimit); - revalidatePath("/admin/toggles/registration"); - return { success: true, statusSet: rsvpLimit }; - }); diff --git a/apps/web/src/app/admin/layout.tsx b/apps/web/src/app/admin/layout.tsx index a28aff892..aa7f1306f 100644 --- a/apps/web/src/app/admin/layout.tsx +++ b/apps/web/src/app/admin/layout.tsx @@ -32,7 +32,7 @@ export default async function AdminLayout({ children }: AdminLayoutProps) { return ( <> - +
diff --git a/apps/web/src/app/admin/toggles/dashboard/page.tsx b/apps/web/src/app/admin/toggles/dashboard/page.tsx deleted file mode 100644 index c82873b71..000000000 --- a/apps/web/src/app/admin/toggles/dashboard/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Page() { - return

Coming soon

; -} diff --git a/apps/web/src/app/admin/toggles/landing/page.tsx b/apps/web/src/app/admin/toggles/landing/page.tsx deleted file mode 100644 index 0316c8a75..000000000 --- a/apps/web/src/app/admin/toggles/landing/page.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { - NavItemsManager, - AddNavItemDialog, -} from "@/components/admin/toggles/NavItemsManager"; -import { getAllNavItems } from "@/lib/utils/server/redis"; - -export default async function Page() { - const nav = await getAllNavItems(); - return ( -
-
-

- Navbar Items -

-
- -
-
- - a.name.localeCompare(b.name), - )} - /> -
- ); -} - -export const dynamic = "force-dynamic"; diff --git a/apps/web/src/app/admin/toggles/layout.tsx b/apps/web/src/app/admin/toggles/layout.tsx deleted file mode 100644 index 0a2eff345..000000000 --- a/apps/web/src/app/admin/toggles/layout.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import ToggleItem from "@/components/admin/toggles/ToggleItem"; -import Restricted from "@/components/Restricted"; -import { PermissionType } from "@/lib/constants/permission"; -import { userHasPermission } from "@/lib/utils/server/admin"; -import { getCurrentUser } from "@/lib/utils/server/user"; -import { notFound } from "next/navigation"; - -interface ToggleLayoutProps { - children: React.ReactNode; -} - -export default async function Layout({ children }: ToggleLayoutProps) { - const user = await getCurrentUser(); - - if (!userHasPermission(user, PermissionType.MANAGE_NAVLINKS)) - return notFound(); - - return ( -
-
- - - - - - -
-
{children}
-
- ); -} diff --git a/apps/web/src/app/admin/toggles/page.tsx b/apps/web/src/app/admin/toggles/page.tsx deleted file mode 100644 index be7a63f30..000000000 --- a/apps/web/src/app/admin/toggles/page.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export default async function Page() { - return ( -
-

Toggles

-

- Toggles allow you to control various dynamic options on the - website. If you don't see an option here, chances are it can be - changed in the hackkit.config.ts file or via - enviroment variables. Visit the HackKit docs to learn more! -

-
- ); -} diff --git a/apps/web/src/app/admin/toggles/registration/page.tsx b/apps/web/src/app/admin/toggles/registration/page.tsx deleted file mode 100644 index fbd6ecbc0..000000000 --- a/apps/web/src/app/admin/toggles/registration/page.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { RegistrationToggles } from "@/components/admin/toggles/RegistrationSettings"; -import { PermissionType } from "@/lib/constants/permission"; -import { userHasPermission } from "@/lib/utils/server/admin"; -import { redisMGet } from "@/lib/utils/server/redis"; -import { parseRedisBoolean, parseRedisNumber } from "@/lib/utils/server/redis"; -import { getCurrentUser } from "@/lib/utils/server/user"; -import c from "config"; -import { notFound } from "next/dist/client/components/navigation"; - -export default async function Page() { - const [defaultRegistrationEnabled, defaultRSVPsEnabled, defaultRSVPLimit]: ( - | string - | null - )[] = await redisMGet( - "config:registration:registrationEnabled", - "config:registration:allowRSVPs", - "config:registration:maxRSVPs", - ); - - const user = await getCurrentUser(); - - if (!userHasPermission(user, PermissionType.MANAGE_REGISTRATION)) - return notFound(); - - return ( -
-
-

- Registration & Sign-in -

-
- -
- ); -} diff --git a/apps/web/src/app/dash/layout.tsx b/apps/web/src/app/dash/layout.tsx index 4d4eac4a1..b7d034d45 100644 --- a/apps/web/src/app/dash/layout.tsx +++ b/apps/web/src/app/dash/layout.tsx @@ -29,57 +29,64 @@ export default async function DashLayout({ children }: DashLayoutProps) { return ( <> -
-
- - {c.hackathonName - +
-
-

Dashboard

-
-
- - - - - - - - - - +
+
+ + {c.hackathonName + + +
+

+ Dashboard +

+
+
+ + + + + + + + + + +
+
+ +
-
- +
+ {Object.entries(c.dashPaths.dash).map(([name, path]) => ( + + ))}
+ {children} + +
-
- {Object.entries(c.dashPaths.dash).map(([name, path]) => ( - - ))} -
- {children} ); } diff --git a/apps/web/src/app/dash/page.tsx b/apps/web/src/app/dash/page.tsx index 90cdef25b..5bbfc02f1 100644 --- a/apps/web/src/app/dash/page.tsx +++ b/apps/web/src/app/dash/page.tsx @@ -7,11 +7,15 @@ import { createQRpayload } from "@/lib/utils/shared/qr"; import { Countdown } from "@/components/dash/overview/ClientBubbles"; import { Questions, - TitleBubble, + TitleTicket, QuickQR, + QRTiteleHorizintalTicket, + QRTiteleVerticalTicket } from "@/components/dash/overview/ServerBubbles"; -import { getUser } from "db/functions"; import { getCurrentUser } from "@/lib/utils/server/user"; +import LandingThread from "@/components/landing/LandingThread"; +import Pin from "@/components/landing/Pin"; + export default async function Page() { const user = await getCurrentUser(); @@ -22,22 +26,29 @@ export default async function Page() { }); return ( -
-
-

Welcome,

-

- {user.firstName} -

-
-
- - - - -
-
+ <> + +
+ + +
+ +
+ + + + + + + + +
+
+ +
+ ); } diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index 69b2adacf..9fc65f97e 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -4,101 +4,71 @@ @layer base { :root { - --background: 0 0% 100%; - --foreground: 240 10% 3.9%; - - --nav: 255, 255, 255; - --hackathon-primary: 206 86% 52%; - - --muted: 240 4.8% 95.9%; - --muted-foreground: 240 3.8% 46.1%; - - --popover: 0 0% 100%; - --popover-foreground: 240 10% 3.9%; - - --card: 0 0% 100%; - --card-foreground: 240 10% 3.9%; - - --border: 240 5.9% 90%; - --input: 240 5.9% 90%; - - --primary: 240 5.9% 10%; - --primary-foreground: 0 0% 98%; - - --secondary: 240 4.8% 95.9%; - --secondary-foreground: 240 5.9% 10%; - - --accent: 240 4.8% 95.9%; - --accent-foreground: 240 5.9% 10%; - - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 0 0% 98%; - - --ring: 240 5% 64.9%; - - --radius: 0.5rem; - - --gradient-color-1: #668cff; - --gradient-color-2: #3366ff; - --gradient-color-3: #002db3; - --gradient-color-4: #1952cc; - --sidebar-background: 0 0% 98%; - --sidebar-foreground: 240 5.3% 26.1%; - --sidebar-primary: 240 5.9% 10%; - --sidebar-primary-foreground: 0 0% 98%; - --sidebar-accent: 240 4.8% 95.9%; - --sidebar-accent-foreground: 240 5.9% 10%; - --sidebar-border: 220 13% 91%; - --sidebar-ring: 217.2 91.2% 59.8%; - } - - .dark { - --background: 240 10% 3.9%; - --foreground: 0 0% 98%; - - --nav: 240 10% 3.9%; - - --muted: 240 3.7% 15.9%; - --muted-foreground: 240 5% 64.9%; - - --popover: 240 10% 3.9%; - --popover-foreground: 0 0% 98%; - - --card: 240 10% 3.9%; - --card-foreground: 0 0% 98%; - - --border: 240 3.7% 15.9%; - --input: 240 3.7% 15.9%; - - --primary: 0 0% 98%; - --primary-foreground: 240 5.9% 10%; - - --secondary: 240 3.7% 15.9%; - --secondary-foreground: 0 0% 98%; - - --accent: 240 3.7% 15.9%; - --accent-foreground: 0 0% 98%; - - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 0 85.7% 97.3%; - - --ring: 240 3.7% 15.9%; - - --sidebar-background: 240 5.9% 10%; - - --sidebar-foreground: 240 4.8% 95.9%; - - --sidebar-primary: 224.3 76.3% 48%; - - --sidebar-primary-foreground: 0 0% 100%; - - --sidebar-accent: 240 3.7% 15.9%; - - --sidebar-accent-foreground: 240 4.8% 95.9%; - - --sidebar-border: 240 3.7% 15.9%; - - --sidebar-ring: 217.2 91.2% 59.8%; + --gradient-color-stops: var(--hackathon-primary), transparent; + --bg-image: url("/img/assets/background.webp"); + + --background: oklch(0.9404 0.0181 89.3604); + --foreground: oklch(0.145 0 0); + --card: oklch(96.263% 0.00505 67.277); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.2843 0.0195 80.4025); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.8407 0.1291 90.3073); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --destructive-foreground: oklch(1 0 0); + --border: oklch(24.228% 0.01641 79.424); + --input: oklch(0.922 0 0); + --ring: oklch(24.228% 0.01641 79.424); + --nav: #ffffff; + --hackathon-primary: #ac1703; + --chart-1: oklch(0.81 0.1 252); + --chart-2: oklch(0.62 0.19 260); + --chart-3: oklch(0.55 0.22 263); + --chart-4: oklch(0.49 0.22 264); + --chart-5: oklch(0.42 0.18 266); + --sidebar: oklch(1 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.2843 0.0195 80.4025); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.8407 0.1291 90.3073); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.5452 0.0549 80.4233); + --sidebar-ring: oklch(0.708 0 0); + --font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", + "Noto Color Emoji"; + --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, + serif; + --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; + --radius: 0.625rem; + --shadow-x: 0; + --shadow-y: 1px; + --shadow-blur: 3px; + --shadow-spread: 0px; + --shadow-opacity: 0.1; + --shadow-color: oklch(0 0 0); + --shadow-2xs: 0 1px 3px 0px rgb(0 0 0 / 0.05); + --shadow-xs: 0 1px 3px 0px rgb(0 0 0 / 0.05); + --shadow-sm: 0 1px 3px 0px rgb(0 0 0 / 0.1), + 0 1px 2px -1px rgb(0 0 0 / 0.1); + --shadow: 0 1px 3px 0px rgb(0 0 0 / 0.1), + 0 1px 2px -1px rgb(0 0 0 / 0.1); + --shadow-md: 0 1px 3px 0px rgb(0 0 0 / 0.1), + 0 2px 4px -1px rgb(0 0 0 / 0.1); + --shadow-lg: 0 1px 3px 0px rgb(0 0 0 / 0.1), + 0 4px 6px -1px rgb(0 0 0 / 0.1); + --shadow-xl: 0 1px 3px 0px rgb(0 0 0 / 0.1), + 0 8px 10px -1px rgb(0 0 0 / 0.1); + --shadow-2xl: 0 1px 3px 0px rgb(0 0 0 / 0.25); } } @@ -109,6 +79,10 @@ body { @apply bg-background text-foreground; + + background-image: var(--bg-image); + background-size: contain; + background-position: center; } } @@ -140,7 +114,7 @@ .pulsatingDot:before { animation: pulseRing 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite; /* background-color: var(--pulsating-dot, #00BEFF); */ - background-color: hsl(var(--hackathon-primary)); + background-color: var(--hackathon-primary); border-radius: 45px; content: ""; display: block; @@ -172,3 +146,7 @@ transform: scale(1.1); } } + +.pin { + z-index: 40 !important; +} diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index b0b86cbd0..063b61976 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -12,9 +12,7 @@ export default function RootLayout({ return ( - - {children} - + {children} ); diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 71707548c..b42010f19 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -1,11 +1,13 @@ import Navbar from "@/components/shared/Navbar"; import Hero from "@/components/landing/Hero"; import About from "@/components/landing/About"; +import Map from "@/components/landing/Map"; import Partners from "@/components/landing/Partners"; import Footer from "@/components/landing/Footer"; import MLHBadge from "@/components/landing/MLHBadge"; - +import FAQ from "@/components/landing/faq"; +import LandingThread from "@/components/landing/LandingThread"; import { Oswald } from "next/font/google"; import WorkWithUs from "@/components/landing/WorkWithUs"; @@ -16,17 +18,22 @@ const oswald = Oswald({ export default function Home() { return ( -
+
+ -
- + {/*
*/} + + + + + + +
- - - -
-
+ {/*
*/}
); } diff --git a/apps/web/src/app/register/page.tsx b/apps/web/src/app/register/page.tsx index 905969afb..769681f94 100644 --- a/apps/web/src/app/register/page.tsx +++ b/apps/web/src/app/register/page.tsx @@ -1,45 +1,56 @@ import c from "config"; import RegisterForm from "@/components/registration/RegisterForm"; +import RegisterClosed from "@/components/registration/RegistretionClosed"; import { auth, currentUser } from "@clerk/nextjs/server"; import { redirect } from "next/navigation"; import Navbar from "@/components/shared/Navbar"; import Link from "next/link"; -import { redisMGet } from "@/lib/utils/server/redis"; -import { parseRedisBoolean } from "@/lib/utils/server/redis"; -import { Button } from "@/components/shadcn/ui/button"; import { getUser } from "db/functions"; +import { Manuale, Shadows_Into_Light } from "next/font/google"; + +const manuale = Manuale({ + subsets: ["latin"], + display: "swap", +}); +const shadow = Shadows_Into_Light({ + subsets: ["latin"], + weight: "400", +}); export default async function Page() { - const { userId } = await auth(); - if (!userId) return redirect("/sign-up"); - const user = await currentUser(); - if (!user) return redirect("/sign-up"); + const registrationEnabled = c.registrationAvailable; + + if (registrationEnabled) { + + const { userId } = await auth(); + if (!userId) return redirect("/sign-up"); - const registration = await getUser(userId); - if (registration) return redirect("/dash"); + const user = await currentUser(); + if (!user) return redirect("/sign-up"); - const [defaultRegistrationEnabled]: (string | null)[] = await redisMGet( - "config:registration:registrationEnabled", - ); + const registration = await getUser(userId); + if (registration) return redirect("/dash"); - if (parseRedisBoolean(defaultRegistrationEnabled, true) === true) { return ( <> -
-
-

+
+
+

+ Case File · {c.hackathonName} +

+

Register

-

+

Welcome Hacker!{" "} Please fill out the form below to complete your registration for {c.hackathonName}.

-

+

Psttt... Running into a issue? Please let us know on{" "} - + Discord ! @@ -55,32 +66,5 @@ export default async function Page() { ); } - return ( -

-
-

{c.hackathonName}

-

- Registration -

-
-

- Registration Is Currently Closed -

-

- If you believe this is a mistake or have any questions, feel - free to reach out to us at {c.issueEmail}! -

- - - - -

- Already registered? - - Sign-in. - -

-
-
- ); + return ( ); } diff --git a/apps/web/src/app/rsvp/page.tsx b/apps/web/src/app/rsvp/page.tsx index 31632a650..0510ae86d 100644 --- a/apps/web/src/app/rsvp/page.tsx +++ b/apps/web/src/app/rsvp/page.tsx @@ -7,20 +7,11 @@ import { eq } from "db/drizzle"; import { userCommonData } from "db/schema"; import ClientToast from "@/components/shared/ClientToast"; import { SignedOut, RedirectToSignIn } from "@clerk/nextjs"; -import { - parseRedisBoolean, - parseRedisNumber, - redisGet, -} from "@/lib/utils/server/redis"; import Link from "next/link"; import { Button } from "@/components/shadcn/ui/button"; import { getUser } from "db/functions"; -export default async function RsvpPage({ - searchParams, -}: { - searchParams?: { [key: string]: string | string[] | undefined }; -}) { +export default async function RsvpPage() { const { userId } = await auth(); if (!userId) { @@ -42,22 +33,12 @@ export default async function RsvpPage({ return redirect("/i/approval"); } - const rsvpEnabled = parseRedisBoolean( - (await redisGet("config:registration:allowRSVPs")) as - | string - | boolean - | null - | undefined, - true, - ); + const rsvpEnabled = c.rsvpAvailable; let isRsvpPossible = false; - if (rsvpEnabled === true) { - const rsvpLimit = parseRedisNumber( - await redisGet("config:registration:maxRSVPs"), - c.rsvpDefaultLimit, - ); + if (rsvpEnabled) { + const rsvpLimit = c.rsvpLimit; const rsvpUserCount = await db .select({ count: count() }) diff --git a/apps/web/src/app/sign-up/[[...sign-up]]/page.tsx b/apps/web/src/app/sign-up/[[...sign-up]]/page.tsx index eea682138..c09385469 100644 --- a/apps/web/src/app/sign-up/[[...sign-up]]/page.tsx +++ b/apps/web/src/app/sign-up/[[...sign-up]]/page.tsx @@ -1,16 +1,11 @@ import { SignUp } from "@clerk/nextjs"; -import { redisMGet } from "@/lib/utils/server/redis"; -import { parseRedisBoolean } from "@/lib/utils/server/redis"; import c from "config"; -import { Button } from "@/components/shadcn/ui/button"; -import Link from "next/link"; +import RegisterClosed from "@/components/registration/RegistretionClosed";; export default async function Page() { - const [defaultRegistrationEnabled]: (string | null)[] = await redisMGet( - "config:registration:registrationEnabled", - ); + const registrationEnabled = c.registrationAvailable; - if (parseRedisBoolean(defaultRegistrationEnabled, true) === true) { + if (registrationEnabled) { return (
@@ -18,32 +13,5 @@ export default async function Page() { ); } - return ( -
-
-

{c.hackathonName}

-

- Registration -

-
-

- Registration Is Currently Closed -

-

- If you believe this is a mistake or have any questions, feel - free to reach out to us at {c.issueEmail}! -

- - - - -

- Already registered?{" "} - - Sign-in. - -

-
-
- ); + return ( ); } diff --git a/apps/web/src/components/admin/toggles/NavItemsManager.tsx b/apps/web/src/components/admin/toggles/NavItemsManager.tsx deleted file mode 100644 index 237590d6e..000000000 --- a/apps/web/src/components/admin/toggles/NavItemsManager.tsx +++ /dev/null @@ -1,317 +0,0 @@ -"use client"; - -import type { NavItemToggleType } from "@/validators/shared/navitemtoggle"; -import { - Table, - TableBody, - TableCaption, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/shadcn/ui/table"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/shadcn/ui/dialog"; -import { Button } from "@/components/shadcn/ui/button"; -import { Input } from "@/components/shadcn/ui/input"; -import { Label } from "@/components/shadcn/ui/label"; -import { Plus, Loader2 } from "lucide-react"; -import { useState } from "react"; -import { useAction, useOptimisticAction } from "next-safe-action/hooks"; -import { - setItem, - removeItem, - toggleItem, - editItem, -} from "@/actions/admin/modify-nav-item"; -import { toast } from "sonner"; -import Link from "next/link"; -import { Switch } from "@/components/shadcn/ui/switch"; - -interface NavItemsManagerProps { - navItems: NavItemToggleType[]; -} - -export function NavItemsManager({ navItems }: NavItemsManagerProps) { - const { execute, result, status } = useAction(removeItem, { - onSuccess: () => { - toast.dismiss(); - toast.success("NavItem deleted successfully!"); - }, - onError: () => { - toast.dismiss(); - toast.error("Error deleting NavItem"); - }, - }); - - return ( -
- - {/* A list of your recent invoices. */} - {/* TODO: FIX MASSIVE BUG WHERE IF ENCODED IS DIFFERENT IT WILL ALL BREAK */} - - - Name - Link - Enabled - Options - - - - {navItems.map((item) => ( - - - {item.name} - - - - {item.url} - - - - {/* didToggle(item.name, checked)} - /> */} - - - - - - - - ))} - -
-
- ); -} - -function ToggleSwitch({ - itemStatus, - name, -}: { - itemStatus: boolean; - name: string; -}) { - const initialData = { itemStatus }; // Initial data matching the shape of toggleItem's return type - - const { execute, optimisticState } = useOptimisticAction(toggleItem, { - currentState: initialData, - updateFn: (state, { statusToSet }) => { - return { itemStatus: statusToSet }; - }, - onError: () => { - toast.error("Error toggling NavItem"); - }, - }); - - return ( - - execute({ name, statusToSet: checked }) - } - /> - ); -} - -export function AddNavItemDialog() { - const [name, setName] = useState(null); - const [url, setUrl] = useState(null); - const [open, setOpen] = useState(false); - - const { - execute, - result, - status: createStatus, - } = useAction(setItem, { - onSuccess: () => { - console.log("Success"); - setOpen(false); - toast.success("NavItem created successfully!"); - }, - onError: () => { - toast.error("Error creating NavItem"); - }, - }); - - const isLoading = createStatus === "executing"; - - return ( - - - - - - - New Item - - Create a item to show in the non-dashboard navbar - - -
-
- - setName(e.target.value)} - id="name" - placeholder="A Cool Hyperlink" - className="col-span-3" - /> -
-
- - setUrl(e.target.value)} - id="name" - placeholder="https://example.com/" - className="col-span-3" - /> -
-
- - - -
-
- ); -} - -interface EditNavItemDialogProps { - existingName: string; - existingUrl: string; - existingEnabled: boolean; -} - -function EditNavItemDialog({ - existingName, - existingUrl, - existingEnabled, -}: EditNavItemDialogProps) { - const [name, setName] = useState(existingName); - const [url, setUrl] = useState(existingUrl); - const [open, setOpen] = useState(false); - - const { execute, status: editStatus } = useAction(editItem, { - onSuccess: () => { - console.log("Success"); - setOpen(false); - toast.success("NavItem edited successfully!"); - }, - onError: () => { - toast.error("Error editing NavItem"); - }, - }); - const isLoading = editStatus === "executing"; - - return ( - - - - - - - Edit Item - - Edit an existing item shown in the non-dashboard navbar - - -
-
- - setName(e.target.value)} - id="name" - placeholder="A Cool Hyperlink" - className="col-span-3" - value={name} - /> -
-
- - setUrl(e.target.value)} - id="name" - placeholder="https://example.com/" - className="col-span-3" - value={url} - /> -
-
- - - -
-
- ); -} diff --git a/apps/web/src/components/admin/toggles/RegistrationSettings.tsx b/apps/web/src/components/admin/toggles/RegistrationSettings.tsx deleted file mode 100644 index 116aa1f36..000000000 --- a/apps/web/src/components/admin/toggles/RegistrationSettings.tsx +++ /dev/null @@ -1,116 +0,0 @@ -"use client"; - -import { Button } from "@/components/shadcn/ui/button"; -import { Input } from "@/components/shadcn/ui/input"; -import { Label } from "@/components/shadcn/ui/label"; -import { Switch } from "@/components/shadcn/ui/switch"; -import { useOptimisticAction } from "next-safe-action/hooks"; -import { toast } from "sonner"; -import { - toggleRegistrationEnabled, - toggleRegistrationMessageEnabled, - toggleRSVPs, - setRSVPLimit, -} from "@/actions/admin/registration-actions"; -import { UpdateItemWithConfirmation } from "./UpdateItemWithConfirmation"; - -interface RegistrationTogglesProps { - defaultRegistrationEnabled: boolean; - defaultRSVPsEnabled: boolean; - defaultRSVPLimit: number; -} - -export function RegistrationToggles({ - defaultRegistrationEnabled, - defaultRSVPsEnabled, - defaultRSVPLimit, -}: RegistrationTogglesProps) { - const { - execute: executeToggleRSVPs, - optimisticState: toggleRSVPsOptimisticData, - } = useOptimisticAction(toggleRSVPs, { - currentState: { success: true, statusSet: defaultRSVPsEnabled }, - updateFn: (state, { enabled }) => { - return { statusSet: enabled, success: true }; - }, - }); - - const { - execute: executeToggleRegistrationEnabled, - optimisticState: ToggleRegistrationEnabledOptimisticData, - } = useOptimisticAction(toggleRegistrationEnabled, { - currentState: { success: true, statusSet: defaultRegistrationEnabled }, - updateFn: (state, { enabled }) => { - return { statusSet: enabled, success: true }; - }, - }); - - const { - execute: executeSetRSVPLimit, - optimisticState: SetRSVPLimitOptimisticData, - } = useOptimisticAction(setRSVPLimit, { - currentState: { success: true, statusSet: defaultRSVPLimit }, - updateFn: (state, { rsvpLimit }) => { - return { statusSet: rsvpLimit, success: true }; - }, - }); - - return ( - <> -
-

Registration

-
-
-

New Registrations

- { - toast.success( - `Registration ${checked ? "enabled" : "disabled"} successfully!`, - ); - executeToggleRegistrationEnabled({ - enabled: checked, - }); - }} - /> -
-
-
-
-

RSVPs

-
-
-

Allow RSVPs

- { - toast.success( - `RSVPs ${checked ? "enabled" : "disabled"} successfully!`, - ); - executeToggleRSVPs({ enabled: checked }); - }} - /> -
-
-

RSVP Limit

- { - toast.success( - `Hacker RSVP limit successfully changed to ${newLimit}!`, - ); - executeSetRSVPLimit({ rsvpLimit: newLimit }); - }} - /> -
-
-
- - ); -} diff --git a/apps/web/src/components/admin/toggles/ToggleItem.tsx b/apps/web/src/components/admin/toggles/ToggleItem.tsx deleted file mode 100644 index 0c57d9e58..000000000 --- a/apps/web/src/components/admin/toggles/ToggleItem.tsx +++ /dev/null @@ -1,30 +0,0 @@ -"use client"; - -import Link from "next/link"; -import { usePathname } from "next/navigation"; - -interface ToggleItemProps { - name: string; - path: string; -} - -export default function ToggleItem({ name, path }: ToggleItemProps) { - const currPath = usePathname(); - return ( - -
-

{name}

-
- - ); -} diff --git a/apps/web/src/components/admin/toggles/UpdateItemWithConfirmation.tsx b/apps/web/src/components/admin/toggles/UpdateItemWithConfirmation.tsx deleted file mode 100644 index dc35d3eab..000000000 --- a/apps/web/src/components/admin/toggles/UpdateItemWithConfirmation.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { useState } from "react"; -import { Input } from "@/components/shadcn/ui/input"; -import { Button } from "@/components/shadcn/ui/button"; - -interface UpdateItemWithConfirmationBaseProps { - defaultValue: T; - enabled: boolean; - onSubmit: (value: T) => void; -} - -type UpdateItemWithConfirmationProps = - | ({ type: "string" } & UpdateItemWithConfirmationBaseProps) - | ({ type: "number" } & UpdateItemWithConfirmationBaseProps); - -export function UpdateItemWithConfirmation({ - type, - defaultValue, - onSubmit, - enabled, -}: UpdateItemWithConfirmationProps) { - const [valueUpdated, setValueUpdated] = useState(false); - const [value, setValue] = useState(defaultValue.toString()); - - return ( -
- { - // Ignore the change if the value is a non numeric character. - if (type === "number" && /[^0-9]/.test(updated)) { - setValue(value); - return; - } - - setValue(updated); - - /* Avoid allowing the user to update the default value to itself. - * Also disallow the user from sending a zero length input. */ - setValueUpdated( - updated !== defaultValue.toString() && - updated.length !== 0, - ); - }} - /> - -
- ); -} diff --git a/apps/web/src/components/dash/overview/ClientBubbles.tsx b/apps/web/src/components/dash/overview/ClientBubbles.tsx index 8551b01ba..bd7f64564 100644 --- a/apps/web/src/components/dash/overview/ClientBubbles.tsx +++ b/apps/web/src/components/dash/overview/ClientBubbles.tsx @@ -1,8 +1,17 @@ "use client"; -import { useState } from "react"; import { useTimer } from "react-timer-hook"; -import { Badge } from "@/components/shadcn/ui/badge"; +import { Manuale, Shadows_Into_Light } from "next/font/google"; +import Pin from "@/components/landing/Pin"; + +const manuale = Manuale({ + subsets: ["latin"], + display: "swap", +}); +const shadow = Shadows_Into_Light({ + subsets: ["latin"], + weight: "400", +}); interface CountdownProps { title: string; @@ -13,51 +22,66 @@ export function Countdown({ title, date }: CountdownProps) { const { seconds, minutes, hours, days } = useTimer({ expiryTimestamp: date, }); + function DossierPins() { + return ( + <> + + + + + + ); + } return ( -
-
-
-

+ + +
+
+

- {days} + {String(days).padStart(2, "0")}

Days

-
+

- {hours} + {String(hours).padStart(2, "0")}

Hours

-
+

- {minutes} + {String(minutes).padStart(2, "0")}

Minutes

-
+

- {seconds} + {String(seconds).padStart(2, "0")}

Seconds

-
- +
Time To {title} -
); -} +} \ No newline at end of file diff --git a/apps/web/src/components/dash/overview/ServerBubbles.tsx b/apps/web/src/components/dash/overview/ServerBubbles.tsx index e01e995b7..a7b400ece 100644 --- a/apps/web/src/components/dash/overview/ServerBubbles.tsx +++ b/apps/web/src/components/dash/overview/ServerBubbles.tsx @@ -1,67 +1,244 @@ -import { Button } from "@/components/shadcn/ui/button"; import Link from "next/link"; +import Image from "next/image"; import c from "config"; import { format } from "date-fns"; -import GradientHero from "./GradientHero"; import QRCode from "react-qr-code"; +import { Manuale, Shadows_Into_Light } from "next/font/google"; +import { Mail } from "lucide-react"; +import Pin from "@/components/landing/Pin"; + +const manuale = Manuale({ + subsets: ["latin"], + display: "swap", +}); + +const shadow = Shadows_Into_Light({ + subsets: ["latin"], + weight: "400", +}); export function Questions() { + function DossierPins() { + return ( + <> + + + + + ); + } return ( -
+
+ +
-

Have a question?

-

+

Have a question?

+

We're here to help! Feel free to reach out to us via email or on Discord.

-
- - +
+ + Discord logo - - + +
); } -export function TitleBubble() { +function QR({ qrPayload}: { qrPayload: string; qrSize?: string }) { + return ( + <> +

Quick QR

+
+ +
+

+ Click / Tap To Open Event Pass +

+ + ); +} + +function TicketInfo({ className, firstName }: { className?: string; firstName: string }) { return ( -
- -
-

+
+
+

{c.hackathonName}

-

- {`${format(c.startDate, "h:mma, MMM d, yyyy")}`} @{" "} - {c.prettyLocation} -

+

+ 24 hours, one mission: the perfect hack +

+
+
+
+
+

Event

+

{c.hackathonName}

+
+
+

Date

+

{format(c.startDate, "MM-dd-yy")}

+
+
+

Location

+

Downtown campus | SP1 | SP2

+
+
+

Pass No.

+

RH-10-2026

+
+
+ +
+ +
+

Welcome to the crew, {firstName}

+
+
+ ); +} + +export function QRTiteleHorizintalTicket({ qrPayload, firstName }: { qrPayload: string; firstName: string }) { + function DossierPins() { + return ( + <> + + + + + + ); + } + return ( +
+ + + +
+ + + + + + +
+
+ ); +} + + +export function QRTiteleVerticalTicket({ qrPayload, firstName }: { qrPayload: string; firstName: string }) { + function DossierPins() { + return ( + <> + + + + + + ); + } + return ( +
+ + + +
+ + + + + + +
+
+ ); +} + +export function TitleTicket({ firstName }: { firstName: string }) { + function DossierPins() { + return ( + <> + + + + + + ); + } + + return ( + + ); } export function QuickQR({ qrPayload }: { qrPayload: string }) { + function DossierPins() { + return ( + <> + + + + ); + } return ( - -

Quick QR

-
- + + + +
+
-

- Click / Tap To Open Event Pass -

+ ); } diff --git a/apps/web/src/components/landing/About.tsx b/apps/web/src/components/landing/About.tsx index 407df687b..dc57cff1f 100644 --- a/apps/web/src/components/landing/About.tsx +++ b/apps/web/src/components/landing/About.tsx @@ -1,29 +1,189 @@ -import Balancer from "react-wrap-balancer"; -import Image from "next/image"; -import D1 from "../../../public/img/landing/d1.svg"; -import D2 from "../../../public/img/landing/d2.svg"; -import D3 from "../../../public/img/landing/d3.svg"; -import D4 from "../../../public/img/landing/d4.svg"; -import Dino_Coding from "../../../public/img/landing/dinos_coding.png"; +"use client"; +import { Manuale, Shadows_Into_Light } from "next/font/google"; +import { motion } from "motion/react"; +import Pin from "./Pin"; + +const manuale = Manuale({ + subsets: ["latin"], + display: "swap", +}); +const shadow = Shadows_Into_Light({ + subsets: ["latin"], + weight: "400", +}); + +function DossierPins() { + return ( + <> + + + + + + ); +} + export default function About() { - const d1_stylesheet = { - width: "25rem", - height: "auto", - sm: "width: 30rem", - }; return ( -
-
-

- About Section -

-

- Introduce the hackathon and its purpose! Make it sound - enticing -

+
+ +
+
+
+ + + RowdyHacks XII About Us Section + +
+
+

+ What is RowdyHacks? +

+ +
+

+ RowdyHacks is UTSA's annual hackathon, hosted by + the Association for Computing Machinery (ACM) at + UTSA. +
+ It's a weekend-long event where students, tech + enthusiasts, and creative minds from all + backgrounds come together to collaborate, + innovate, and build real-world projects in 24 + hours. +

+ +
+
+ + {/* ===== Desktop ===== */} +
+
+ + + RowdyHacks XII About Us Section + +
+
+

+ What is RowdyHacks? +

+ +
+

+ RowdyHacks is UTSA's annual hackathon, + hosted by the Association for Computing + Machinery (ACM) at UTSA. +
+ It's a weekend-long event where students, + tech enthusiasts, and creative minds from + all backgrounds come together to + collaborate, innovate, and build real-world + projects in 24 hours. +

+ +
+
+ +
+ RowdyHacks XII About Us Section + +
+ +

+ Whether you’ve a seasoned hackathon vet or + you’re just getting started, you’ll feel + right at home at RowdyHacks. Come hang out, + try something new, team up with others, and + bring your ideas to life. There’s plenty of + room to explore, learn as you go, and get + help when you need it. You don’t need to be + an expert, just curious and ready to build. + By the end, you’ll have something real to + show for it, and a few new friends along the + way. +

+ + +
+
+
+
); diff --git a/apps/web/src/components/landing/CreatedWithHackkit.tsx b/apps/web/src/components/landing/CreatedWithHackkit.tsx index 553ded28e..076120a94 100644 --- a/apps/web/src/components/landing/CreatedWithHackkit.tsx +++ b/apps/web/src/components/landing/CreatedWithHackkit.tsx @@ -1,18 +1,26 @@ import Image from "next/image"; import Link from "next/link"; + +import { Shadows_Into_Light } from "next/font/google"; + +const shadowsIntoLight = Shadows_Into_Light({ + weight: "400", + subsets: ["latin"], +}); + export default function CreatedWithHackkit() { return ( -
- + {/* HackKit Logo -
+ /> */} +
Created with HackKit diff --git a/apps/web/src/components/landing/Footer.tsx b/apps/web/src/components/landing/Footer.tsx index 2e801f2ee..e8613a10f 100644 --- a/apps/web/src/components/landing/Footer.tsx +++ b/apps/web/src/components/landing/Footer.tsx @@ -1,32 +1,79 @@ "use client"; -import { type FunctionComponent, useState } from "react"; import Image from "next/image"; +import FooterLinks, { footerSections } from "./FooterLinks"; + +import { Shadows_Into_Light } from "next/font/google"; import Link from "next/link"; -import { Instagram, Facebook, Twitter, Github, Disc } from "lucide-react"; -import Discord from "../../../public/img/landing/discord_icon.svg"; -import CreatedWithHackkit from "@/components/landing/CreatedWithHackkit"; +import { Facebook, Github, Instagram, Twitter } from "lucide-react"; +import CreatedWithHackkit from "./CreatedWithHackkit"; -interface Props { - className?: string; -} +const shadowsIntoLight = Shadows_Into_Light({ + weight: "400", + subsets: ["latin"], +}); export default function Footer() { - const [showResources, setShowResources] = useState(false); - const [showLinks, setShowLinks] = useState(false); - const [showHackathons, setShowHackathons] = useState(false); - return ( -
-
-

- {" "} - Your Footer Here -

-
-
+
+
+
+ RowdyHacks Logo +
+ + {/* links, resources, other hackatons */} +
+ {footerSections.map((section) => ( + + ))} +
+ + {/* icons */} + +
+ + + + + + + + + + + + + + Discord logo + +
+ + +

+ Made with </> & ♥ @ RowdyHacks +
© RowdyHacks & Association of Computing Machinery + at UTSA 2026. All Rights Reserved. +

-
+ ); } diff --git a/apps/web/src/components/landing/FooterLinks.tsx b/apps/web/src/components/landing/FooterLinks.tsx new file mode 100644 index 000000000..82d56610e --- /dev/null +++ b/apps/web/src/components/landing/FooterLinks.tsx @@ -0,0 +1,104 @@ +"use client"; + +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuItem, + DropdownMenuContent, +} from "../shadcn/ui/dropdown-menu"; +import Link from "next/link"; + +import { Shadows_Into_Light } from "next/font/google"; + +const shadowsIntoLight = Shadows_Into_Light({ + weight: "400", + subsets: ["latin"], +}); + +const resources = [ + { name: "Register", link: "/auth" }, + { name: "FAQ", link: "/faq" }, + { name: "Code of Conduct", link: "https://mlh.io/code-of-conduct" }, + { name: "Contact Us", link: "/contact" }, + { name: "ACM-W", link: "https://acmutsa.org/suborg_acmw/" }, + { name: "ACM UTSA", link: "https://acmutsa.org/" }, +] as const; + +const links = [ + { name: "Open Source", link: "https://github.com/acmutsa/rowdyHacksXI" }, +] as const; + +const hackathons = [ + { name: "CodeQuantum", link: "https://cqhacks.org/" }, + { name: "RowdyDatathon", link: "https://rowdydatathon.org/" }, + { name: "TAMUhack", link: "https://tamuhack.com/" }, + { name: "WEHack", link: "https://wehackutd.com/" }, + { name: "HackUTD", link: "https://hackutd.co/" }, + { name: "HackTX", link: "https://hacktx.com/" }, + { name: "HackUNT", link: "https://unthackathon.com/#/" }, + { name: "HackUTA", link: "https://hackuta.org/" }, + { name: "Hacklahoma", link: "https://hacklahoma.org/" }, +] as const; + +export default function FooterLinks({ + title, + data, +}: { + title: string; + data: Readonly<{ name: string; link: string }[]>; +}) { + return ( + <> + {/* mobile */} +
+ + + + {title} + + + + {data.map(({ name, link }, idx) => ( + + + {name} + + + ))} + + +
+ + {/* desktop */} +
+

+ {title} +

+ {data.map(({ link, name }, idx) => ( + + + {name} + + + ))} +
+ + ); +} + +export const footerSections = [ + { title: "Resources", data: resources }, + { title: "Links", data: links }, + { title: "Other Hackathons", data: hackathons }, +] as const; diff --git a/apps/web/src/components/landing/Hero.tsx b/apps/web/src/components/landing/Hero.tsx index 59d5c7da8..0f2243df0 100644 --- a/apps/web/src/components/landing/Hero.tsx +++ b/apps/web/src/components/landing/Hero.tsx @@ -1,56 +1,185 @@ -import Image from "next/image"; -import Link from "next/link"; -import { Button } from "../shadcn/ui/button"; +"use client"; + +import { Manuale, Shadows_Into_Light } from "next/font/google"; +import { motion } from "motion/react"; +import Pin from "@/components/landing/Pin"; + +const line1 = "Heist"; +const line2 = "starts at 9:00"; + +const shadows = Shadows_Into_Light({ + subsets: ["latin"], + variable: "--font-shadows", + weight: "400", +}); +const manuale = Manuale({ + subsets: ["latin"], + weight: "500", +}); + +function DossierPins() { + return ( + <> + + + + + + + + ); +} export default function Hero() { return ( -
-
-
-
-
-
-
- HackKit Logo -
-
-

- Hack -
- Kit -

-
+ <> +
+ + +
+ + + {/* top-secret: animated pop-in (moved from commented code) */} +
+ +
+ +
+
-

- Feature-packed Hackathon managment software{" "} - that just works. -

+
+ +
+
+ +
+ + {/* Heist / starts at 9:00: per-character fade-up (moved from commented code) */} +
+

+ {line1.split("").map((char, i) => ( + + {char} + + ))} +

+

+ {line2.split("").map((char, i) => ( + + {char} + + ))} +

+
+
+ +
+ +

+ Help Wanted +

+
+
+ +

+ Register +

+
+
+ +

+ Mentors +

+
+
+ +

+ Judges +

+
+
+ +

+ Volunteers +

-
-
- - - - - - - - - -
-
-
-
+
+ ); } diff --git a/apps/web/src/components/landing/LandingThread.tsx b/apps/web/src/components/landing/LandingThread.tsx new file mode 100644 index 000000000..6ab1a71e4 --- /dev/null +++ b/apps/web/src/components/landing/LandingThread.tsx @@ -0,0 +1,9 @@ +"use client"; + +import { useEffect } from "react"; +import { mountLandingThread } from "@/lib/utils/client/thread"; + +export default function LandingThread() { + useEffect(() => mountLandingThread(), []); + return null; +} diff --git a/apps/web/src/components/landing/MLHBadge.tsx b/apps/web/src/components/landing/MLHBadge.tsx index 7c0e49c6d..874c4d2d7 100644 --- a/apps/web/src/components/landing/MLHBadge.tsx +++ b/apps/web/src/components/landing/MLHBadge.tsx @@ -4,11 +4,13 @@ import Image from "next/image"; export default function MLHBadge() { return ( <> -
+
@@ -22,24 +24,6 @@ export default function MLHBadge() { />
-
- - Major League Hacking 2025 Hackathon Season - -
); } diff --git a/apps/web/src/components/landing/Map.tsx b/apps/web/src/components/landing/Map.tsx new file mode 100644 index 000000000..df8734a0d --- /dev/null +++ b/apps/web/src/components/landing/Map.tsx @@ -0,0 +1,284 @@ +"use client"; +import Image from "next/image"; +import { useRef } from "react"; +import { Shadows_Into_Light } from "next/font/google"; +import Pin from "@/components/landing/Pin"; +import { findPosition } from "@/hooks/findPosition"; +import { motion } from "motion/react"; + +const line1 = "CONNECTED?"; +const line2_1 = "UTSA"; +const line2_2 = "Main Campus"; +const line3_1 = "UTSA"; +const line3_2 = "San Pedro 1"; +const line3_3 = "(Place of action)"; + +const shadowsIntoLight = Shadows_Into_Light({ + weight: "400", + subsets: ["latin"], + variable: "--font-shadows", +}); + +export default function Map() { + const mapContainerRef = useRef(null); + const mapImgRef = useRef(null); + const mainCampusCardRef = useRef(null); + const mainCampusImgRef = useRef(null); + const sp1CardRef = useRef(null); + const sp1CampusImgRef = useRef(null); + + const sp1PinStyle = findPosition( + mapContainerRef, + mapImgRef, + { x: 0.54, y: 0.75 }, + 20, + ); + const sp1TextStyle = findPosition( + mapContainerRef, + mapImgRef, + { x: 0.46, y: 0.82 }, + 10, + ); + const sp1CircleStyle = findPosition( + mapContainerRef, + mapImgRef, + { x: 0.54, y: 0.77 }, + 10, + ); + const sp1CardTextStyle = findPosition( + sp1CardRef, + sp1CampusImgRef, + { x: 0.3, y: 0.87 }, + 20, + ); + + const mainCampusPinStyle = findPosition( + mapContainerRef, + mapImgRef, + { x: 0.31, y: 0.22 }, + 20, + ); + const mainCampusTextStyle = findPosition( + mapContainerRef, + mapImgRef, + { x: 0.3, y: 0.29 }, + 10, + ); + const mainCampusCircleStyle = findPosition( + mapContainerRef, + mapImgRef, + { x: 0.31, y: 0.24 }, + 10, + ); + const mainCampusCardTextStyle = findPosition( + mainCampusCardRef, + mainCampusImgRef, + { x: 0.4, y: 0.87 }, + 20, + ); + + const connectedStyle = findPosition( + mapContainerRef, + mapImgRef, + { x: 0.48, y: 0.5 }, + 10, + ); + + return ( +
+
+
+ {/* Pictures */} + +
+
+
+ main campus +
+ +
+
+

+ Target 2 +

+
+
+
+ +
+
+ sp1 +
+ +
+ +
+

+ SP1 - Target 1 +

+
+
+
+
+ + +
+
+
+ ); +} diff --git a/apps/web/src/components/landing/PartnerCard.tsx b/apps/web/src/components/landing/PartnerCard.tsx index 436873b92..32a70c657 100644 --- a/apps/web/src/components/landing/PartnerCard.tsx +++ b/apps/web/src/components/landing/PartnerCard.tsx @@ -1,6 +1,8 @@ import React from "react"; import Link from "next/link"; import Image from "next/image"; +import { Manuale } from "next/font/google"; +import Pin from "./Pin"; type Partner = { name: string; @@ -9,78 +11,60 @@ type Partner = { tier: string; }; -type colorMap = { - key: string; - value: string; -}; - -// const tierBorderMap = { -// [Tier.Title]: "w-[15rem] sm:w-72 md:w-72 lg:w-80 2xl:w-[19rem]", -// [Tier.Gold]: "w-[12.75rem] sm:w-[14.75rem] md:w-[16rem] lg:w-72 2xl:w-[19rem]", -// [Tier.Silver]: "w-[11rem] sm:w-52 md:w-60 lg:w-[16rem] 2xl:w-[17rem] ", -// [Tier.Bronze]: "w-32 sm:w-40 md:w-[12rem] lg:w-[14rem] 2xl:w-[16rem]", -// [Tier.Rowdy_Partner]: "w-[7rem] sm:w-32 md:w-40 lg:w-[11rem] 2xl:w-[13rem]", -// [Tier.In_Kind_Partner]: "w-[6rem] sm:w-[7rem] md:w-32 lg:w-40 2xl:w-52", -// }; - -const tierColorMap: { [key: string]: string } = { - ["Title Sponsor"]: "text-purple-500", - ["Gold Sponsor"]: "text-yellow-600", - ["Silver Sponsor"]: "text-gray-400", - ["Bronze Sponsor"]: "text-amber-800", - ["Rowdy Partner"]: "text-blue-500", - ["Rowdy In-Kind"]: "text-red-500", -}; +const manuale = Manuale({ + weight: ["300", "400", "500", "600", "700", "800"], + subsets: ["latin"], + variable: "--font-manuale", +}); function PartnerCard({ partner, is_title, + index, }: { partner: Partner; is_title: boolean; + index: number; }) { - const text: string = is_title - ? "text-2xl sm:text-3xl xl:text-4xl 2xl:text-[3rem]" - : "text-md sm:text-lg lg:text-xl xl:text-2xl 2xl:text-3xl"; - - const height: string = is_title - ? "h-[15rem] sm:h-[15rem] md:h-[16rem] lg:h-[20rem] xl:h-[20rem] 2xl:h-[22rem]" - : "h-[9rem] sm:h-[11rem] md:h-[11rem] lg:h-[12rem] xl:h-[14rem] 2xl:h-[17rem]"; - const image: string = is_title - ? "w-[17rem] sm:w-[17rem] md:w-[18rem] xl:w-[20rem] 2xl:w-[24rem]" - : "w-[8rem] sm:w-[10rem] md:w-[14rem] lg:w-48 xl:w-[16rem]"; - + const padding: string[] = [ + "pl-[15vh] pt-[0vh] pb-[2vh] lg:pt-[0vh] xl:pt-[5vh] xl:pb-[0vh] 2xl:pl-[3vh] 2xl:pt-[7vh] 2xl:pb-[0vh]", + "pl-[1vh] pr-[30vw] pt-[0vh] pb-[2vh] lg:pt-[0vh] lg:pr-[2vw] xl:pt-[2vh] xl:pr-[2vw] 2xl:pl-[0vw] 2xl:pr-[0vw] ", + "pl-[1vh] pr-[30vw] pt-[0vh] pb-[0vh] md:pr-[2vw] lg:pr-[30vw] xl:pr-[40vw] xl:pt-[0vh] xl:pb-[2vh] 2xl:pr-[0vw] 2xl:pb-[7vh]", + "pl-[1vh] pt-[5vh] pb-[0vh] md:pt-[15vh] lg:pt-[5vh] lg:pb-[0vh] lg:pb-[4vh] xl:pr-[3vw] xl:pt-[0vh] xl:pb-[6vh] 2xl:pl-[0vw] 2xl:pr-[0vw]", + "pl-[1vh] pt-[0vh] pb-[6vh] md:pr-[4vw] lg:pt-[0vh] lg:pb-[5vh] lg:pr-[4vw] xl:pr-[4vw] xl:pt-[6vh] xl:pb-[0vh] 2xl:pr-[33vw]", + "pl-[1vh] pt-[0vh] pb-[4vh] xl:pt-[5vh] 2xl:pb-[0vh] 2xl:pt-[7vh]", + "pl-[1vh] pb-[2vh]", + ]; return ( -
- {`${partner?.name} +
+ +
+
+ {partner.logo ? ( + {`${partner.name} + ) : ( + + Logo + + )} +
+ +
+
-

- {partner?.name} -

-

- {partner?.tier} -

); } diff --git a/apps/web/src/components/landing/Partners.tsx b/apps/web/src/components/landing/Partners.tsx index 9b8bb203b..6136b5981 100644 --- a/apps/web/src/components/landing/Partners.tsx +++ b/apps/web/src/components/landing/Partners.tsx @@ -1,6 +1,19 @@ import partnerData from "./partners.json"; import PartnerCard from "./PartnerCard"; import Image from "next/image"; +import { Manuale, Shadows_Into_Light } from "next/font/google"; +import Pin from "./Pin"; + +const shadowsIntoLight = Shadows_Into_Light({ + weight: "400", + subsets: ["latin"], + variable: "--font-shadows", +}); + +const manuale = Manuale({ + subsets: ["latin"], + display: "swap", +}); type Partner = { name: string; @@ -9,41 +22,88 @@ type Partner = { tier: string; }; -export default async function Partners() { - // Christian Walker: Aware of weird bug from 1280px to 1286 px where background dissapears - const marathon: Partner = { - name: "Marathon", - logo: "marathon_logo.svg", - url: "https://www.marathonpetroleum.com/", - tier: "Title Sponsor", - }; +function DossierPins() { + return ( + <> + + + + + + ); +} + +export default async function Partners() { return ( -
-
-

- Partners Sections -

-

- { - "See the Partners Component inside components/landing/Partners for an example" - } -

+
+ + +
+ +
+ +

+ Sponsors +

+
+ +
+ +

+ Currently under investigation +

+
+ + {/*
+
+ sponsors-background +
+ +
+ {partnerData.partners.map( + (partner: Partner, index: number) => ( + + ), + )} + {Array.from({ length: 6 }, (_, index) => ( + + ))} +
+
*/}
- {/* Example Code of what our previous partner section looked like */} - {/*

- A Huge Thanks To Our Rowdyhacks Partners! -

- -
- -
- -
- {partnerData.partners.map((partner: Partner) => ( - - ))} -
*/}
); } diff --git a/apps/web/src/components/landing/Person.tsx b/apps/web/src/components/landing/Person.tsx index 83e976af1..5075fdc35 100644 --- a/apps/web/src/components/landing/Person.tsx +++ b/apps/web/src/components/landing/Person.tsx @@ -1,9 +1,9 @@ export type Person = { - fname: string; //picture file name must match name with .png + fname: string; lname: string; imgLink: string; - role: string; - linkedin: string; - website: string; - github: string; + linkedin?: string; + note?: string; + top?:string + left?:string }; diff --git a/apps/web/src/components/landing/Pin.tsx b/apps/web/src/components/landing/Pin.tsx new file mode 100644 index 000000000..0fa7ec210 --- /dev/null +++ b/apps/web/src/components/landing/Pin.tsx @@ -0,0 +1,30 @@ +import Image from "next/image"; + +export default function Pin({ + name = "/img/assets/silver-pin.svg", + size = 25, + className = "", + no_thread = false, + no_img = false, +}: { + name?: string; + size?: number; + className?: string; + no_thread?: boolean; + no_img?: boolean; + maxSize?: number; +}) { + return ( + + ); +} diff --git a/apps/web/src/components/landing/TeamMember.tsx b/apps/web/src/components/landing/TeamMember.tsx deleted file mode 100644 index 870d8eeb8..000000000 --- a/apps/web/src/components/landing/TeamMember.tsx +++ /dev/null @@ -1,145 +0,0 @@ -"use client"; - -import { Person } from "./Person"; -import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "../shadcn/ui/card"; -import { Oswald } from "next/font/google"; -import Image from "next/image"; -import { useState } from "react"; -const oswald = Oswald({ - variable: "--font-oswald", - subsets: ["latin"], -}); - -// Using the raw svg tag is inefficient. Will need to change later -function LinkedIn({ fillColor }: { fillColor: string }) { - return ( - - - - ); -} - -function Website({ fillColor }: { fillColor: string }) { - return ( - - - - ); -} - -function Github({ fillColor }: { fillColor: string }) { - return ( - - - - ); -} - -export default function TeamMember({ person }: { person: Person }) { - // Edit the max width and height and then set the height to auto in the styling - - const [src, setSrc] = useState(person.imgLink); - const [styling, setStyling] = useState( - "max-w-[110px] md:max-w-[140px] lg:max-w-[160px] 2xl:max-w-[200px] h-auto rounded-lg", - ); - - const FallBackStyling = - "max-w-[105px] md:max-w-[132px] lg:max-w-[150px] xl:max-w-[151px] 2xl:max-w-[188px] rounded-lg"; - - return ( - -
- - -

{`${person.fname}\u00A0${person.lname}`}

-
- -

- {person.role} -

-
-
- - {/* This also needs to be fixed */} - Person Placeholder { - setSrc("/img/logo/hackkit.svg"); - setStyling(FallBackStyling); - }} - /> - - - - -
-
- ); -} diff --git a/apps/web/src/components/landing/WorkWithUs.tsx b/apps/web/src/components/landing/WorkWithUs.tsx index 842c6e243..ccfc3cdb2 100644 --- a/apps/web/src/components/landing/WorkWithUs.tsx +++ b/apps/web/src/components/landing/WorkWithUs.tsx @@ -1,13 +1,263 @@ +"use client"; + +import Image from "next/image"; +import { useEffect, useState } from "react"; +import { Shadows_Into_Light } from "next/font/google"; +import { Person } from "./Person"; +import teamData from "./team.json"; +import Link from "next/link"; +import { Linkedin } from "lucide-react"; +import { motion } from "motion/react"; +import Pin from "./Pin"; + +const people: Person[] = teamData.team; + +const shadowsIntoLight = Shadows_Into_Light({ + weight: "400", + subsets: ["latin"], + variable: "--font-shadows", +}); + +function srcFor(p: Person) { + return p.imgLink && p.imgLink.length > 0 ? p.imgLink : `/${p.fname}.png`; +} + +// Polaroid signature: +function Polaroid({ + person, + slotIndex, +}: { + person: Person; + slotIndex: number; +}) { + const [front, setFront] = useState(person); + const [back, setBack] = useState(person); + const [showFront, setShowFront] = useState(true); + const [roration] = useState(() => Math.random() * 10 - 3); + + useEffect(() => { + if (showFront && person !== front) { + setBack(person); + setShowFront(false); + } else if (!showFront && person !== back) { + setFront(person); + setShowFront(true); + } + }, [person, front, back, showFront]); + + return ( +
+ + {/* photo */} +
+ {`${front.fname} + +
+ + {/* name + linkedin in a row */} +
+ {/* name crossfade */} +
+

+ {front.fname} {front.lname} +

+

+ {back.fname} {back.lname} +

+
+ + {/* icon crossfade — its own relative box keeps it in the row */} +
+ {front.linkedin && ( + + + + )} + {back.linkedin && ( + + + + )} +
+
+ + {(() => { + const active = showFront ? front : back; + if (!active.note) return null; + return ( +
+

+ {active.note.split("").map((char, i) => ( + + {char === " " ? "\u00A0" : char} + + ))} +

+
+ ); + })()} +
+ ); +} + +function DossierPins() { + return ( + <> + + + + + ); +} + export default function WorkWithUs() { + const [index, setIndex] = useState(0); + const len = people.length || 1; + + const [step, setStep] = useState(3); + + useEffect(() => { + const lg = window.matchMedia("(min-width: 1024px)"); // lg + const md = window.matchMedia("(min-width: 768px)"); // md + const sm = window.matchMedia("(min-width: 640px)"); // sm + + const update = () => { + if (lg.matches) setStep(5); + else if (md.matches) setStep(4); + else if (sm.matches) setStep(3); + else setStep(2); + }; + + update(); + lg.addEventListener("change", update); + md.addEventListener("change", update); + sm.addEventListener("change", update); + return () => { + lg.removeEventListener("change", update); + md.removeEventListener("change", update); + sm.removeEventListener("change", update); + }; + }, []); + + const move = (delta: number) => setIndex((i) => (i + delta + len) % len); + const slots = [0, 1, 2, 3, 4]; + return ( -
-

- Work With Us Section -

-

- Incentivize companies to monetarily support and other students - to volunteer to help out!{" "} -

+
+
+
+
+ +

+ Main Suspects +

+
+
+ + {/* carousel row */} +
+ + + {slots.map((slot) => { + const person_id = (index + slot) % len; + const person = people[person_id]; + const visibility = + slot < 2 + ? "flex" + : slot === 2 + ? "hidden sm:flex" + : slot === 3 + ? "hidden md:flex" + : "hidden lg:flex"; + return ( +
+ +
+ ); + })} + + +
+
); } diff --git a/apps/web/src/components/landing/faq.json b/apps/web/src/components/landing/faq.json new file mode 100644 index 000000000..4a2fdac3d --- /dev/null +++ b/apps/web/src/components/landing/faq.json @@ -0,0 +1,28 @@ +{ + "faq": [ + { + "question": "Who can attend?", + "answer": "All students can sign up to be a hacker. Regardless of your experience, education, or background, as long as you are excited about learning, building, and having fun, we'd love for you to attend." + }, + { + "question": "When is the deadline to apply?", + "answer": "The deadline for registration is , at 23:59." + }, + { + "question": "How much experience do I need?", + "answer": "Absolutely zero! We want you here because you have a passion for creating, not because you're the most experienced hacker on the block. We'll have lots of resources including workshops and a bunch of mentors to help beginners get started. There'll also be plenty of people to learn from and help out!" + }, + { + "question": "How much does it cost?", + "answer": "Nothing. Nada. Zilch. It's completely free for all accepted hackers. To make it even better, we'll be giving out a ton of swag to every hacker, and prizes to our winners." + }, + { + "question": "What should I bring?", + "answer": "Please bring a valid ID in addition to anything that would help you with creating your hack or making you comfortable. A laptop, charger, mouse, keyboard, hardware, light jacket, and any hygienic products should be helpful. Don't bring anything you wouldn't bring on an airplane." + }, + { + "question": "How do teams work?", + "answer": "Teams are limited to 1-4 hackers. If you have a team in mind, make sure all members submit an application before the deadline. If you don't have a team and would like to be a part of one, no worries! We'll have a dedicated time for team formation after the opening ceremony." + } + ] +} diff --git a/apps/web/src/components/landing/faq.tsx b/apps/web/src/components/landing/faq.tsx new file mode 100644 index 000000000..8d1090502 --- /dev/null +++ b/apps/web/src/components/landing/faq.tsx @@ -0,0 +1,167 @@ +"use client"; +import { Manuale } from "next/font/google"; +import faqData from "./faq.json"; +import { motion } from "motion/react"; +import Pin from "./Pin"; + +const manuale = Manuale({ + subsets: ["latin"], + display: "swap", +}); + +type Faq = { question: string; answer: string }; + +const LEFT_COUNT = 4; +const allFaqs = faqData.faq as Faq[]; +const leftFaqs = allFaqs.slice(0, LEFT_COUNT); +const rightFaqs = allFaqs.slice(LEFT_COUNT); + +function DossierPins() { + return ( + <> + + + + + ); +} + +function PaperBg() { + return ( + + ); +} + +function FaqHeader() { + return ( +
+ +

+ FAQ +

+
+ ); +} + +function ClassifiedStamp({ + wrapperClassName = "relative flex justify-end pr-[5%] pb-[5%]", +}: { + wrapperClassName?: string; +}) { + return ( +
+ +
+ ); +} + +function FaqItem({ item }: { item: Faq }) { + return ( + +
+

+ {item.question} +

+ +
+

+ {item.answer} +

+
+ ); +} + +/* ---------- Page ---------- */ + +export default function FAQ() { + return ( +
+ +
+ {/* ===== Desktop & Tablet ===== */} +
+ {/* Left paper */} +
+
+ + + {leftFaqs.map((item, index) => ( + + ))} +
+
+ + {/* Right paper */} +
+
+ + + {rightFaqs.map((item, index) => ( + + ))} +
+
+
+ + {/* ===== Mobile ===== */} +
+
+ + +
+ + +
+ + {allFaqs.map((item, index) => ( + + ))} +
+
+
+
+ ); +} diff --git a/apps/web/src/components/landing/partners.json b/apps/web/src/components/landing/partners.json index fc654015b..17ec4b4b7 100644 --- a/apps/web/src/components/landing/partners.json +++ b/apps/web/src/components/landing/partners.json @@ -1,142 +1,28 @@ { "partners": [ { - "name": "Cymanii", - "logo": "CyManII_Logo.svg", - "url": "https://cymanii.org/", - "tier": "Gold Sponsor" - }, - { - "name": "UTSA DS Dept.", - "logo": "UTSADS.svg", - "url": "https://sds.utsa.edu/", - "tier": "Gold Sponsor" - }, - { - "name": "Swivel", - "logo": "swivel_logo.svg", - "url": "https://www.getswivel.io/", - "tier": "Silver Sponsor" - }, - { - "name": "UTSA CS Dept.", - "logo": "UTSA_CS.svg", - "url": "https://sciences.utsa.edu/computer-science/", - "tier": "Silver Sponsor" - }, - { - "name": "Frost Bank", - "logo": "FrostBank.svg", - "url": "https://www.frostbank.com/", - "tier": "Silver Sponsor" - }, - { - "name": "Valero", - "logo": "ValeroLogo.svg", - "url": "https://www.valero.com/", - "tier": "Silver Sponsor" - }, - { - "name": "Google", - "logo": "Google_Icon.svg", - "url": "https://about.google/", - "tier": "Bronze Sponsor" - }, - { - "name": "Paycom", - "logo": "PaycomLogo.svg", - "url": "https://www.paycom.com/", - "tier": "Bronze Sponsor" + "name": "H-E-B", + "logo": "HEB.svg", + "url": "https://www.heb.com/", + "tier": "title" }, { "name": "Dell", - "logo": "Dell_Tech_Logo.svg", + "logo": "dell.svg", "url": "https://www.dell.com/", - "tier": "Bronze Sponsor" - }, - { - "name": "S + S", - "logo": "Students_and_Startups.svg", - "url": "https://studentsstartups.com/", - "tier": "Bronze Sponsor" - }, - { - "name": "AFCS", - "logo": "AFCSLogo.svg", - "url": "https://afciviliancareers.com/", - "tier": "Bronze Sponsor" - }, - { - "name": "Accenture", - "logo": "Accenture-logo.svg", - "url": "https://www.accenture.com/", - "tier": "Rowdy Partner" - }, - { - "name": "UTSA COE", - "logo": "UTSA_COE.svg", - "url": "https://klesse.utsa.edu/", - "tier": "Rowdy Partner" - }, - { - "name": "UTSA Tech Store", - "logo": "rowdy_tech_logo.svg", - "url": "https://campustechnologystore.com/campustechnologystore/", - "tier": "Rowdy Partner" - }, - { - "name": "TD Synnex", - "logo": "TD_Synnex_logo.svg", - "url": "https://www.tdsynnex.com/", - "tier": "Rowdy Partner" - }, - { - "name": "Wolfram Alpha", - "logo": "wolfram_logo.svg", - "url": "https://www.wolframalpha.com/", - "tier": "Rowdy Partner" - }, - { - "name": "CodePath", - "logo": "Codepath_logo.svg", - "url": "https://www.codepath.org/", - "tier": "Rowdy Partner" + "tier": "golden" }, { - "name": "ACM", - "logo": "ACM_logo.svg", - "url": "https://www.acm.org/", - "tier": "Rowdy Partner" - }, - { - "name": "Artea", - "logo": "Artea_logo.svg", - "url": "https://www.drinkartea.com/", - "tier": "Rowdy In-Kind" - }, - { - "name": "Pho Thien An", - "logo": "Pho_logo.svg", - "url": "https://www.phothienan.com/", - "tier": "Rowdy In-Kind" - }, - { - "name": "Bunz Burgers", - "logo": "Bunz_logo.svg", - "url": "https://www.tastybunz.com/", - "tier": "Rowdy In-Kind" - }, - { - "name": "H-E-B", - "logo": "HEB.svg", - "url": "https://www.heb.com/", - "tier": "Rowdy In-Kind" + "name": "Apple", + "logo": "apple.svg", + "url": "https://www.apple.com/", + "tier": "silver" }, { - "name": "Six Flags", - "logo": "Six_Flags_logo.svg", - "url": "https://www.sixflags.com/fiestatexas", - "tier": "Rowdy In-Kind" + "name": "google", + "logo": "google.svg", + "url": "https://www.google.com/", + "tier": "bronze" } ] } diff --git a/apps/web/src/components/landing/team.json b/apps/web/src/components/landing/team.json new file mode 100644 index 000000000..86a9e9760 --- /dev/null +++ b/apps/web/src/components/landing/team.json @@ -0,0 +1,202 @@ +{ + "team": [ + { + "fname": "Evelynn", + "lname": "Donaldson", + "imgLink": "/img/assets/team/Evelynn Donaldson.webp", + "linkedin": "https://www.linkedin.com/in/evelynn-donaldson-191a00290/" + }, + { + "fname": "Alekzander", + "lname": "Brysch", + "imgLink": "/img/assets/team/Alekzander Brysch.webp", + "linkedin": "https://www.linkedin.com/in/zander-brysch/", + "note": "Director?", + "top": "87%", + "left": "10%" + }, + { + "fname": "Paula", + "lname": "Com", + "imgLink": "/img/assets/team/Paula Com.webp", + "linkedin": "https://www.linkedin.com/in/paula-com-morales/" + }, + { + "fname": "Tri", + "lname": "Nguyen", + "imgLink": "/img/assets/team/Tri Nguyen.webp", + "linkedin": "https://www.linkedin.com/in/tri-nguyen2/" + }, + { + "fname": "Rufat", + "lname": "Niftaliyev", + "imgLink": "/img/assets/team/Rufat Niftaliyev.webp", + "linkedin": "https://www.linkedin.com/in/rufat-niftaliyev/" , + "note": "Lead?", + "top": "87%", + "left": "50%" + }, + { + "fname": "Cayden", + "lname": "Hutcheson", + "imgLink": "/img/assets/team/Cayden Hutcheson.webp", + "linkedin": "https://www.linkedin.com/in/cayden-hutcheson110/", + "note": "Director?", + "top": "8%", + "left": "15%" + }, + { + "fname": "Ash", + "lname": "Hernandez", + "imgLink": "/img/assets/team/Ash Hernandez.webp", + "linkedin": "https://www.linkedin.com/in/ashley-hernandez-sanchez-b76312333/" + }, + { + "fname": "Maryna", + "lname": "Korolova", + "imgLink": "/img/assets/team/Maryna Korolova.webp", + "linkedin": "https://www.linkedin.com/in/marynakorolova", + "note": "Lead?", + "top": "83%", + "left": "50%" + }, + { + "fname": "Shaun", + "lname": "Philippe", + "imgLink": "/img/assets/team/Shaun Philippe.webp", + "linkedin": "https://www.linkedin.com/in/shaun-ph/" + }, + { + "fname": "Josie", + "lname": "Sauceda", + "imgLink": "/img/assets/team/Josie Sauceda.webp", + "linkedin": "https://www.linkedin.com/in/josie-sauceda/" + }, + { + "fname": "Miguel", + "lname": "Oseguera", + "imgLink": "/img/assets/team/Miguel Oseguera.webp", + "linkedin": "https://www.linkedin.com/in/miguel-oseguera-0b5306281/", + "note": "Lead?", + "top": "8%", + "left": "8%" + }, + { + "fname": "Blessy", + "lname": "Kalluri", + "imgLink": "/img/assets/team/Blessy Kalluri.webp", + "linkedin": "https://www.linkedin.com/in/blessykalluri/" + }, + { + "fname": "Camille", + "lname": "Hart", + "imgLink": "/img/assets/team/Camille Hart.webp", + "linkedin": "https://www.linkedin.com/in/camille-louise-rivera/" + }, + { + "fname": "Anh", + "lname": "Doan", + "imgLink": "/img/assets/team/Anh Doan.webp", + "linkedin": "https://www.linkedin.com/in/minh-anh-doan-600b94291/", + "note": "Lead?", + "top": "85%", + "left": "6%" + }, + { + "fname": "Abrar", + "lname": "Ahmed", + "imgLink": "/img/assets/team/Abrar Ahmed.webp", + "linkedin": "https://www.linkedin.com/in/abrar-ahmed1/" + }, + { + "fname": "Diego", + "lname": "Medina", + "imgLink": "/img/assets/team/Diego Medina.webp", + "linkedin": "https://www.linkedin.com/in/diegomedina12/", + "note": "Lead?", + "top": "85%", + "left": "39%" + }, + { + "fname": "Dyshana", + "lname": "Torres Rivera", + "imgLink": "/img/assets/team/Dyshana Torres Rivera.webp", + "linkedin": "https://www.linkedin.com/in/dyshana-torres/" + }, + { + "fname": "Elisa", + "lname": "Moran", + "imgLink": "/img/assets/team/Elisa Moran.webp", + "linkedin": "https://www.linkedin.com/in/elisa-moran-a6aa2b29a/" + }, + { + "fname": "Eric", + "lname": "Lee", + "imgLink": "/img/assets/team/Eric Lee.webp", + "linkedin": "https://www.linkedin.com/in/eric-lee-sunghyun/", + "note": "Lead?", + "top": "9%", + "left": "7%" + }, + { + "fname": "Francisco", + "lname": "Epinoza", + "imgLink": "/img/assets/team/Francisco Epinoza.webp", + "linkedin": "https://www.linkedin.com/in/francisco0-espinoza7/" + }, + { + "fname": "Layla", + "lname": "Mendiola", + "imgLink": "/img/assets/team/Layla Mendiola.webp", + "linkedin": "https://www.linkedin.com/in/layla-mendiola-144013381/" + }, + { + "fname": "Martin", + "lname": "Llano", + "imgLink": "/img/assets/team/Martin Llano.webp", + "linkedin": "https://www.linkedin.com/in/martin-llano-b10239291/" + }, + { + "fname": "Reese", + "lname": "Sylvester", + "imgLink": "/img/assets/team/Reese Sylvester.webp", + "linkedin": "" , + "note": "Lead?", + "top": "10%", + "left": "13%" + }, + { + "fname": "Anam", + "lname": "Sultana", + "imgLink": "/img/assets/team/Anam Sultana.webp", + "linkedin": "https://www.linkedin.com/in/anam-sult/" + }, + { + "fname": "Savanah", + "lname": "Schaefer", + "imgLink": "/img/assets/team/Savanah Schaefer.webp", + "linkedin": "https://www.linkedin.com/in/savanahsch/", + "note": "Lead?", + "top": "86%", + "left": "10%" + }, + { + "fname": "Scherly", + "lname": "Ramirez", + "imgLink": "/img/assets/team/Scherly Ramirez.webp", + "linkedin": "https://www.linkedin.com/in/scherly-ramirez-miranda-189623388/" + }, + { + "fname": "Tochi", + "lname": "Kalu", + "imgLink": "/img/assets/team/Tochi Kalu.webp", + "linkedin": "" + }, + { + "fname": "Victoria", + "lname": "Rivas", + "imgLink": "/img/assets/team/Victoria Rivas.webp", + "linkedin": "" + } + ] +} \ No newline at end of file diff --git a/apps/web/src/components/registration/FormGroupWrapper.tsx b/apps/web/src/components/registration/FormGroupWrapper.tsx index 1c9867feb..86a91947f 100644 --- a/apps/web/src/components/registration/FormGroupWrapper.tsx +++ b/apps/web/src/components/registration/FormGroupWrapper.tsx @@ -8,8 +8,8 @@ export default function FormGroupWrapper({ title, }: FormGroupWrapperProps) { return ( -
-

+

+

{title}

{children}
diff --git a/apps/web/src/components/registration/RegisterForm.tsx b/apps/web/src/components/registration/RegisterForm.tsx index 85abd141b..c435097c2 100644 --- a/apps/web/src/components/registration/RegisterForm.tsx +++ b/apps/web/src/components/registration/RegisterForm.tsx @@ -82,6 +82,12 @@ import { decodeBase64AsFile, } from "@/lib/utils/shared/files"; import { useDebouncedCallback } from "use-debounce"; +import { Manuale } from "next/font/google"; + +const manuale = Manuale({ + subsets: ["latin"], + display: "swap", +}); export default function RegisterForm({ defaultEmail, @@ -361,14 +367,14 @@ export default function RegisterForm({ isLoading={isLoading} /> ) : ( -
+
-
+
- + @@ -1292,7 +1298,7 @@ export default function RegisterForm({ {formatRegistrationField( - `Where did you hear about ${c.hackathonName}?`, + `Where did you hear about us?`, hackerRegistrationFormValidator.shape[ field.name ].isOptional(), @@ -1648,13 +1654,13 @@ export default function RegisterForm({ uploadedFile ? "" : "cursor-pointer" - } flex min-h-[200px] flex-col items-center justify-center rounded-lg border-dashed border-white`} + } flex min-h-[200px] flex-col items-center justify-center rounded-lg border border-dashed border-border`} > -

+

{uploadedFile ? `${uploadedFile.name} (${Math.round(uploadedFile.size / 1024)}kb)` : isDragActive @@ -1697,7 +1703,7 @@ export default function RegisterForm({

-
+
@
{ setSkills(newTags); field.onChange( diff --git a/apps/web/src/components/registration/RegistretionClosed.tsx b/apps/web/src/components/registration/RegistretionClosed.tsx new file mode 100644 index 000000000..0c4b1f52f --- /dev/null +++ b/apps/web/src/components/registration/RegistretionClosed.tsx @@ -0,0 +1,54 @@ +import c from "config"; +import { Button } from "@/components/shadcn/ui/button"; +import Link from "next/link"; +import { Manuale, Shadows_Into_Light } from "next/font/google"; + +const manuale = Manuale({ + subsets: ["latin"], + display: "swap", +}); +const shadow = Shadows_Into_Light({ + subsets: ["latin"], + weight: "400", +}); + +export default function RegistrationClosed() { + return ( +
+
+

+ Case File · {c.hackathonName} +

+ +

+ Registration Is
Currently Closed +

+ +

+ This operation is currently closed to new team members. If you believe + this was an error, or you've got intel for us — + reach the handlers at{" "} + + {c.issueEmail} + + . +

+ +
+ + + +
+ +

+ Already in the team? + + Sign in. + +

+
+
+ ); +} diff --git a/apps/web/src/components/shadcn/ui/button.tsx b/apps/web/src/components/shadcn/ui/button.tsx index 4006280be..06178a58c 100644 --- a/apps/web/src/components/shadcn/ui/button.tsx +++ b/apps/web/src/components/shadcn/ui/button.tsx @@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils/client/cn"; const buttonVariants = cva( - "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { diff --git a/apps/web/src/components/shadcn/ui/checkbox.tsx b/apps/web/src/components/shadcn/ui/checkbox.tsx index 6f1abca51..b64d0f427 100644 --- a/apps/web/src/components/shadcn/ui/checkbox.tsx +++ b/apps/web/src/components/shadcn/ui/checkbox.tsx @@ -13,7 +13,7 @@ const Checkbox = React.forwardRef< ) { {...fieldProps} ref={ref} className={cn( - "inline-flex h-10 flex-1 items-center rounded-l-md border border-r-0 border-input bg-transparent py-2 pl-3 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", + "inline-flex h-10 flex-1 items-center rounded-l-md border border-r-0 border-input bg-transparent py-2 pl-3 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-0", props.isDisabled ? "cursor-not-allowed opacity-50" : "", )} > diff --git a/apps/web/src/components/shadcn/ui/date-time-picker/time-field.tsx b/apps/web/src/components/shadcn/ui/date-time-picker/time-field.tsx index 7905d22af..e62a5dacc 100644 --- a/apps/web/src/components/shadcn/ui/date-time-picker/time-field.tsx +++ b/apps/web/src/components/shadcn/ui/date-time-picker/time-field.tsx @@ -29,7 +29,7 @@ function TimeField(props: AriaTimeFieldProps) { {...fieldProps} ref={ref} className={cn( - "inline-flex h-10 w-full flex-1 rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", + "inline-flex h-10 w-full flex-1 rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-0", props.isDisabled ? "cursor-not-allowed opacity-50" : "", )} > diff --git a/apps/web/src/components/shadcn/ui/input.tsx b/apps/web/src/components/shadcn/ui/input.tsx index e5bf081f6..001d1c6d7 100644 --- a/apps/web/src/components/shadcn/ui/input.tsx +++ b/apps/web/src/components/shadcn/ui/input.tsx @@ -11,7 +11,7 @@ const Input = React.forwardRef( (({ className, ...props }, ref) => ( ( return (