diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 58fd786b..545ffcd6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -27,6 +27,7 @@ jobs: SERVICE_ACCOUNT: ${{ secrets.SERVICE_ACCOUNT }} DIRECTORY_SPREADSHEET_ID: ${{ secrets.DIRECTORY_SPREADSHEET_ID }} TOWNHALL_SPREADSHEET_ID: ${{ secrets.TOWNHALL_SPREADSHEET_ID }} + GM_SPREADSHEET_ID: ${{ secrets.GM_SPREADSHEET_ID }} steps: - uses: actions/checkout@v2 @@ -42,4 +43,6 @@ jobs: - run: npm run thp + - run: npm run gmp + - run: npm run lint diff --git a/.github/workflows/node-build.yml b/.github/workflows/node-build.yml index bee51ce7..1fe86625 100644 --- a/.github/workflows/node-build.yml +++ b/.github/workflows/node-build.yml @@ -27,6 +27,7 @@ jobs: SERVICE_ACCOUNT: ${{ secrets.SERVICE_ACCOUNT }} DIRECTORY_SPREADSHEET_ID: ${{ secrets.DIRECTORY_SPREADSHEET_ID }} TOWNHALL_SPREADSHEET_ID: ${{ secrets.TOWNHALL_SPREADSHEET_ID }} + GM_SPREADSHEET_ID: ${{ secrets.GM_SPREADSHEET_ID }} steps: - uses: actions/checkout@v2 @@ -42,6 +43,8 @@ jobs: - run: npm run thp + - run: npm run gmp + - run: npm run build - run: npm test diff --git a/.gitignore b/.gitignore index bfe68405..177a41d9 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ output.json offoutput.json townhall.json past-townhall.json +gmData.json diff --git a/components/Footer.js b/components/Footer.js index c459b183..137cb921 100644 --- a/components/Footer.js +++ b/components/Footer.js @@ -7,7 +7,7 @@ import SocialMedia from './SocialMedia'; const footerACMLinks = [ { title: 'About', path: '/about' }, { title: 'Events', path: '/events' }, - { title: 'General Meeting', path: '/gm/w24' }, + { title: 'General Meeting', path: '/gm' }, { title: 'CS Town Hall', path: '/town-hall' }, { title: 'Internship Program', path: '/internship' }, { title: 'Dev Team', path: '/dev'}, diff --git a/netlify.toml b/netlify.toml index 9697970a..aaee1b45 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,5 +1,5 @@ [build] - command = "npm run ofp; npm run thp; npm run build" + command = "npm run ofp; npm run thp; npm run gmp; npm run build" publish = "build" [[plugins]] diff --git a/package.json b/package.json index af38bacd..11cdb009 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "scripts": { "start": "next dev", "start-production": "next start", - "build": "npm run ofp && npm run thp && next build", + "build": "npm run ofp && npm run thp && npm run gmp && next build", "lint-js": "eslint \"**/*.js\"", "lint-js-fix": "eslint --fix \"**/*.js\"", "lint-css": "stylelint \"**/*.css\" \"**/*.scss\"", @@ -35,6 +35,7 @@ "seg": "node scripts/single-event-generator.mjs", "ofp": "node scripts/officer-parser.mjs", "thp": "node scripts/town-hall-generator.mjs", + "gmp": "node scripts/gm-generator.mjs", "test": "jest --env=jsdom" }, "eslintConfig": { diff --git a/pages/gm.js b/pages/gm.js new file mode 100644 index 00000000..0b214e50 --- /dev/null +++ b/pages/gm.js @@ -0,0 +1,280 @@ +import { NextSeo } from 'next-seo'; +import Image from 'next/image'; +import Link from 'next/link'; +import React from 'react'; +import Countdown from 'react-countdown'; + +import Banner from '../components/Banner'; +import Layout from '../components/Layout'; +import gmData from '../gmData.json'; + +import aiLogo from '../public/images/committees/ai_wordmark.svg'; +import boardLogo from '../public/images/committees/board_wordmark.svg'; +import cyberLogo from '../public/images/committees/cyber_wordmark.svg'; +import designLogo from '../public/images/committees/design_wordmark.svg'; +import hackLogo from '../public/images/committees/hack_wordmark.svg'; +import icpcLogo from '../public/images/committees/icpc_wordmark.svg'; +import studioLogo from '../public/images/committees/studio_wordmark.svg'; +import teachlaLogo from '../public/images/committees/teachLA_wordmark.svg'; +import wLogo from '../public/images/committees/w_wordmark.svg'; +import googleSlideLogo from '../public/images/slides.png'; +import winterGMgraphic from '../public/images/Winter_GM_2024_graphic.png'; + + +const dayToName = (day) => { + switch (day) { + case 0: + return 'Sunday'; + case 1: + return 'Monday'; + case 2: + return 'Tuesday'; + case 3: + return 'Wednesday'; + case 4: + return 'Thursday'; + case 5: + return 'Friday'; + default: + return 'Saturday'; + } +}; + +const getDateWithSuffix = (date) => { + let suffix = ''; + switch (date % 10) { + case 1: + suffix = 'st'; + break; + case 2: + suffix = 'nd'; + break; + case 3: + suffix = 'rd'; + break; + default: + suffix = 'th'; + } + return date.toString() + suffix; +}; + +const calculateTimeStrings = ({days, hours, minutes, seconds}) => { + let dayString = 'Day'; + let hourString = 'Hour'; + let minuteString = 'Minute'; + let secondString = 'Second'; + if(days !== 1){ dayString += 's'; } + if(hours !== 1){ hourString += 's'; } + if(minutes !== 1){ minuteString += 's'; } + if(seconds !== 1){ secondString += 's'; } + + return {dayString, hourString, minuteString, secondString}; +}; + +const parseGMData = (jsonContent) => { + const data = {}; + + for (const row of jsonContent) { + data[row.name] = row.description; + } + + const startTime = new Date(data?.gm_start_time); + + return { + gm_start_time: startTime, + gm_end_time: new Date(data?.gm_end_time), + rsvp_link: data?.rsvp_link, + quarter: data?.quarter, + slides_link: data?.slides_link, + location: data?.location, + day_of_week: dayToName(startTime.getDay()), + date_with_suffix: getDateWithSuffix(startTime.getDate()), + pres: data?.pres, + ivp: data?.ivp, + evp: data?.evp, + studio: data?.studio, + icpc: data?.icpc, + design: data?.design, + cyber: data?.cyber, + teachLA: data?.teachLA, + w: data?.w, + ai: data?.ai, + hack: data?.hack, + initiatives: data?.initiatives.split(';'), + }; +}; + +const GMCountdown = (props) => { + return ( + <> +
{data.quarter} GM will be hosted in {data.location}.
+Encouraged: Phone to scan QR codes, excitement to learn about ACM!
++ Don't hesitate to contact us at acm@ucla.edu if you any accessiblity concerns for {data.quarter} GM. +
+ +An introduction to ACM by our president {data.pres}.
+Learn what ACM's eight committees have planned for {data.quarter} quarter.
+How to get more involved with ACM beyond attending workshops and events
+See exciting new programs that ACM is trying out
+{item}
)} +Interact with ACM's officers and walk away with new friends!
+All ACM officers
+