Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Daniel/announcements #500

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions src/components/General/AnnouncementPopup.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, {useState, useEffect} from 'react';
import { useNavigate } from 'react-router-dom';
import '../../styles/AnnouncementPopup.css';
import { TfiAnnouncement } from 'react-icons/tfi';



const AnnouncementPopup = () => {
const [show, setShow] = useState(true);
const [latestAnnouncement, setLatestAnnouncement] = useState(null);
const navigate = useNavigate();

const formatDate = (timestamp) => {
const date = new Date(timestamp);
return date.toLocaleDateString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
});
};

useEffect(() => {
fetch('src/data/announcements.json')
.then((response) => response.json())
.then((data) => {
if (data.length > 0) {
setLatestAnnouncement(data[0]);
}
})
.catch((error) => console.error('Error fetching announcements', error));
}, []);

const handleDelete = () => {
setShow(false);
};

if (!show || !latestAnnouncement) return null;

return (
<div className='popup'>
<button className = 'speaker-icon' onClick={() => navigate('./announcements')}>
<TfiAnnouncement/>
</button>
<div className='popup-content'>
<button className='close' onClick={handleDelete}>
&times;
</button>
<h1 className='popup-label'> {latestAnnouncement.subject} </h1>
<p className = 'popup-date'> {formatDate(latestAnnouncement.timestamp)} </p>
<p className='popup-body'> {latestAnnouncement.body} </p>
</div>
</div>

);

};

export default AnnouncementPopup
32 changes: 32 additions & 0 deletions src/data/announcements.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"id": 4,
"subject": "Congratulations!",
"body": "This workshop covers the basics of Web Development - HTML, CSS, and JavaScript! Together, they make up the structure (HTML), the style (CSS), and the functionality (JS) of a web application.",
"timestamp": "2025-02-04T01:06:22Z"
},
{
"id": 3,
"subject": "Yay!",
"body": "Hello! Welcome to HOTH XI's Intro to Web APIs workshop. This is a guide to introduce you to the foundations of Web APIs that will allow you to integrate them into any fullstack project. We will be covering the client-server model, HTTP requests & responses, and how we can leverage external servers to retrieve data and services for an app. Keep reading to learn more!",
"timestamp": "2025-02-02T01:05:09Z"
},
{
"id": 2,
"subject": "Intro to Servers!",
"body": "In this workshop, you will learn server-side programming in the context of full stack applications! Topics covered include HTTP, CRUD, and REST APIs. The second half of the workshop will include a hands-on demo building your own REST API using Flask and connecting it with a React frontend. By the end of the workshop you will become a server savant savvy with tools such as Postman. Viewers are recommended to have a strong foundation in JavaScript and Python.",
"timestamp": "2025-02-02T01:01:26Z"
},
{
"id": 1,
"subject": "Intro to React.js",
"body": "Hello! Welcome to the Intro to React JS workshop for HOTH XI! Here we will be introducing frontend web development using React. In this workshop we will utilize HTML, CSS, and JavaScript, so I would recommend watching the workshop on those if you are not already familiar with them!",
"timestamp": "2025-02-02T00:58:11Z"
},
{
"id": 0,
"subject": "Intro to React Native",
"body": "Hello and welcome to our Intro to React Native workshop! We'll be covering the basics of React Native in a way that I hope is simple to understand and impactful enough to teach some key features of app development. Happy hacking!",
"timestamp": "2025-02-02T00:57:26Z"
}
]
29 changes: 22 additions & 7 deletions src/pages/Announcements.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
import React from 'react';
import useTitle from '../components/General/useTitle';
import announcements from '../data/announcements.json';
import '../styles/Announcements.css';

export default function Announcements() {
useTitle(' | Announcements');

const formatDate = (timestamp) => {
const date = new Date(timestamp);
return date.toLocaleDateString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
});
};

return (
<div id='announcements'>
<h1 className='announcements-title'>Announcements</h1>
<div className='announcements-container'>
<p>
HOTH XII will take place later this quarter, and our team is working
hard to organize a fantastic hackathon for you all!
</p>
<p>More news and announcements coming soon. Stay tuned!</p>
<h1 className = 'announcements-title'>Announcements</h1>
<div className = 'announcements-container'>
{announcements.map((announcement) => (
<div key={announcement.id} className='announcements-label'>
<h2 className = 'announcements-subject'>{announcement.subject}</h2>
<p className = 'announcements-date'>
{formatDate(announcement.timestamp)}
</p>
<p className = 'announcements-body'>{announcement.body}</p>
</div>
))}
</div>
</div>
);
Expand Down
3 changes: 3 additions & 0 deletions src/pages/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Banner from '../components/Home/Banner';
import HothDescription from '../components/Home/HothDescription';
import PhotoCarousel from '../components/Home/PhotoCarousel';
import FAQSection from '../components/Home/FAQSection';
import AnnouncementPopup from '../components/General/AnnouncementPopup';

