diff --git a/index.html b/index.html index 93ef8b9..b13c0a3 100644 --- a/index.html +++ b/index.html @@ -3,6 +3,17 @@ + + NUS Students' Computing Club diff --git a/package-lock.json b/package-lock.json index e01e23a..8423b09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,8 @@ "react-calendar": "^4.8.0", "react-dom": "^18.2.0", "react-icons": "^5.0.1", - "react-router-dom": "^6.21.1" + "react-router-dom": "^6.21.1", + "react-slick": "^0.30.2" }, "devDependencies": { "@html-eslint/eslint-plugin": "^0.22.0", @@ -2114,6 +2115,11 @@ "node": ">= 6" } }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "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", @@ -2293,6 +2299,11 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/enquire.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", + "integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw==" + }, "node_modules/es-abstract": { "version": "1.22.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", @@ -3687,6 +3698,14 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "dependencies": { + "string-convert": "^0.2.0" + } + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -3765,6 +3784,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -4487,6 +4511,22 @@ "react-dom": ">=16.8" } }, + "node_modules/react-slick": { + "version": "0.30.2", + "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.30.2.tgz", + "integrity": "sha512-XvQJi7mRHuiU3b9irsqS9SGIgftIfdV5/tNcURTb5LdIokRA5kIIx3l4rlq2XYHfxcSntXapoRg/GxaVOM1yfg==", + "dependencies": { + "classnames": "^2.2.5", + "enquire.js": "^2.1.6", + "json2mq": "^0.2.0", + "lodash.debounce": "^4.0.8", + "resize-observer-polyfill": "^1.5.0" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -4545,6 +4585,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -4790,6 +4835,11 @@ "node": ">=0.10.0" } }, + "node_modules/string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", diff --git a/package.json b/package.json index baf40e8..f549b1c 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "react-calendar": "^4.8.0", "react-dom": "^18.2.0", "react-icons": "^5.0.1", - "react-router-dom": "^6.21.1" + "react-router-dom": "^6.21.1", + "react-slick": "^0.30.2" }, "devDependencies": { "@html-eslint/eslint-plugin": "^0.22.0", diff --git a/public/announcements/bash.jpg b/public/announcements/bash.jpg new file mode 100644 index 0000000..cb10dd3 Binary files /dev/null and b/public/announcements/bash.jpg differ diff --git a/public/announcements/ffc.jpg b/public/announcements/ffc.jpg new file mode 100644 index 0000000..bdd4424 Binary files /dev/null and b/public/announcements/ffc.jpg differ diff --git a/public/announcements/fow.jpg b/public/announcements/fow.jpg new file mode 100644 index 0000000..7a69bad Binary files /dev/null and b/public/announcements/fow.jpg differ diff --git a/public/announcements/fsc.jpg b/public/announcements/fsc.jpg new file mode 100644 index 0000000..488d3c0 Binary files /dev/null and b/public/announcements/fsc.jpg differ diff --git a/src/pages/home/AnnouncementsCard.css b/src/pages/home/AnnouncementsCard.css new file mode 100644 index 0000000..398401b --- /dev/null +++ b/src/pages/home/AnnouncementsCard.css @@ -0,0 +1,74 @@ +.container { + @apply + flex + flex-row + max-w-full + h-[30vh] + lg:h-[30vh] + items-center + justify-center + md:justify-around + px-2 + md:gap-2 + + ; + } + +.container>img { + @apply + object-cover + p-4 + w-32 + md:w-48 + max-h-[30vh] + rounded-3xl + ; +} + +.text-container { + @apply + flex + flex-col + lg:p-4 + max-h-full + ; +} + +.text-container>h2 { + @apply + font-bold + text-sm + md:text-xl + ; +} + +.text-container>h3 { + @apply + font-subheading + text-xs + md:text-sm + pb-4 + ; +} + +.text-container>p { + @apply + line-clamp-2 + font-body + text-xs + md:text-sm + ; +} + +.text-container>h4 { + @apply + text-right + text-primary + font-subheading + p-2 + text-xs + md:text-base + ; +} + + \ No newline at end of file diff --git a/src/pages/home/AnnouncementsCard.tsx b/src/pages/home/AnnouncementsCard.tsx new file mode 100644 index 0000000..a1c85a5 --- /dev/null +++ b/src/pages/home/AnnouncementsCard.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import WindowCard from '../../layout/WindowCard'; +import './AnnouncementsCard.css'; +import { Link } from 'react-router-dom'; + +interface AnnouncementsCardProps { + title: string; + desc: string; + date: string; + imgSrc: string; + link: string; +} + +export default function AnnouncementsCard(props: AnnouncementsCardProps) { + const content = ( +
+ +
+

