diff --git a/articles.json b/articles.json new file mode 100644 index 0000000..aa67213 --- /dev/null +++ b/articles.json @@ -0,0 +1 @@ +{"wellness_festival": {"title": "SOC Wellness Festival", "body": "\nHey SoC Students,\n\nAre you feeling the mid-semester slump? Is your brain starting to feel fried from staring at endless lines of code? If so, don\u2019t panic. We\u2019ve got the antidote for you!\n\nThis year, we are introducing Canine Companion: Interacting with Dogs, a collaboration between Student Life Office and Computing Club.\n\nRegistration is free for all NUS SoC students!\n\nPlease note:\nEvent is limited to 10-minute timeslot per person. You will be allocated to, and informed about a specific 10-minute timeslot within the window period that the event is conducted.\n\nDo check out some other exciting workshops under SoC Wellness Festival 2024 too\ud83d\ude0e\ud83d\ude0e:\n- Craft your own Musical Box\n- Build your own Air Plant Terrarium\n- Embrace Nature with Forest Therapy\n\nSlots are limited so do register your interest at https://forms.office.com/r/4vfPX0aiCF now!\n", "link": "wellness_festival", "imgSrc": "/articles/wellness_festival.jpg"}, "bizcom_league": {"title": "BIZCOM League", "body": "\nHEY SOC\ud83e\udd13\nRecess week is almost here \ud83d\ude0b! are you looking for ways to destress?? \ud83d\ude0c AND meet new friends \ud83e\udd73\ud83e\udd73?\n\nJoin us at BIZCOM LEAGUE, and stand a chance to win:\n- HaiDiLao vouchers \ud83c\udf72 - Grab vouchers \ud83d\ude97\n- NTUC vouchers \ud83c\udf7e\n- JBL speakers \ud83d\udd08!\n- FREE JERSEYS \ud83d\udc55\nanddddd most importantly, IT\u2019s FREE!!!! \ud83e\udd11\n\n\nBIZCOM LEAGUE IS BACK AGAIN\ud83d\ude31\ud83d\ude31\ud83e\udd29\ud83e\udd29 between NUS Computing Club and NUS Bizad Club where you get to make some new Biz friends! (You may sign up in groups of 8 MAX, or even solo!)\nAll you have to do is sign up and play four sports (basketball\ud83c\udfc0 , dodgeball \ud83e\udd3e\u200d\u2640\ufe0f, ultimate frisbee\ud83e\udd4f , captain\u2019s ball \ud83c\udfd0) over the course of two days!\n\nWHEN?\n\u203c\ufe0f26 Feb 9am - 7pm\n\u203c\ufe0f27 Feb 9am - 7pm\n\nSo WHAT ARE YOU WAITING FOR\u2049\ufe0fSIGN UP NOW\u203c\ufe0f you won\u2019t regret it \ud83e\udd2d\nhttps://nus.campuslabs.com/engage/submitter/form/start/626464\n", "link": "bizcom_league", "imgSrc": "/articles/bizcom_league.jpg"}, "freshman_social_camp": {"title": "Freshman Social Camp", "body": "\nDates: 19th June - 22nd June 2024\n\nTheme: Harry Potter\n\nFSC is crafted to kickstart your university journey with enduring friendships and unforgettable experiences. Engage in a variety of physical and intellectual games, participate in team bonding exercises, and compete for exciting team and individual prizes. You will also have the opportunity to attend the beach finale event Bash together with your new friends, solidifying your friendships.\n\nSignup links will be released soon! Stay tuned!\n", "link": "freshman_social_camp", "imgSrc": "/announcements/fsc.jpg"}, "freshman_orientation_camp": {"title": "Freshman Orientation Camp", "body": "\nDates: 24th July - 27th July 2024\n\nTheme: Teenage Mutant Ninja Turtles\n\nFOW is a 4-day physical orientation camp where seniors help freshmen adapt to different aspects of university life through preparatory talks and team-building activities. Forge lasting friendships as you navigate campus resources and academic challenges together. Look forward to strategic team games that develop you both intellectually and physically.\n\nSignup links will be released soon! Stay tuned!\n", "link": "freshman_orientation_camp", "imgSrc": "/announcements/fow.jpg"}, "freshman_finale_camp": {"title": "Freshman Finale Camp", "body": "\nDates: 5th August - 7th August 2024\n\nTheme: Elementals: Rediscover your inner element\n\nAbstract: FFC is a 3-day physical summer camp, perfectly tailored for international students gearing up for matriculation closer to August. The camp offers an array of theme-based activities such as flag-building and exhilarating house face-offs. Engage in friendly competition alongside your housemates, strategizing to earn glory for your elemental faction in a series of thrilling challenges. End the camp on a high note with its campfire and barbecue finale under the stars.\n\nSignup links will be released soon! Stay tuned!\n", "link": "freshman_finale_camp", "imgSrc": "/announcements/ffc.jpg"}, "computing_bash": {"title": "Computing Bash", "body": "\nEvent date: 16th August 2024\n\nA fun-filled beach finale event where freshmen and seniors come together to wrap up the entire orientation experience with a night of performances, games, and food. Held at Sentosa Beach, Bash 2024 offers an electrifying atmosphere with DJ sets, inflatable obstacle courses, and much more.\n\nSignup links will be released soon! Stay tuned!\n", "link": "computing_bash", "imgSrc": "/announcements/bash.jpg"}, "computing_day": {"title": "Computing Day", "body": "\nComputing Day 2024 is a vibrant celebration organized by the NUS Students' Computing Club and the Student Life Office, scheduled for August 14, 2024, at COM3 MPH, NUS. Under the theme \"Code & Chill,\" this event aims to foster community spirit and pride among students, staff, and alumni of the School of Computing (SoC). The day is packed with activities that highlight the computing culture, including a mix of technical showcases and fun-filled engagements like a coding competition, VR gaming, student project exhibits, and traditional carnival games.\n\nThe event welcomes all NUS members, focusing on encouraging student involvement and showcasing innovations from various Student Interest Groups (SIGs). Highlights include the opening ceremony with the Dean, a coding competition prize ceremony, and a closing ceremony that recaps the day's events. Additional attractions such as food booths, photobooths, and a merchandise booth ensure that there\u2019s something for everyone.\n\nDesigned to build a bridge between students, faculty, and alumni, Computing Day 2024 will provide a platform for showcasing computing projects, sharing experiences, and promoting an inclusive culture within SoC. With comprehensive planning and the participation of key stakeholders, the event is set to be a memorable day that celebrates the essence and excitement of computing at NUS.\n", "link": "computing_day", "imgSrc": "/announcements/computing_day.png"}, "rag_and_flag": {"title": "Rag and Flag", "body": "\nRag and Flag is an annual event at NUS that brings together students from various faculties to participate in community service and fundraising activities. The day begins with students engaging in volunteer work across different locations, followed by a vibrant parade featuring student performances and creatively decorated floats. This event not only fosters a sense of unity and social responsibility among students but also helps raise funds for various charitable causes. Rag and Flag embodies the spirit of giving back to the community while celebrating student creativity and teamwork.\n", "link": "rag_and_flag", "imgSrc": "/announcements/rag_and_flag.jpg"}} \ No newline at end of file diff --git a/index.html b/index.html index 13196e1..17900a7 100644 --- a/index.html +++ b/index.html @@ -14,6 +14,7 @@ type='text/css' href='https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css' > + NUS Students' Computing Club diff --git a/lib/utils.ts b/lib/utils.ts new file mode 100644 index 0000000..cec6ac9 --- /dev/null +++ b/lib/utils.ts @@ -0,0 +1,6 @@ +import { ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/package-lock.json b/package-lock.json index ad62fa4..6af153f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,20 @@ "version": "0.0.0", "dependencies": { "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@headlessui/react": "^2.1.2", + "@heroicons/react": "^1.0.6", + "clsx": "^2.1.1", + "date-fns": "^3.6.0", + "framer-motion": "^11.3.21", "react": "^18.2.0", "react-calendar": "^4.8.0", "react-dom": "^18.2.0", + "react-element-to-jsx-string": "^15.0.0", "react-hot-toast": "^2.4.1", "react-icons": "^5.0.1", "react-router-dom": "^6.21.1", - "react-slick": "^0.30.2" + "react-slick": "^0.30.2", + "tailwind-merge": "^2.4.0" }, "devDependencies": { "@html-eslint/eslint-plugin": "^0.22.0", @@ -388,6 +395,11 @@ "node": ">=6.9.0" } }, + "node_modules/@base2/pretty-print-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz", + "integrity": "sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.19.10", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", @@ -827,6 +839,80 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", + "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", + "dependencies": { + "@floating-ui/utils": "^0.2.4" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz", + "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.4" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.19", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.19.tgz", + "integrity": "sha512-Jk6zITdjjIvjO/VdQFvpRaD3qPwOHH6AoDHxjhpy+oK4KFgaSP871HYWUAPdnLmx1gQ+w/pB312co3tVml+BXA==", + "dependencies": { + "@floating-ui/react-dom": "^2.1.1", + "@floating-ui/utils": "^0.2.4", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", + "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" + }, + "node_modules/@headlessui/react": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.2.tgz", + "integrity": "sha512-Kb3hgk9gRNRcTZktBrKdHhF3xFhYkca1Rk6e1/im2ENf83dgN54orMW0uSKTXFnUpZOUFZ+wcY05LlipwgZIFQ==", + "dependencies": { + "@floating-ui/react": "^0.26.16", + "@react-aria/focus": "^3.17.1", + "@react-aria/interactions": "^3.21.3", + "@tanstack/react-virtual": "^3.8.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^18", + "react-dom": "^18" + } + }, + "node_modules/@heroicons/react": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-1.0.6.tgz", + "integrity": "sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ==", + "peerDependencies": { + "react": ">= 16" + } + }, "node_modules/@html-eslint/eslint-plugin": { "version": "0.22.0", "resolved": "https://registry.npmjs.org/@html-eslint/eslint-plugin/-/eslint-plugin-0.22.0.tgz", @@ -1013,6 +1099,83 @@ "node": ">=14" } }, + "node_modules/@react-aria/focus": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.17.1.tgz", + "integrity": "sha512-FLTySoSNqX++u0nWZJPPN5etXY0WBxaIe/YuL/GTEeuqUIuC/2bJSaw5hlsM6T2yjy6Y/VAxBcKSdAFUlU6njQ==", + "dependencies": { + "@react-aria/interactions": "^3.21.3", + "@react-aria/utils": "^3.24.1", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@react-aria/interactions": { + "version": "3.21.3", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.3.tgz", + "integrity": "sha512-BWIuf4qCs5FreDJ9AguawLVS0lV9UU+sK4CCnbCNNmYqOWY+1+gRXCsnOM32K+oMESBxilAjdHW5n1hsMqYMpA==", + "dependencies": { + "@react-aria/ssr": "^3.9.4", + "@react-aria/utils": "^3.24.1", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz", + "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@react-aria/utils": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.24.1.tgz", + "integrity": "sha512-O3s9qhPMd6n42x9sKeJ3lhu5V1Tlnzhu6Yk8QOvDuXf7UGuUjXf9mzfHJt1dYzID4l9Fwm8toczBzPM9t0jc8Q==", + "dependencies": { + "@react-aria/ssr": "^3.9.4", + "@react-stately/utils": "^3.10.1", + "@react-types/shared": "^3.23.1", + "@swc/helpers": "^0.5.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@react-stately/utils": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.1.tgz", + "integrity": "sha512-VS/EHRyicef25zDZcM/ClpzYMC5i2YGN6uegOeQawmgfGjb02yaCX0F0zR69Pod9m2Hr3wunTbtpgVXvYbZItg==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@react-types/shared": { + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.23.1.tgz", + "integrity": "sha512-5d+3HbFDxGZjhbMBeFHRQhexMFt4pUce3okyRtUVKbbedQFUrtXSBg9VszgF2RTeQDKDkMCIQDtz5ccP/Lk1gw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, "node_modules/@remix-run/router": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.1.tgz", @@ -1282,6 +1445,39 @@ "eslint": ">=8.40.0" } }, + "node_modules/@swc/helpers": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.12.tgz", + "integrity": "sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.8.3.tgz", + "integrity": "sha512-9ICwbDUUzN99CJIGc373i8NLoj6zFTKI2Hlcmo0+lCSAhPQ5mxq4dGOMKmLYoEFyHcGQ64Bd6ZVbnPpM6lNK5w==", + "dependencies": { + "@tanstack/virtual-core": "3.8.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.8.3.tgz", + "integrity": "sha512-vd2A2TnM5lbnWZnHi9B+L2gPtkSeOtJOAw358JqokIH1+v2J7vUAzFVPwB/wrye12RFOurffXu33plm4uQ+JBQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -2132,9 +2328,9 @@ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } @@ -2203,6 +2399,15 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2931,6 +3136,30 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/framer-motion": { + "version": "11.3.21", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.21.tgz", + "integrity": "sha512-D+hfIsvzV8eL/iycld4K+tKlg2Q2LdwnrcBEohtGw3cG1AIuNYATbT5RUqIM1ndsAk+EfGhoSGf0UaiFodc5Tw==", + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3502,6 +3731,14 @@ "node": ">=8" } }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -4477,6 +4714,25 @@ "react": "^18.2.0" } }, + "node_modules/react-element-to-jsx-string": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz", + "integrity": "sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==", + "dependencies": { + "@base2/pretty-print-object": "1.0.1", + "is-plain-object": "5.0.0", + "react-is": "18.1.0" + }, + "peerDependencies": { + "react": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", + "react-dom": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0" + } + }, + "node_modules/react-element-to-jsx-string/node_modules/react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==" + }, "node_modules/react-hot-toast": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", @@ -4493,9 +4749,9 @@ } }, "node_modules/react-icons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz", - "integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", + "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", "peerDependencies": { "react": "*" } @@ -5131,6 +5387,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, + "node_modules/tailwind-merge": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.4.0.tgz", + "integrity": "sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz", @@ -5250,6 +5520,11 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 88c237c..c9f969b 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,20 @@ }, "dependencies": { "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@headlessui/react": "^2.1.2", + "@heroicons/react": "^1.0.6", + "clsx": "^2.1.1", + "date-fns": "^3.6.0", + "framer-motion": "^11.3.21", "react": "^18.2.0", "react-calendar": "^4.8.0", "react-dom": "^18.2.0", + "react-element-to-jsx-string": "^15.0.0", "react-hot-toast": "^2.4.1", "react-icons": "^5.0.1", "react-router-dom": "^6.21.1", - "react-slick": "^0.30.2" + "react-slick": "^0.30.2", + "tailwind-merge": "^2.4.0" }, "devDependencies": { "@html-eslint/eslint-plugin": "^0.22.0", diff --git a/public/announcements/computing_day.png b/public/announcements/computing_day.png new file mode 100644 index 0000000..94a0b2f Binary files /dev/null and b/public/announcements/computing_day.png differ diff --git a/public/announcements/elections.jpg b/public/announcements/elections.jpg new file mode 100644 index 0000000..02fe471 Binary files /dev/null and b/public/announcements/elections.jpg differ diff --git a/public/announcements/rag_and_flag.jpg b/public/announcements/rag_and_flag.jpg new file mode 100644 index 0000000..53748fa Binary files /dev/null and b/public/announcements/rag_and_flag.jpg differ diff --git a/public/elections/Computing Club 27th MC Election Standing Order AY2425.pdf b/public/elections/Computing Club 27th MC Election Standing Order AY2425.pdf new file mode 100644 index 0000000..443a905 Binary files /dev/null and b/public/elections/Computing Club 27th MC Election Standing Order AY2425.pdf differ diff --git a/public/elections/Constituent_Club_Management_Committee_Election_Regulations_Rev_Ed.pdf b/public/elections/Constituent_Club_Management_Committee_Election_Regulations_Rev_Ed.pdf new file mode 100644 index 0000000..a10ce3b Binary files /dev/null and b/public/elections/Constituent_Club_Management_Committee_Election_Regulations_Rev_Ed.pdf differ diff --git a/public/elections/NUSSU_Constitution_approved_by_BOT_on_26072018.pdf b/public/elections/NUSSU_Constitution_approved_by_BOT_on_26072018.pdf new file mode 100644 index 0000000..c9189b4 Binary files /dev/null and b/public/elections/NUSSU_Constitution_approved_by_BOT_on_26072018.pdf differ diff --git a/public/elections/NUSSU_Executive_Committee_Election_Regulations_Rev_Ed_2021_Mar.pdf b/public/elections/NUSSU_Executive_Committee_Election_Regulations_Rev_Ed_2021_Mar.pdf new file mode 100644 index 0000000..ebddf3e Binary files /dev/null and b/public/elections/NUSSU_Executive_Committee_Election_Regulations_Rev_Ed_2021_Mar.pdf differ diff --git a/src/App.jsx b/src/App.jsx index dfd0ee6..527a9f4 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ import { useEffect } from 'react'; import { useLocation, Routes, Route } from 'react-router-dom'; -import { About, Article, Events, Home, Privacy, Resources } from './pages'; +import { About, Article, Events, Home, Privacy, Resources, Elections } from './pages'; import { Toaster } from 'react-hot-toast'; import NavigationBar from './layout/NavigationBar'; import Footer from './layout/Footer'; @@ -24,6 +24,7 @@ function App() { } /> } /> + } /> diff --git a/src/index.css b/src/index.css index 375049c..e1a76cf 100644 --- a/src/index.css +++ b/src/index.css @@ -9,9 +9,11 @@ html, body { font-family: 'Montserrat', sans-serif; overscroll-behavior: none; + scroll-behavior: smooth; + scroll-padding-top: 4.5rem; } -a { +/* a { font-weight: 500; color: 'white'; text-decoration: inherit; @@ -51,4 +53,4 @@ button:focus-visible { button { background-color: #f9f9f9; } -} +} */ diff --git a/src/layout/NavigationMenu.tsx b/src/layout/NavigationMenu.tsx index c93ed3f..64cab26 100644 --- a/src/layout/NavigationMenu.tsx +++ b/src/layout/NavigationMenu.tsx @@ -11,6 +11,7 @@ function NavigationMenu() { 'About': '/about', 'Events': '/events', 'Resources': '/resources', + 'Elections': '/elections', 'Photos': 'https://www.flickr.com/photos/137141057@N04/albums/', }; diff --git a/src/pages/elections/Faq.tsx b/src/pages/elections/Faq.tsx new file mode 100644 index 0000000..cb18121 --- /dev/null +++ b/src/pages/elections/Faq.tsx @@ -0,0 +1,52 @@ +/* eslint-disable react/no-unescaped-entities */ +/* eslint-disable @stylistic/max-len */ +import React from 'react'; +import './index.css'; +import { FAQ } from './constants'; + +function Faq() { + return ( +
+
+

