Skip to content
This repository was archived by the owner on Mar 5, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions components/BulletPoint.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import styles from '../styles/components/BulletPoint.module.scss';
import { type SectionStyle, getSectionStyling, Fonts } from '../utils';
import { type BulletPoint } from '../config';
import Icon from './Icon';

interface Props {
bullet: BulletPoint;
style: SectionStyle;
}

const Button = ({ bullet, style }: Props): JSX.Element => {
const sectionStyle = getSectionStyling(style);
return (
<div className={[styles.container, Fonts.Open_Sans].join(' ')}>
<div
className={[styles.iconContainer, sectionStyle.foregroundColor].join(
' '
)}
>
<Icon iconType={bullet.icon} />
</div>
<h4>{bullet.title}</h4>
<span>{bullet.text}</span>
</div>
);
};

export default Button;
62 changes: 62 additions & 0 deletions components/Icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* @module Icon: A dynamic icon component.
*/
import React from 'react';
// Icon Imports - Icons at https://react-icons.github.io/react-icons/search
import { MdOutlinePeopleOutline } from 'react-icons/md';
import {
FaAward,
FaRegLightbulb,
FaHourglassStart,
FaFacebook,
FaInstagram,
FaTwitter,
FaLinkedin,
} from 'react-icons/fa';
import { LuChevronsLeftRight } from 'react-icons/lu';
import { FiTarget } from 'react-icons/fi';

// Icon Types
export enum IconType {
// General
People = 'People',
Award = 'Award',
LightBulb = 'LightBulb',
Development = 'Development',
Target = 'Target',
HourGlass = 'HourGlass',
// Social
Facebook = 'Facebook',
Instagram = 'Instagram',
Twitter = 'Twitter',
Linkedin = 'linkedin',
}

export const Icon = ({ iconType }: { iconType: IconType }): JSX.Element => {
switch (iconType) {
// General
case IconType.People:
return <MdOutlinePeopleOutline />;
case IconType.Award:
return <FaAward />;
case IconType.LightBulb:
return <FaRegLightbulb />;
case IconType.Development:
return <LuChevronsLeftRight />;
case IconType.Target:
return <FiTarget />;
case IconType.HourGlass:
return <FaHourglassStart />;
// Social
case IconType.Facebook:
return <FaFacebook />;
case IconType.Instagram:
return <FaInstagram />;
case IconType.Twitter:
return <FaTwitter />;
case IconType.Linkedin:
return <FaLinkedin />;
}
};