{props.title}

+

{props.date}

+

{props.desc}

+

+ Read More +

+
+
+ ); + + return ( + + ); +} diff --git a/src/pages/home/Carousel.css b/src/pages/home/Carousel.css new file mode 100644 index 0000000..9347122 --- /dev/null +++ b/src/pages/home/Carousel.css @@ -0,0 +1,39 @@ +.item { + @apply + p-8 + md:p-14 + ; +} + +.slick-arrow.slick-next, +.slick-arrow.slick-prev{ + @apply + flex + justify-center + items-center + h-24 + w-24 + z-10 + max-w-full + ; +} + +.slick-prev::before,.slick-next::before{ + display:none; +} + +.arrows { + @apply + h-80 + w-80 + text-primary + opacity-60 + z-10 + ; +} + +.arrows:hover { + @apply + opacity-100 + ; +} diff --git a/src/pages/home/Carousel.tsx b/src/pages/home/Carousel.tsx new file mode 100644 index 0000000..7ec1c50 --- /dev/null +++ b/src/pages/home/Carousel.tsx @@ -0,0 +1,80 @@ +import React from "react"; +import Slider from "react-slick"; +import AnnouncementsCard from './AnnouncementsCard'; +import './Carousel.css'; +import { GoChevronLeft, GoChevronRight } from "react-icons/go"; +import announcements from './announcements.json' with {type: 'json'}; + + +function NextArrow(props) { + const { className, style, onClick } = props; + return ( +
+ +
+ ); + } + + function PrevArrow(props) { + const { className, style, onClick } = props; + return ( +
+
+ ); + } + + +export default function Carousel() { + var settings = { + dots: true, + infinite: true, + speed: 500, + slidesToShow: 2, + slidesToScroll: 1, + nextArrow: , + prevArrow: , + responsive: [ + { + breakpoint: 1200, + settings: { + slidesToShow: 1, + slidesToScroll: 1, + initialSlide: 1 + } + }, + { + breakpoint: 800, + settings: { + slidesToShow: 1, + slidesToScroll: 1, + initialSlide: 1, + nextArrow: false, + prevArrow: false + } + } + ] + }; + + + return ( +
+ + {announcements.map((announcement, index) => ( +
+ +
+ ))} +
+
+ ); +} diff --git a/src/pages/home/announcements.json b/src/pages/home/announcements.json new file mode 100644 index 0000000..27c0abd --- /dev/null +++ b/src/pages/home/announcements.json @@ -0,0 +1,26 @@ +[ + { + "title": "Freshman Social Camp (FSC)", + "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": "19th June - 22nd June 2024", + "imgSrc": "announcements/fsc.jpg" + }, + { + "title": "Freshman Orientation Week (FOW)", + "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": "24th July - 22nd July 2024", + "imgSrc": "announcements/fow.jpg" + }, + { + "title": "Freshman Finale Camp (FFC)", + "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": "5th August - 7th August 2024", + "imgSrc": "announcements/ffc.jpg" + }, + { + "title": "Computing Bash", + "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": "16th August 2024", + "imgSrc": "announcements/bash.jpg" + } +] \ No newline at end of file diff --git a/src/pages/home/index.css b/src/pages/home/index.css index 8224c5d..206ae33 100644 --- a/src/pages/home/index.css +++ b/src/pages/home/index.css @@ -14,6 +14,57 @@ section { ; } +.latest-announcements { + @apply + flex + flex-col + h-[80vh] +} + +.section-header { + @apply + flex + flex-col + w-full + items-center + justify-center + h-[20vh] + px-4 + ; +} + +.section-header>h3 { + @apply + text-xl + font-heading + text-white + ; +} + +.section-header>h1 { + @apply + text-4xl + md:text-5xl + lg:text-6xl + text-white + font-heading + pb-4 + text-center + ; +} + +.carousel-container { + @apply + h-[60vh] + pt-6 + px-0 + md:px-6 + lg:px-20 + overflow-hidden + ; +} + + .section-description { @apply w-96 diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 3e9fec5..715c956 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Link } from 'react-router-dom'; import './index.css'; +import Carousel from './Carousel'; function Home() { return ( @@ -19,6 +20,16 @@ function Home() { + {/* latest announcements */} +
+
+

Latest Announcements

+
+
+ +
+
+ {/* events */}