export default function Home() {
useTitle('');
Expand Down Expand Up @@ -35,6 +36,8 @@ export default function Home() {
<Container2>
<FAQSection />
</Container2>

<AnnouncementPopup />
</div>
);
}
7 changes: 3 additions & 4 deletions src/pages/Schedule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import useTitle from '../components/General/useTitle';
import eventSchedule from '../data/eventSchedule';
import '../styles/Schedule.css';
import { FaRegClock } from 'react-icons/fa';
import '../styles/Announcements.css';

const formatTime = date => {
const options = {
Expand Down Expand Up @@ -44,9 +43,9 @@ export default function Schedule() {
))}
</div>
) : (
<div id='announcements'>
<h1 className='announcements-title'>Schedule</h1>
<div className='announcements-container'>
<div id='schedule'>
<h1 className='schedule-title'>Schedule</h1>
<div className='events-container'>
<p>
HOTH XII will take place later this quarter, and our team is working
hard to organize a fantastic hackathon for you all!{' '}
Expand Down
72 changes: 72 additions & 0 deletions src/styles/AnnouncementPopup.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.popup {
position: fixed;
right: 1rem;
bottom: 1rem;
justify-content: flex-end;
align-items: center;
z-index: 100;

}

.popup-content {
background: #f7f7f7;
padding: 1.5rem;
border: 1px solid lightgray;
border-radius: 1rem;
margin-left: 2rem;
max-width: 16rem;
}

.dark .popup-content {
background: #362d40;
border: 1px solid #362d40;
}

.speaker-icon {
position: absolute;
background-color: yellow;
top: -3.4rem;
right: 0rem;
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 0px 10px rgba(0, 0, 0, 0.5);
font-size: 1.5rem;
transition: all 0.3s ease-in-out;
cursor: pointer;
border: none;
}

.speaker-icon:hover {
background-color: #FFFFC5;
}

.popup-label {
font-size: 1.5rem;
}

.popup-date {
font-size: 0.9rem;
}

.popup-body {
font-size: 0.95rem;
}

.close {
position: absolute;
top: 0.5rem;
left: 2.5rem;
border: none;
font-size: 1.2rem;
font-weight: bold;
background: transparent;
cursor: pointer;
}

.dark .close {
color: white;
}
44 changes: 39 additions & 5 deletions src/styles/Announcements.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,50 @@
#announcements {
width: 100%;
max-width: 60rem;
padding: 2rem 3rem;
max-width: 80rem;
padding: 2rem 10rem;
}

.announcements-title {
font-size: 3rem;
padding-bottom: 1.5rem;
font-size: 2.5rem;
text-align: center;
}

.announcements-container {
display: flex;
flex-direction: column;
display: grid;
gap: 1rem;
width: 100%;
margin: 0 auto;
}

.announcements-label {
background: var(--bgWhite);
padding: 1.5rem 2rem;
border: 1px solid lightgray;
box-shadow: 0 2px 6px var(--lightGray);
border-radius: 0.75rem;
transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
}

.announcements-label:hover {
transform: translateY(-3px);
box-shadow: 0 0px 6px var(--hackPrimary);
}

.announcements-subject {
margin-top: 1.1%;
padding-top: 0.1rem;
}

.announcements-date {
margin-top: 0.7rem;
text-align: left;
font-size: 0.9rem;
margin-bottom: 1rem;
}

.announcements-body {
margin-top: 1.5rem;
}

@media (max-width: 550px) {
Expand Down
8 changes: 7 additions & 1 deletion src/styles/Schedule.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#schedule {
width: 100%;
max-width: 80rem;
padding: 2rem 10rem;
}

.schedule-page {
padding: 2rem;
position: relative;
Expand All @@ -11,7 +17,7 @@

.schedule-title {
text-align: left;
font-size: 2rem;
font-size: 2.5rem;
padding-top: 30px;
}

Expand Down