export default Icon;
51 changes: 43 additions & 8 deletions config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import z, { type ZodError } from 'zod';
import { fromZodError } from 'zod-validation-error';
import { IconType } from './components/Icon';
// Import Config
import rawConfig from './config.yaml';
// General Types
Expand All @@ -29,14 +30,22 @@ export enum SectionType {
TextSection = 'TextSection',
NewsSection = 'NewsSection',
EventSection = 'EventSection',
AboutSection = 'AboutSection',
}
export enum HeaderStyle {
Default = 'Default',
Inline = 'Inline',
}
const headerStyle = z.nativeEnum(HeaderStyle);
interface SectionBase {
// section_type: SectionType; -- We cannot have this here because of the whole filtering by sections stuff, but it is necessary on each type
section_header: string;
header_style: HeaderStyle;
}
const sectionBase = z.strictObject({
section_type: z.nativeEnum(SectionType),
section_header: z.string(),
header_style: headerStyle.optional().default(HeaderStyle.Default),
});
// Config Types
interface SocialIcon {
Expand Down Expand Up @@ -210,31 +219,56 @@ const eventSection = sectionBase.extend({
}
),
});
export type Section = TextSection | NewsSection | EventSection;
const section = z.union([textSection, newsSection, eventSection]);
// Home page
interface HomePage {

const iconType = z.nativeEnum(IconType);
export interface BulletPoint {
icon: IconType;
title: string;
text: string;
}
const bulletPoint = z.strictObject({
icon: iconType,
title: z.string(),
text: z.string(),
});
export interface AboutSection extends SectionBase {
section_type: SectionType.AboutSection;
text: string;
image: ImageDescription;
bullet_points: BulletPoint[];
}
const aboutSection = sectionBase.extend({
section_type: z.literal(SectionType.AboutSection),
text: z.string(),
image: imageDescription,
bullet_points: z.array(bulletPoint).max(3).optional().default([]),
});
export type Section = TextSection | NewsSection | EventSection | AboutSection;
const section = z.union([textSection, newsSection, eventSection, aboutSection]);
// Pages
interface ComposablePage {
sections: Section[];
}
const homePage = z.strictObject({
const composablePage = z.strictObject({
sections: z.array(section),
});

// config
interface ValidConfig {
website_config: WebsiteConfig;
page_list: PageItem[];
footer_config: FooterConfig;
// Page Configs
home_page: HomePage;
home_page: ComposablePage;
events: EventItem[];
about_page: ComposablePage;
}
const configValidator = z.strictObject({
website_config: websiteConfig,
page_list: z.array(pageItem),
footer_config: footerConfig,
home_page: homePage,
home_page: composablePage,
events: z.array(eventItem),
about_page: composablePage,
});
// Config Section Spaced out for an easier error
// =========================================================================
Expand Down Expand Up @@ -274,3 +308,4 @@ export const footer_config = config.footer_config;
export const page_list = config.page_list;
export const home_page = config.home_page;
export const events = config.events;
export const about_page = config.about_page;
55 changes: 53 additions & 2 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ page_list:
page_link: /
display_in_navbar: true
- page_name: About Us
page_link: /About
page_link: /about
display_in_navbar: true
- page_name: Events
page_link: /Events
Expand Down Expand Up @@ -90,4 +90,55 @@ home_page:
- text: NEWS ABOUT EXCITING EVENT
date: 2024-07-25
# href: /
href: /
# Configuration for About page
about_page:
sections:
- section_type: AboutSection
section_header: Who Are We?
header_style: Inline
text: The Trent Computer Science Club Association is a student-run organization dedicated to enriching the computer science experience at Trent University. From coding workshops to hackathons, the TCSCA offers a variety of opportunities for students to expand their knowledge and network effectively to break into the tech industry.
image:
src: /about1.png
alt: Currently a placeholder
bullet_points:
- icon: People
title: Our Dedicated Members
text: Meet the individuals who lead our club and drive our initiatives.
- icon: HourGlass
title: More Text
text: Example text to say stuff about something about us
- icon: Award
title: Even More text
text: Example text to say stuff about something about us
- section_type: AboutSection
section_header: Our Mission
text: Our mission is to create a vibrant community of computer science enthusiasts, where students can explore their interests, develop their skills, and collaborate on innovative projects. We strive to inspire the next generation of technology leaders and empower them to make a positive impact on the world.
image:
src: /about2.png
alt: Currently a placeholder
bullet_points:
- icon: LightBulb
title: Inspiring Innovation
text: We aim to inspire our members to explore the boundless possibilities of computer science and technology.
- icon: Development
title: Empowering Developers
text: We empower our members to develop their skills, collaborate on projects, and make a meaningful impact.
- icon: Target
title: Fostering Innovation
text: We encourage our members to think outside the box and develop innovative solutions to real-world problems.
- section_type: AboutSection
section_header: Why Join Us?
text: Our mission is to create a vibrant community of computer science enthusiasts, where students can explore their interests, develop their skills, and collaborate on innovative projects. We strive to inspire the next generation of technology leaders and empower them to make a positive impact on the world.
image:
src: /about3.png
alt: Currently a placeholder
bullet_points:
- icon: People
title: Networking Opportunities
text: Connect with a diverse community of computer science enthusiasts and build lasting professional relationships.
- icon: HourGlass
title: Skill Development
text: Participate in workshops, hackathons, and project-based learning to enhance your technical and soft skills.
- icon: Award
title: Community Involvement
text: Contribute to the local community through volunteering, outreach programs, and collaborative projects.
43 changes: 43 additions & 0 deletions layouts/AboutSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import Image from '../components/Image';
import styles from '../styles/layouts/AboutSection.module.scss';
import BulletPoint from '../components/BulletPoint';
import { type SectionStyle, getSectionStyling, Fonts } from '../utils';
import { type AboutSection } from '../config';

interface Props {
section: AboutSection;
style: SectionStyle;
className?: string;
}

const AboutSection = ({
section: { text, image, bullet_points },
style,
className,
}: Props) => {
const sectionStyle = getSectionStyling(style);
return (
<div
className={`${styles.container} ${className ?? ''} ${Fonts.Open_Sans} ${sectionStyle.backgroundColor}`}
>
<div>
<div>
<p>{text}</p>
</div>
{bullet_points.length != 0 && (
<div className={styles.bulletList}>
{bullet_points.map((bullet, i) => (
<BulletPoint bullet={bullet} style={style} key={i} />
))}
</div>
)}
<div className={styles.imageContainer}>
<Image src={image.src} alt={image.alt} fill={true} />
</div>
</div>
</div>
);
};

export default AboutSection;
13 changes: 11 additions & 2 deletions layouts/EventSection.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from 'react';
import styles from '../styles/layouts/EventSection.module.scss';
import { type SectionStyle, getSectionStyling } from '../utils';
import { EventGridStyle, type EventSection, type EventItem } from '../config';
import { FaChevronLeft, FaChevronRight } from 'react-icons/fa';
import Event from '../components/Event';
Expand Down Expand Up @@ -38,10 +39,12 @@ const getSectionLayout = (

interface Props {
className?: string;
style: SectionStyle;
section: EventSection;
}

export default function EventSection({ className, section }: Props) {
export default function EventSection({ section, className, style }: Props) {
const sectionStyle = getSectionStyling(style);
const [currentView, setCurrentView] = useState(0);
// Map the events
const events = section.events.map((event, i): [EventItem, JSX.Element] => [
Expand All @@ -59,7 +62,13 @@ export default function EventSection({ className, section }: Props) {
);
// Build ui
return (
<div className={[styles.container, className].join(' ')}>
<div
className={[
styles.container,
className,
sectionStyle.backgroundColor,
].join(' ')}
>
{/* Event Container */}
<div>{event_view}</div>
{/* Possible Buttons */}
Expand Down
16 changes: 13 additions & 3 deletions layouts/NewsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import React from 'react';
import Link from 'next/link';
import Button from '../components/Button';
import { SlCalender, SlLocationPin } from 'react-icons/sl';
import { Fonts, DateFormat, formatDate } from '../utils';
import {
type SectionStyle,
getSectionStyling,
Fonts,
DateFormat,
formatDate,
} from '../utils';
import { type NewsSection, type NewsItem } from '../config';

const NewsItemComponent = ({ newsItem }: { newsItem: NewsItem }) => {
Expand Down Expand Up @@ -43,12 +49,16 @@ const NewsItemComponent = ({ newsItem }: { newsItem: NewsItem }) => {

interface NewsSectionProps {
section: NewsSection;
style: SectionStyle;
className?: string;
}
const NewsSection = ({ section, className }: NewsSectionProps) => {
const NewsSection = ({ section, style, className }: NewsSectionProps) => {
const { news_feed } = section;
const sectionStyle = getSectionStyling(style);
return (
<div className={`${styles.container} ${className ?? ''}`}>
<div
className={`${styles.container} ${className ?? ''} ${sectionStyle.backgroundColor}`}
>
{news_feed.map((item, i) => (
<NewsItemComponent key={i} newsItem={item} />
))}
Expand Down
Loading