FAQ

+

+ Frequently asked questions. +

+
+
+ {FAQ.map((faq, index) => ( +
+
+ + {faq.question} + + + + + + +

+ {faq.answer} +

+
+
+ ))} +
+
+ ); +} + +export default Faq; diff --git a/src/pages/elections/Footer.tsx b/src/pages/elections/Footer.tsx new file mode 100644 index 0000000..4ac389c --- /dev/null +++ b/src/pages/elections/Footer.tsx @@ -0,0 +1,51 @@ +import React from 'react'; + +function Footer() { + return ( +
+

+ Empowering Students.{' '} + Enriching Lives. +

+ + + +
+ ); +} + +export default Footer; diff --git a/src/pages/elections/Officer.tsx b/src/pages/elections/Officer.tsx new file mode 100644 index 0000000..0e7865b --- /dev/null +++ b/src/pages/elections/Officer.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { officers } from './constants'; +import RoleCard from '../about/RoleCard'; + +function Officer() { + return ( +
+

Elections Committee

+
+ {officers.map((member) => { + const imgSrc: string = `/members/${member.name.replace( + /\s/g, + '', + )}.jpg`; + return ( + + ); + })} +
+
+ ); +} + +export default Officer; diff --git a/src/pages/elections/Regulations.tsx b/src/pages/elections/Regulations.tsx new file mode 100644 index 0000000..7388eb7 --- /dev/null +++ b/src/pages/elections/Regulations.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import './index.css'; +import { regulationsData } from './constants'; + +function Regulations() { + return ( +
+
+

Regulations

+

+ Last updated as of 2 August, 2024. +

+
+
+ {regulationsData.map((regulation, index) => ( +
+
+ +
+

+ + {regulation.title} + +

+
+ ))} +
+
+ ); +} + +export default Regulations; diff --git a/src/pages/elections/Roles.tsx b/src/pages/elections/Roles.tsx new file mode 100644 index 0000000..ce0670e --- /dev/null +++ b/src/pages/elections/Roles.tsx @@ -0,0 +1,75 @@ +/* eslint-disable react/no-unescaped-entities */ +/* eslint-disable @stylistic/max-len */ +import React from 'react'; +import './index.css'; +import { wingsData } from './constants'; + +function Roles() { + return ( +
+
+

Roles

+

+ Learn more about the roles available in the NUS Students' Computing + Club. +

+
+
+ {wingsData.map((wing, index) => ( +
+
+ + {wing.title} + + + + + + +
+
    + {wing.roles.map((role, roleIndex) => ( +
  • + {role.name} + {role.subRoles && ( +
      + {role.subRoles.map((subRole, subRoleIndex) => ( +
    • + {subRole} +
    • + ))} +
    + )} +
  • + ))} +
+ {/* */} +
+
+
+ ))} +
+
+ ); +}; + +export default Roles; diff --git a/src/pages/elections/Timeline.tsx b/src/pages/elections/Timeline.tsx new file mode 100644 index 0000000..a139f13 --- /dev/null +++ b/src/pages/elections/Timeline.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { TimelineEvents } from './constants'; + +function Timeline() { + return ( +
+
+
+
+
+

Timeline

+ + The election will run through the first half of{' '} + + AY24/25 Semester 1 + + . Do take note of key dates and events. For more information + about each phase, check out our{' '} + + FAQ + {' '} + section! + +
+
+
+
+ {TimelineEvents.map((event, index) => ( +
+

+ {event.title} +

+ +

{event.description}

+
+ ))} +
+
+
+
+
+ ); +} + +export default Timeline; diff --git a/src/pages/elections/constants.js b/src/pages/elections/constants.js new file mode 100644 index 0000000..09bf0aa --- /dev/null +++ b/src/pages/elections/constants.js @@ -0,0 +1,210 @@ +export const TimelineEvents = [ + { + title: 'Nomination Period Starts', + date: '09 Aug 2024, Friday', + description: + 'Nomination period starts for the election of the new committee members.', + }, + { + title: 'Nomination Period Ends', + date: '17 Aug 2024, Friday', + description: + 'The final day for submitting nominations for the election of the new committee members.', + }, + { + title: 'Campaigning Period', + date: '19 Aug 2024, Monday - 26 Aug 2024, Monday', + description: 'Candidates campaign to gather support from the voters.', + }, + { + title: 'Cooling Off Day', + date: '27 Aug 2024, Tuesday', + description: + 'A day for voters to reflect on their choices before voting, with no campaigning allowed.', + }, + { + title: 'External Elections', + date: '28 Aug 2024, Wednesday - 30 Aug 2024, Friday', + description: + 'External elections are held to elect representatives from different groups.', + }, + { + title: 'Results Release of External Elections', + date: 'BY 4 Sep 2024, Tuesday', + description: 'The results of the external elections are announced.', + }, + // { + // 'title': 'Internal Elections', + // 'date': '5 Sep 2024, Thursday to 7 Sep 2024, Saturday', + // 'description': 'Internal elections are held to elect specific roles within the organization.', + // }, + // { + // 'title': 'Results Release of Internal Elections', + // 'date': 'BY 13 Sep 2024, Friday', + // 'description': 'The results of the internal elections are announced.', + // }, + // { + // 'title': 'Club Annual General Meeting', + // 'date': '14 Sep 2024, Saturday (tentative)', + // 'description': 'The annual general meeting of the club to discuss the past year and future plans.', + // }, + // { + // 'title': '46th NUSSU Council First Council Meeting', + // 'date': '21-22 September 2021', + // 'description': 'The first council meeting of the 46th NUSSU Council to outline the agenda for the new term.', + // }, +]; + +export const FAQ = [ + { + question: 'What are the items I need to prepare?', + answer: + 'Awesome that you\'re considering joining us! You\'ll have to submit the nomination forms to elections@nuscomputing.com together with their related material. If there are no issues with the nomination, candidates can start preparing the publicity materials for their campaign.', + }, + { + question: 'What\'s the commitment like?', + answer: + 'The amount of commitment varies between every role and also depends on the number of initiatives/events you wish to push out. Contact the respective MC members for a clearer understanding of the commitment level. You can reach us at elections@nuscomputing.com!', + }, + { + question: 'What\'re all the roles in Computing Club?', + answer: 'You can find all the roles and their responsibilities below.', + }, + { + question: 'Can I try for multiple roles?', + answer: 'Yes, you can indicate your second choice in the nomination form.', + }, + { + question: 'Can I join other CCAs with Computing Club?', + answer: + 'Yup, you can be part of multiple CCAs in NUS. However, if you are intending to run for President, you cannot be the President of another CCA. We recommend checking your timetable and calendar to ensure there aren\'t any other major commitments that may compromise your best work with us!', + }, + { + question: 'Are there any pre-requisites?', + answer: + 'There is no pre-requisite to be in the Computing Club Management Committee, except that upon election, you are required to perform and learn on the job leadership, management, communication, processes, and procedures of the Union, and day-to-day execution of your portfolio.', + }, + { + question: 'Can I change my decision?', + answer: + 'You can pull out of elections at any point in time, just let us know! The positions you include in your nomination form is not final; you make your decision during the Internal Elections. If you are unsure of which position but want to be a part of the management committee, join us for externals first and decide after!', + }, +]; + +export const regulationsData = [ + // { + // title: 'Union Elections Standing Orders', + // link: 'assets/elections/regulations/Union_Election_Standing_Orders.pdf', + // color: '#78e08f', + // }, + { + title: 'NUSSU Executive Committee Election Regulations', + link: '/elections/NUSSU_Executive_Committee_Election_Regulations_Rev_Ed_2021_Mar.pdf', + color: '#f19066', + }, + { + title: 'Constituent Club Management Committee Election Regulations', + link: '/elections/Constituent_Club_Management_Committee_Election_Regulations_Rev_Ed.pdf', + color: '#395B9B', + }, + { + title: 'AY 2024/2025 NUSSU Students\' Computing Club Election Standing Orders', + link: '/elections/Computing Club 27th MC Election Standing Order AY2425.pdf', + color: '#778beb', + }, + { + title: 'Constitution of the National University of Singapore Students\' Union', + link: '/elections/NUSSU_Constitution_approved_by_BOT_on_26072018.pdf', + color: '#93c6c3', + }, +]; + +export const officers = [ + { + name: 'Mervyn Seah', + role: 'Returning Officer', + }, + { + name: 'Jamie Ho', + role: 'Election Officer', + }, + { + name: 'Ng Le Xuan', + role: 'Election Officer', + }, +]; + +export const wingsData = [ + { + title: 'Presidential Wing', + roles: [ + { name: 'President' }, + { name: 'Finance Secretary', subRoles: ['Deputy Finance Secretary'] }, + { name: 'Tech Lead', subRoles: ['Deputy Tech Lead'] }, + { name: 'General Secretary', subRoles: ['Deputy General Secretary'] }, + ], + link: 'elections/presidentialwing.html', + }, + { + title: 'External Relations', + roles: [ + { name: 'Vice President (External Relations)' }, + { + name: 'Director of Marketing', + subRoles: [ + 'Deputy Director of Marketing (Sponsorships)', + 'Deputy Director of Marketing (Merchandise)', + ], + }, + { + name: 'Director of Publicity', + subRoles: [ + 'Deputy Director of Publicity', + ], + }, + ], + link: 'elections/externalrelations.html', + }, + { + title: 'Internal Relations', + roles: [ + { name: 'Vice President (Internal Relations)' }, + { name: 'Director of Welfare', subRoles: ['Deputy Director of Welfare'] }, + { name: 'Director of Sports', subRoles: ['Deputy Director of Sports'] }, + ], + link: 'elections/internalrelations.html', + }, + { + title: 'Student Development', + roles: [ + { name: 'Vice President (Student Development)' }, + { + name: 'Director of Academic Liaison', + subRoles: ['Deputy Director of Academic Liaison'], + }, + { name: 'Director of Community Engagement' }, + { name: 'Director of Rag & Flag', subRoles: [ + 'Deputy Director of Rag & Flag', + ] }, + ], + link: 'elections/studentdevelopment.html', + }, + { + title: 'Student Life', + roles: [ + { name: 'Vice President (Student Life)' }, + { + name: 'Director of Freshmen Orientation Projects', + subRoles: [ + 'Deputy Director of Freshmen Orientation Projects', + 'Deputy Director of Freshmen Orientation Projects', + ], + }, + { + name: 'Director of Student Engagement', + subRoles: ['Deputy Director of Student Engagement'], + }, + ], + link: 'elections/studentlife.html', + }, +]; diff --git a/src/pages/elections/index.css b/src/pages/elections/index.css new file mode 100644 index 0000000..f10901e --- /dev/null +++ b/src/pages/elections/index.css @@ -0,0 +1,23 @@ +.elections { + @apply + flex + flex-col + justify-center + items-center + gap-8 + mt-8 + mx-auto + w-full + ; +} + +.faq>h1, .elections .title, .regulations>h1, .officers>h1, .roles>h1 { + @apply + mx-8 + md:mx-64 + text-3xl + font-bold + text-center + text-primary + ; +} diff --git a/src/pages/elections/index.tsx b/src/pages/elections/index.tsx new file mode 100644 index 0000000..17abe3b --- /dev/null +++ b/src/pages/elections/index.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import Faq from './Faq'; +import Timeline from './Timeline'; +import Regulations from './Regulations'; +import Footer from './Footer'; +import Officer from './Officer'; +import Roles from './Roles'; + +function Elections() { + return ( +
+

Elections

+

+ Find out how you{' '} + can play a part in the NUS Students' Computing Club Elections + today! +

+ + + + + +
+
+ ); +} + +export default Elections; diff --git a/src/pages/events/Calendar.tsx b/src/pages/events/Calendar.tsx new file mode 100644 index 0000000..0313173 --- /dev/null +++ b/src/pages/events/Calendar.tsx @@ -0,0 +1,222 @@ +import React, { useState, useRef, useEffect } from 'react'; +import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid'; +import { + add, + eachDayOfInterval, + endOfMonth, + format, + getDay, + isEqual, + isSameMonth, + isToday, + isWithinInterval, + parse, + parseISO, + startOfDay, + startOfToday, +} from 'date-fns'; +import articles from './articles.json'; +import SearchResult from './SearchResult'; + +type Article = { + title: string; + body: string; + link: string; + imgSrc: string; + startDatetime: string; + endDatetime: string; +}; + +const articlesData: Article[] = Object.values(articles); + +function classNames(...classes: (string | boolean | null)[]) { + return classes.filter(Boolean).join(' '); +} + +export default function Calendar() { + const today = startOfToday(); + const [selectedDay, setSelectedDay] = useState(null); + const [currentMonth, setCurrentMonth] = useState(format(today, 'MMM-yyyy')); + const firstDayCurrentMonth = parse(currentMonth, 'MMM-yyyy', new Date()); + + const days = eachDayOfInterval({ + start: firstDayCurrentMonth, + end: endOfMonth(firstDayCurrentMonth), + }); + + const calendarRef = useRef(null); + const resultsRef = useRef(null); + + function previousMonth() { + const firstDayNextMonth = add(firstDayCurrentMonth, { months: -1 }); + setCurrentMonth(format(firstDayNextMonth, 'MMM-yyyy')); + } + + function nextMonth() { + const firstDayNextMonth = add(firstDayCurrentMonth, { months: 1 }); + setCurrentMonth(format(firstDayNextMonth, 'MMM-yyyy')); + } + + const displayedArticles = selectedDay + ? articlesData.filter((article) => + isWithinInterval(startOfDay(selectedDay), { + start: startOfDay(parseISO(article.startDatetime)), + end: startOfDay(parseISO(article.endDatetime)), + }), + ) + : articlesData; + + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if ( + calendarRef.current && + !calendarRef.current.contains(event.target as Node) && + resultsRef.current && + !resultsRef.current.contains(event.target as Node) + ) { + setSelectedDay(null); + } + } + + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [calendarRef, resultsRef]); + + const handleResultsAreaClick = (event: React.MouseEvent) => { + if (event.target === event.currentTarget) { + setSelectedDay(null); + } + }; + + return ( +
+
+
+
+
+

