Skip to content

Commit

Permalink
UADS-53 feat: Integrated CMS with the Socials Component
Browse files Browse the repository at this point in the history
  • Loading branch information
Harsheel12 committed Jun 27, 2024
1 parent d42a607 commit 874ae8f
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 36 deletions.
55 changes: 55 additions & 0 deletions backend/controllers/SocialController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Request, Response } from "express";
import { Client } from "@notionhq/client";
import { config } from "dotenv";
config();

const notionSecret = process.env.NOTION_SECRET;
const socialID = process.env.SOCIAL_DB_ID;

const notion = new Client({
auth: notionSecret,
});

type Row = {
Name: {
id: string;
title: {
text: {
content: string;
};
}[];
};
Link: {
id: string;
url: string;
};
};

type rowsStructured = {
name: string;
link: string;
}[];

const getSocials = async (req: Request, res: Response) => {
if (!notionSecret || !socialID) {
throw new Error("Missing creds");
}

const query = await notion.databases.query({
database_id: socialID,
});

// @ts-ignore
const rows = query.results.map((res) => res.properties) as Row[];

const rowsStructured: rowsStructured = rows.map((row) => ({
name: row.Name.title[0].text.content,
link: row.Link.url,
}));

const orderedRowsStructured = rowsStructured.reverse();

res.status(200).json(orderedRowsStructured);
};

export { getSocials };
4 changes: 4 additions & 0 deletions backend/routes/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import express from "express";
import eventRoutes from "./eventRoutes";
import sponsorRoutes from "./sponsorRoutes";
import execRoutes from "./execRoutes";
import socialRoutes from "./socialRoutes";

const router = express.Router();

Expand All @@ -14,4 +15,7 @@ router.use("/api/sponsors", sponsorRoutes);
// All exec routes
router.use("/api/execs", execRoutes);

// All exec routes
router.use("/api/socials", socialRoutes);

export default router;
8 changes: 8 additions & 0 deletions backend/routes/socialRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Router } from "express";
import { getSocials } from "../controllers/SocialController";

const socialRoutes = Router();

socialRoutes.get("/", getSocials);

export default socialRoutes;
86 changes: 54 additions & 32 deletions web/src/components/Socials.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,69 @@
import { Link } from "react-router-dom";
import { FaFacebookF, FaInstagram, FaDiscord, FaTiktok } from "react-icons/fa";
import { IoMdMail } from "react-icons/io";
import { useEffect, useState } from "react";
import axios from "axios";

interface SocialsProps {
background: string;
hoverBackground: string;
iconColor: string;
hoverIconColor: string;
background: string;
hoverBackground: string;
iconColor: string;
hoverIconColor: string;
}

interface SocialType {
name: string;
link: string;
}

export default function Socials({ background, hoverBackground, iconColor, hoverIconColor }: SocialsProps) {
return (
<>
<div className="w-80 flex justify-between items-center" data-testid="socialsComponent">
<div className={`w-10 h-10 ${background} rounded-full hover:${hoverBackground} cursor-pointer group`}>
<Link to="https://www.facebook.com/uoadessertsociety" target="_blank" aria-label="Facebook" className="w-full h-full flex justify-center items-center">
<FaFacebookF className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="facebookLogo" />
</Link>
</div>
const [socials, setSocials] = useState<SocialType[]>([]);

<div className={`w-10 h-10 ${background} rounded-full hover:${hoverBackground} cursor-pointer group`}>
<Link to="https://www.instagram.com/uoadessertsociety/" target="_blank" aria-label="Instagram" className="w-full h-full flex justify-center items-center">
<FaInstagram className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="instagramLogo" />
</Link>
</div>
useEffect(() => {
async function fetchSocials() {
try {
const response = await axios.get("http://localhost:4000/api/socials/");
setSocials(response.data);
} catch (error) {
console.error("Error fetching social data", error);
}
}

<div className={`w-10 h-10 ${background} rounded-full hover:${hoverBackground} cursor-pointer group`}>
<Link to="https://discord.gg/dFuwHuU8FT" target="_blank" aria-label="Discord" className="w-full h-full flex justify-center items-center">
<FaDiscord className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="discordLogo" />
</Link>
</div>
fetchSocials();
}, []);

<div className={`w-10 h-10 ${background} rounded-full hover:${hoverBackground} cursor-pointer group`}>
<Link to="https://www.tiktok.com/@uoadessertsociety?_t=8mQ3asFY7Pz&_r=1" target="_blank" aria-label="TikTok" className="w-full h-full flex justify-center items-center">
<FaTiktok className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="tiktokLogo" />
</Link>
</div>
const renderIcon = (name: string) => {
switch (name) {
case "Facebook":
return <FaFacebookF className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="facebookLogo" />;
case "Instagram":
return <FaInstagram className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="instagramLogo" />;
case "Discord":
return <FaDiscord className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="discordLogo" />;
case "TikTok":
return <FaTiktok className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="tiktokLogo" />;
case "Email":
return <IoMdMail className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="emailLogo" />;
default:
return null;
}
};

<div className={`w-10 h-10 ${background} rounded-full hover:${hoverBackground} cursor-pointer group`}>
<Link to="mailto:uoadessertsociety@gmail.com" target="_blank" aria-label="Email" className="w-full h-full flex justify-center items-center">
<IoMdMail className={`${iconColor} group-hover:${hoverIconColor}`} data-testid="emailLogo" />
</Link>
</div>
return (
<>
<div className="w-80 flex justify-between items-center" data-testid="socialsComponent">
{socials.slice(0, -1).map((social, index) => (
<div key={index} className={`w-10 h-10 ${background} rounded-full hover:${hoverBackground} cursor-pointer group`}>
<Link
to={social.name === "Email" ? `mailto:${social.link}` : social.link}
target="_blank"
aria-label={social.name}
className="w-full h-full flex justify-center items-center"
>
{renderIcon(social.name)}
</Link>
</div>
))}
</div>
</>
);
Expand Down
8 changes: 4 additions & 4 deletions web/src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ export default function Home() {
}}
className="mySwiper px-0 md:px-10 py-10"
>
{sponsors.map((sponsor) => {
{sponsors.map((sponsor, index) => {
return (
<SwiperSlide>
<SwiperSlide key={index}>
<SponsorCard sponsor={sponsor} />
</SwiperSlide>
);
Expand Down Expand Up @@ -150,9 +150,9 @@ export default function Home() {
}}
className="mySwiper px-0 md:px-10 py-10"
>
{events.map((event) => {
{events.map((event, index) => {
return (
<SwiperSlide>
<SwiperSlide key={index}>
<EventCard event={event} />
</SwiperSlide>
);
Expand Down

0 comments on commit 874ae8f

Please sign in to comment.