+ {format(firstDayCurrentMonth, 'MMMM yyyy')} +

+ + +
+
+
S
+
M
+
T
+
W
+
T
+
F
+
S
+
+
+ {days.map((day, dayIdx) => ( +
+ + +
+ {articlesData.some((article) => + isWithinInterval(startOfDay(day), { + start: startOfDay(parseISO(article.startDatetime)), + end: startOfDay(parseISO(article.endDatetime)), + }), + ) && ( +
+ )} +
+
+ ))} +
+
+
+

+ {selectedDay + ? `Events on ${format(selectedDay, 'MMM dd, yyyy')}` + : 'All Events'} +

+
+ {displayedArticles.length > 0 ? ( + displayedArticles.map((article) => ( + 120 ? article.body.substring(0, 120) + '...' : article.body} + key={article.link} + /> + )) + ) : ( +

No events found.

+ )} +
+
+
+
+
+ ); +} + +const colStartClasses = [ + '', + 'col-start-2', + 'col-start-3', + 'col-start-4', + 'col-start-5', + 'col-start-6', + 'col-start-7', +]; diff --git a/src/pages/events/articles.json b/src/pages/events/articles.json index a94c9bc..8dcca2d 100644 --- a/src/pages/events/articles.json +++ b/src/pages/events/articles.json @@ -1,26 +1,34 @@ { - "freshman_social_camp": { - "title": "Freshman Social Camp", - "body": "\nDates: 19th June - 22nd June 2024\n\nTheme: Harry Potter\n\nFSC is crafted to kickstart your university journey with enduring friendships and unforgettable experiences. Engage in a variety of physical and intellectual games, participate in team bonding exercises, and compete for exciting team and individual prizes. You will also have the opportunity to attend the beach finale event Bash together with your new friends, solidifying your friendships.\n\nSignup links will be released soon! Stay tuned!\n", - "link": "freshman_social_camp", - "imgSrc": "/announcements/fsc.jpg" - }, - "freshman_orientation_camp": { - "title": "Freshman Orientation Camp", - "body": "\nDates: 24th July - 27th July 2024\n\nTheme: Teenage Mutant Ninja Turtles\n\nFOW is a 4-day physical orientation camp where seniors help freshmen adapt to different aspects of university life through preparatory talks and team-building activities. Forge lasting friendships as you navigate campus resources and academic challenges together. Look forward to strategic team games that develop you both intellectually and physically.\n\nSignup links will be released soon! Stay tuned!\n", - "link": "freshman_orientation_camp", - "imgSrc": "/announcements/fow.jpg" - }, "freshman_finale_camp": { "title": "Freshman Finale Camp", - "body": "\nDates: 5th August - 7th August 2024\n\nTheme: Elementals: Rediscover your inner element\n\nFFC is a 3-day physical summer camp, perfectly tailored for international students gearing up for matriculation closer to August. The camp offers an array of theme-based activities such as flag-building and exhilarating house face-offs. Engage in friendly competition alongside your housemates, strategizing to earn glory for your elemental faction in a series of thrilling challenges. End the camp on a high note with its campfire and barbecue finale under the stars.\n\nSignup links will be released soon! Stay tuned!\n", + "body": "Theme: Elementals: Rediscover your inner element\n\nAbstract: FFC is a 3-day physical summer camp, perfectly tailored for international students gearing up for matriculation closer to August. The camp offers an array of theme-based activities such as flag-building and exhilarating house face-offs. Engage in friendly competition alongside your housemates, strategizing to earn glory for your elemental faction in a series of thrilling challenges. End the camp on a high note with its campfire and barbecue finale under the stars.\n\nSignup links will be released soon! Stay tuned!\n", "link": "freshman_finale_camp", - "imgSrc": "/announcements/ffc.jpg" + "imgSrc": "/announcements/ffc.jpg", + "startDatetime": "2024-08-05T09:00:00", + "endDatetime": "2024-08-07T17:00:00" }, "computing_bash": { "title": "Computing Bash", - "body": "\nEvent date: 16th August 2024\n\nA fun-filled beach finale event where freshmen and seniors come together to wrap up the entire orientation experience with a night of performances, games, and food. Held at Sentosa Beach, Bash 2024 offers an electrifying atmosphere with DJ sets, inflatable obstacle courses, and much more.\n\nSignup links will be released soon! Stay tuned!\n", + "body": "A fun-filled beach finale event where freshmen and seniors come together to wrap up the entire orientation experience with a night of performances, games, and food. Held at Sentosa Beach, Bash 2024 offers an electrifying atmosphere with DJ sets, inflatable obstacle courses, and much more.\n\nSignup links will be released soon! Stay tuned!\n", "link": "computing_bash", - "imgSrc": "/announcements/bash.jpg" + "imgSrc": "/announcements/bash.jpg", + "startDatetime": "2024-08-16T09:00:00", + "endDatetime": "2024-08-16T23:59:59" + }, + "rag_and_flag": { + "title": "Rag & Flag", + "body": "Rag and Flag is an annual event at NUS that brings together students from various faculties to participate in community service and fundraising activities. The day begins with students engaging in volunteer work across different locations, followed by a vibrant parade featuring student performances and creatively decorated floats. This event not only fosters a sense of unity and social responsibility among students but also helps raise funds for various charitable causes. Rag and Flag embodies the spirit of giving back to the community while celebrating student creativity and teamwork.", + "link": "rag_and_flag", + "imgSrc": "/announcements/rag_and_flag.jpg", + "startDatetime": "2024-08-10T09:00:00", + "endDatetime": "2024-08-10T18:00:00" + }, + "computing_day": { + "title": "Computing Day", + "body": "Computing Day 2024 is a vibrant celebration organized by the NUS Students' Computing Club and the Student Life Office, scheduled for August 14, 2024, at COM3 MPH, NUS. Under the theme \"Code & Chill,\" this event aims to foster community spirit and pride among students, staff, and alumni of the School of Computing (SoC). The day is packed with activities that highlight the computing culture, including a mix of technical showcases and fun-filled engagements like a coding competition, VR gaming, student project exhibits, and traditional carnival games.\n\nThe event welcomes all NUS members, focusing on encouraging student involvement and showcasing innovations from various Student Interest Groups (SIGs). Highlights include the opening ceremony with the Dean, a coding competition prize ceremony, and a closing ceremony that recaps the day's events. Additional attractions such as food booths, photobooths, and a merchandise booth ensure that there’s something for everyone.\n\nDesigned to build a bridge between students, faculty, and alumni, Computing Day 2024 will provide a platform for showcasing computing projects, sharing experiences, and promoting an inclusive culture within SoC. With comprehensive planning and the participation of key stakeholders, the event is set to be a memorable day that celebrates the essence and excitement of computing at NUS.\n", + "link": "computing_day", + "imgSrc": "/announcements/computing_day.png", + "startDatetime": "2024-09-04T09:00:00", + "endDatetime": "2024-09-04T17:00:00" } } diff --git a/src/pages/events/dump.py b/src/pages/events/dump.py index b3fe900..557a7e1 100644 --- a/src/pages/events/dump.py +++ b/src/pages/events/dump.py @@ -82,6 +82,18 @@ Signup links will be released soon! Stay tuned! ''' +computing_day_body = ''' +Computing Day 2024 is a vibrant celebration organized by the NUS Students' Computing Club and the Student Life Office, scheduled for August 14, 2024, at COM3 MPH, NUS. Under the theme "Code & Chill," this event aims to foster community spirit and pride among students, staff, and alumni of the School of Computing (SoC). The day is packed with activities that highlight the computing culture, including a mix of technical showcases and fun-filled engagements like a coding competition, VR gaming, student project exhibits, and traditional carnival games. + +The event welcomes all NUS members, focusing on encouraging student involvement and showcasing innovations from various Student Interest Groups (SIGs). Highlights include the opening ceremony with the Dean, a coding competition prize ceremony, and a closing ceremony that recaps the day's events. Additional attractions such as food booths, photobooths, and a merchandise booth ensure that there’s something for everyone. + +Designed to build a bridge between students, faculty, and alumni, Computing Day 2024 will provide a platform for showcasing computing projects, sharing experiences, and promoting an inclusive culture within SoC. With comprehensive planning and the participation of key stakeholders, the event is set to be a memorable day that celebrates the essence and excitement of computing at NUS. +''' + +rag_and_flag_body = """ +Rag and Flag is an annual event at NUS that brings together students from various faculties to participate in community service and fundraising activities. The day begins with students engaging in volunteer work across different locations, followed by a vibrant parade featuring student performances and creatively decorated floats. This event not only fosters a sense of unity and social responsibility among students but also helps raise funds for various charitable causes. Rag and Flag embodies the spirit of giving back to the community while celebrating student creativity and teamwork. +""" + # temporary stopgap for article content # convert multiline articles into json if __name__ == '__main__': @@ -122,5 +134,17 @@ 'link': 'computing_bash', 'imgSrc': '/announcements/bash.jpg' }, + 'computing_day': { + 'title': 'Computing Day', + 'body': computing_day_body, + 'link': 'computing_day', + 'imgSrc': '/announcements/computing_day.png' + }, + 'rag_and_flag': { + 'title': 'Rag and Flag', + 'body': rag_and_flag_body, + 'link': 'rag_and_flag', + 'imgSrc': '/announcements/rag_and_flag.jpg' + } } json.dump(articles, open('articles.json', 'w+')) diff --git a/src/pages/events/index.tsx b/src/pages/events/index.tsx index 3940880..d273464 100644 --- a/src/pages/events/index.tsx +++ b/src/pages/events/index.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import Calendar from 'react-calendar'; import { toast } from 'react-hot-toast'; import { FaSearch } from 'react-icons/fa'; import articles from './articles.json' with {type: 'json'}; @@ -7,6 +6,7 @@ import SearchResult from './SearchResult'; import WindowCard from '../../layout/WindowCard'; import './index.css'; import 'react-calendar/dist/Calendar.css'; +import Calendar from './Calendar'; function Events() { return ( @@ -16,11 +16,11 @@ function Events() {
-
- {/*
+ {/*
+
-
*/} +
{ @@ -48,14 +48,14 @@ function Events() { > ); }) - } + } */} - {/* TODO: handle this */} -
-
+
*/} {/* TODO: implement functionality */} {/*
@@ -63,6 +63,7 @@ function Events() {
}> */} +
); diff --git a/src/pages/home/announcements.json b/src/pages/home/announcements.json index 28cbfc0..789b580 100644 --- a/src/pages/home/announcements.json +++ b/src/pages/home/announcements.json @@ -1,30 +1,37 @@ [ - { - "title": "Freshman Social Camp", - "desc": "FSC is crafted to kickstart your university journey with enduring friendships and unforgettable experiences. Engage in a variety of physical and intellectual games, participate in team bonding exercises, and compete for exciting team and individual prizes. You will also have the opportunity to attend the beach finale event Bash together with your new friends, solidifying your friendships.", - "date": "19/06/24 - 22/06/24", - "link": "./events/freshman_social_camp", - "imgSrc": "/announcements/fsc.jpg" - }, - { - "title": "Freshman Orientation Week", - "desc": "FOW is a 4-day physical orientation camp where seniors help freshmen adapt to different aspects of university life through preparatory talks and team-building activities. Forge lasting friendships as you navigate campus resources and academic challenges together. Look forward to strategic team games that develop you both intellectually and physically.", - "date": "24/07/24 - 27/07/24", - "link": "./events/freshman_orientation_camp", - "imgSrc": "/announcements/fow.jpg" - }, - { - "title": "Freshman Finale Camp", - "desc": "FFC is a 3-day physical summer camp, perfectly tailored for international students gearing up for matriculation closer to August. The camp offers an array of theme-based activities such as flag-building and exhilarating house face-offs. Engage in friendly competition alongside your housemates, strategizing to earn glory for your elemental faction in a series of thrilling challenges. End the camp on a high note with its campfire and barbecue finale under the stars.", - "date": "05/08/24 - 07/08/24", - "link": "./events/freshman_finale_camp", - "imgSrc": "/announcements/ffc.jpg" - }, - { - "title": "Computing Bash", - "desc": "A fun-filled beach finale event where freshmen and seniors come together to wrap up the entire orientation experience with a night of performances, games, and food. Held at Sentosa Beach, Bash 2024 offers an electrifying atmosphere with DJ sets, inflatable obstacle courses, and much more.", - "date": "16/08/24", - "link": "./events/computing_bash", - "imgSrc": "/announcements/bash.jpg" - } + { + "title": "Rag & Flag", + "desc": "Rag and Flag is an annual event at NUS that brings together students from various faculties to participate in community service and fundraising activities. The day begins with students engaging in volunteer work across different locations, followed by a vibrant parade featuring student performances and creatively decorated floats. This event not only fosters a sense of unity and social responsibility among students but also helps raise funds for various charitable causes. Rag and Flag embodies the spirit of giving back to the community while celebrating student creativity and teamwork.", + "date": "10/08/24", + "link": "./events/rag_and_flag", + "imgSrc": "/announcements/rag_and_flag.jpg" + }, + { + "title": "Freshman Finale Camp", + "desc": "FFC is a 3-day physical summer camp, perfectly tailored for international students gearing up for matriculation closer to August. The camp offers an array of theme-based activities such as flag-building and exhilarating house face-offs. Engage in friendly competition alongside your housemates, strategizing to earn glory for your elemental faction in a series of thrilling challenges. End the camp on a high note with its campfire and barbecue finale under the stars.", + "date": "05/08/24 - 07/08/24", + "link": "./events/freshman_finale_camp", + "imgSrc": "/announcements/ffc.jpg" + }, + { + "title": "Computing Bash", + "desc": "A fun-filled beach finale event where freshmen and seniors come together to wrap up the entire orientation experience with a night of performances, games, and food. Held at Sentosa Beach, Bash 2024 offers an electrifying atmosphere with DJ sets, inflatable obstacle courses, and much more.", + "date": "16/08/24", + "link": "./events/computing_bash", + "imgSrc": "/announcements/bash.jpg" + }, + { + "title": "Computing Day", + "desc": "Join us for Computing Day 2024, a festive celebration of community and technology at NUS, orchestrated by the Students' Computing Club and the Student Life Office. This year’s theme, 'Code & Chill,' invites you to relax and engage with various activities including coding competitions, VR gaming, and student projects. Celebrate the spirit of SoC with food, games, and great company, all set for August 14, 2024, at COM3 MPH.", + "date": "4/09/24", + "link": "./events/computing_day", + "imgSrc": "/announcements/computing_day.png" + }, + { + "title": "Elections 2024", + "desc": "The annual Computing Club Elections are back! This year, we are looking for passionate individuals to join the club's Executive Committee and make a difference in the computing community. If you are interested in taking on a leadership role and contributing to the club's growth, stay tuned for more information on the election process and how you can get involved.", + "date": "Check the elections page for more details", + "link": "./elections", + "imgSrc": "/announcements/elections.jpg" + } ] diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index e3617ee..35cd347 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -41,7 +41,7 @@ function Home() { Keep an eye out for the latest Computing Club events!

- + @@ -57,7 +57,7 @@ function Home() { study planner!

- + diff --git a/src/pages/index.ts b/src/pages/index.ts index 1d8e8b5..f5a06cf 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -4,5 +4,6 @@ import Events from './events/index'; import Home from './home'; import Privacy from './privacy'; import Resources from './resources/index'; +import Elections from './elections'; -export { About, Article, Events, Home, Privacy, Resources }; +export { About, Article, Events, Home, Privacy, Resources, Elections }; diff --git a/tailwind.config.js b/tailwind.config.js index a4d013a..7494c1c 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -4,6 +4,19 @@ export default { content: ['./src/**/*.{js,jsx,ts,tsx}'], theme: { extend: { + animation: { + shimmer: 'shimmer 2s linear infinite', + }, + keyframes: { + shimmer: { + from: { + backgroundPosition: '0 0', + }, + to: { + backgroundPosition: '-200% 0', + }, + }, + }, colors: { primary: '#365486', outline: '#333333', diff --git a/vite.config.js.timestamp-1722590175306-f9f62860a91f1.mjs b/vite.config.js.timestamp-1722590175306-f9f62860a91f1.mjs new file mode 100644 index 0000000..2d374c6 --- /dev/null +++ b/vite.config.js.timestamp-1722590175306-f9f62860a91f1.mjs @@ -0,0 +1,27 @@ +// vite.config.js +import { defineConfig } from "file:///C:/Users/Rayson/Desktop/coding/comclub/comclub-website-2024/node_modules/vite/dist/node/index.js"; +import react from "file:///C:/Users/Rayson/Desktop/coding/comclub/comclub-website-2024/node_modules/@vitejs/plugin-react/dist/index.mjs"; +import tailwindcss from "file:///C:/Users/Rayson/Desktop/coding/comclub/comclub-website-2024/node_modules/tailwindcss/lib/index.js"; +var vite_config_default = defineConfig({ + plugins: [ + react( + { + babel: { + plugins: [ + ["@babel/plugin-syntax-import-attributes"] + ] + } + } + ) + ], + base: "/", + css: { + postcss: { + plugins: [tailwindcss()] + } + } +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxVc2Vyc1xcXFxSYXlzb25cXFxcRGVza3RvcFxcXFxjb2RpbmdcXFxcY29tY2x1YlxcXFxjb21jbHViLXdlYnNpdGUtMjAyNFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiQzpcXFxcVXNlcnNcXFxcUmF5c29uXFxcXERlc2t0b3BcXFxcY29kaW5nXFxcXGNvbWNsdWJcXFxcY29tY2x1Yi13ZWJzaXRlLTIwMjRcXFxcdml0ZS5jb25maWcuanNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0M6L1VzZXJzL1JheXNvbi9EZXNrdG9wL2NvZGluZy9jb21jbHViL2NvbWNsdWItd2Vic2l0ZS0yMDI0L3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSc7XHJcbmltcG9ydCByZWFjdCBmcm9tICdAdml0ZWpzL3BsdWdpbi1yZWFjdCc7XHJcbmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICd0YWlsd2luZGNzcyc7XHJcblxyXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xyXG4gIHBsdWdpbnM6IFtcclxuICAgIHJlYWN0KFxyXG4gICAgICB7XHJcbiAgICAgICAgYmFiZWw6IHtcclxuICAgICAgICAgIHBsdWdpbnM6IFtcclxuICAgICAgICAgICAgWydAYmFiZWwvcGx1Z2luLXN5bnRheC1pbXBvcnQtYXR0cmlidXRlcyddLFxyXG4gICAgICAgICAgXSxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgKSxcclxuICBdLFxyXG4gIGJhc2U6ICcvJyxcclxuICBjc3M6IHtcclxuICAgIHBvc3Rjc3M6IHtcclxuICAgICAgcGx1Z2luczogW3RhaWx3aW5kY3NzKCldLFxyXG4gICAgfSxcclxuICB9LFxyXG59KTtcclxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUFpWCxTQUFTLG9CQUFvQjtBQUM5WSxPQUFPLFdBQVc7QUFDbEIsT0FBTyxpQkFBaUI7QUFHeEIsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsU0FBUztBQUFBLElBQ1A7QUFBQSxNQUNFO0FBQUEsUUFDRSxPQUFPO0FBQUEsVUFDTCxTQUFTO0FBQUEsWUFDUCxDQUFDLHdDQUF3QztBQUFBLFVBQzNDO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUFBLEVBQ0EsTUFBTTtBQUFBLEVBQ04sS0FBSztBQUFBLElBQ0gsU0FBUztBQUFBLE1BQ1AsU0FBUyxDQUFDLFlBQVksQ0FBQztBQUFBLElBQ3pCO0FBQUEsRUFDRjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==