Skip to content

Commit

Permalink
feat: overhaul meeting rows
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiteHoodHacker committed Jan 7, 2025
1 parent ee22079 commit 4fe56ad
Show file tree
Hide file tree
Showing 18 changed files with 561 additions and 212 deletions.
30 changes: 30 additions & 0 deletions _global/components/Icons/fluentui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ export const ClockRegular = (props: TSVGElementProps) => (
</SvgWrapper>
);

export const DocumentPdfFilled = (props: TSVGElementProps) => (
<SvgWrapper {...props}>
<path d="M4.49976 9.00299C4.22361 9.00299 3.99976 9.22685 3.99976 9.50299V11.503C3.99976 11.7791 4.22361 12.003 4.49976 12.003C4.7759 12.003 4.99976 11.7791 4.99976 11.503V11.3366H5.33296C5.97736 11.3366 6.49976 10.8142 6.49976 10.1698C6.49976 9.52538 5.97736 9.00299 5.33296 9.00299H4.49976ZM5.33296 10.3366H4.99976V10.003H5.33296C5.42508 10.003 5.49976 10.0777 5.49976 10.1698C5.49976 10.2619 5.42508 10.3366 5.33296 10.3366ZM10.0005 9.50236C10.0008 9.22646 10.2246 9.00299 10.5005 9.00299H11.4988C11.7749 9.00299 11.9988 9.22685 11.9988 9.50299C11.9988 9.77913 11.7749 10.003 11.4988 10.003H10.9998L10.9994 10.3375H11.4988C11.7749 10.3375 11.9988 10.5613 11.9988 10.8375C11.9988 11.1136 11.7749 11.3375 11.4988 11.3375H11L11.0005 11.5017C11.0012 11.7779 10.7779 12.0023 10.5017 12.003C10.2256 12.0037 10.0012 11.7804 10.0005 11.5043L9.99878 10.8368L10.0005 9.50236ZM7.49829 9.00299C7.22215 9.00299 6.99829 9.22685 6.99829 9.50299V11.503C6.99829 11.7791 7.22215 12.003 7.49829 12.003H7.99974C8.82816 12.003 9.49973 11.3314 9.49974 10.503C9.49974 9.67457 8.82817 9.00299 7.99974 9.00299H7.49829ZM7.99829 11.003V10.003H7.99974C8.27588 10.003 8.49974 10.2269 8.49974 10.503C8.49974 10.7791 8.27588 11.003 7.99974 11.003H7.99829ZM9 2.00195H4.5C3.67157 2.00195 3 2.67353 3 3.50195V7.08413C2.4174 7.29005 2 7.84567 2 8.49878V12.502C2 13.3304 2.67157 14.002 3.5 14.002H12.5C13.3284 14.002 14 13.3304 14 12.502V8.49878C14 7.84567 13.5826 7.29005 13 7.08413V5.99994H10.5C9.67157 5.99994 9 5.32837 9 4.49994V2.00195ZM3.5 7.99878H12.5C12.7761 7.99878 13 8.22264 13 8.49878V12.502C13 12.7781 12.7761 13.002 12.5 13.002H3.5C3.22386 13.002 3 12.7781 3 12.502V8.49878C3 8.22264 3.22386 7.99878 3.5 7.99878ZM12.7056 4.99994H10.5C10.2239 4.99994 10 4.77608 10 4.49994V2.29746L12.7056 4.99994Z"/>
</SvgWrapper>
);

export const FlagRegular = (props: TSVGElementProps) => (
<SvgWrapper {...props}>
<path d="M4 9V3H12.0284L10.0931 5.70938C9.96896 5.88323 9.96896 6.11677 10.0931 6.29062L12.0284 9H4ZM4 10H13C13.4067 10 13.6432 9.54032 13.4069 9.20938L11.1145 6L13.4069 2.79062C13.6432 2.45968 13.4067 2 13 2H3.5C3.22386 2 3 2.22386 3 2.5V13.5C3 13.7761 3.22386 14 3.5 14C3.77614 14 4 13.7761 4 13.5V10Z"/>
Expand Down Expand Up @@ -181,6 +187,18 @@ export const OpenRegular = (props: TSVGElementProps) => (
</SvgWrapper>
);

export const PlayCircleFilled = (props: TSVGElementProps) => (
<SvgWrapper {...props}>
<path d="M2 8C2 4.68629 4.68629 2 8 2C11.3137 2 14 4.68629 14 8C14 11.3137 11.3137 14 8 14C4.68629 14 2 11.3137 2 8ZM10.5 8C10.5 7.81993 10.4032 7.65377 10.2465 7.56499L7.61975 6.07654C7.11977 5.79323 6.5 6.1544 6.5 6.72907V9.27099C6.5 9.84566 7.11978 10.2068 7.61976 9.92351L10.2465 8.43502C10.4032 8.34624 10.5 8.18008 10.5 8Z"/>
</SvgWrapper>
);

export const PlayFilled = (props: TSVGElementProps) => (
<SvgWrapper {...props}>
<path d="M6.23541 2.1919C5.2355 1.62944 4 2.352 4 3.49925V12.4995C4 13.6468 5.23546 14.3693 6.23537 13.8069L14.2356 9.30692C15.2551 8.73348 15.2551 7.26566 14.2357 6.69219L6.23541 2.1919Z"/>
</SvgWrapper>
);

export const ShieldFilled = (props: TSVGElementProps) => (
<SvgWrapper {...props}>
<path d="M7.64728 2.14638C7.84268 1.95105 8.15946 1.95123 8.35464 2.14678C9.5947 3.38913 10.9689 4 12.5 4C12.7761 4 13 4.22386 13 4.5V7.50126C13 10.7196 11.3587 12.9075 8.15811 13.9743C8.05548 14.0086 7.94452 14.0086 7.84189 13.9743C4.64126 12.9075 3 10.7196 3 7.50126V4.5C3 4.22386 3.22386 4 3.5 4C5.02923 4 6.40416 3.38902 7.64728 2.14638Z" />
Expand All @@ -203,4 +221,16 @@ export const ShieldKeyholeRegular = (props: TSVGElementProps) => (
<SvgWrapper {...props}>
<path d="M9.25 7.25C9.25 7.76258 8.94148 8.2031 8.5 8.39599V9.50358C8.5 9.77973 8.27614 10.0036 8 10.0036C7.72386 10.0036 7.5 9.77973 7.5 9.50358V8.39599C7.05852 8.2031 6.75 7.76258 6.75 7.25C6.75 6.55964 7.30964 6 8 6C8.69036 6 9.25 6.55964 9.25 7.25ZM7.14309 2.04175C6.78097 2.2883 6.21583 2.61563 5.42482 2.91681C4.6399 3.21566 3.90375 3.36204 3.36353 3.43333C3.09405 3.46889 2.87509 3.48554 2.72547 3.49331C2.6507 3.49719 2.5934 3.49885 2.55593 3.49954L2.50489 3.50003C2.37157 3.49872 2.24323 3.55072 2.14842 3.64449C2.05344 3.73841 2 3.86643 2 4V6.75508C2 9.40779 3.4013 11.8632 5.68525 13.2124L7.74707 14.4305C7.90399 14.5232 8.09891 14.5232 8.2558 14.4304L10.3162 13.2126C12.5993 11.8632 14 9.40823 14 6.7561V4C14 3.86598 13.9462 3.73757 13.8507 3.64358C13.7552 3.54964 13.626 3.49794 13.4921 3.50007L13.4421 3.49981C13.4048 3.49928 13.3478 3.49787 13.2735 3.49426C13.1246 3.48705 12.9066 3.47109 12.6384 3.43602C12.1006 3.36573 11.3679 3.21959 10.5869 2.91771C9.79733 2.61248 9.22913 2.28442 8.86335 2.03774C8.68039 1.91435 8.54795 1.81124 8.46371 1.74141C8.4256 1.70981 8.38768 1.6777 8.35191 1.64343C8.2576 1.55073 8.13037 1.49913 7.99807 1.50001C7.86585 1.50089 7.73916 1.55434 7.64611 1.64819L7.53744 1.74536C7.45475 1.81517 7.32423 1.91842 7.14309 2.04175ZM3 6.75508V4.47725C3.14066 4.46608 3.30705 4.44945 3.49436 4.42473C4.09055 4.34605 4.90577 4.18447 5.78065 3.85136C6.64943 3.52057 7.28362 3.15585 7.70588 2.86835C7.82102 2.78996 7.92034 2.71735 8.00434 2.65277C8.08878 2.71677 8.18861 2.78886 8.30421 2.86682C8.72757 3.15233 9.362 3.51631 10.2264 3.85045C11.0994 4.18794 11.9134 4.34976 12.5088 4.42759C12.6947 4.45189 12.86 4.46809 13 4.47888V6.7561C13 9.05461 11.7861 11.1822 9.80736 12.3518L8.00133 13.4192L6.19388 12.3515C4.21446 11.1821 3 9.0541 3 6.75508Z"/>
</SvgWrapper>
);

export const VideoClipFilled = (props: TSVGElementProps) => (
<SvgWrapper {...props}>
<path d="M2 5.5C2 4.11929 3.11929 3 4.5 3H11.5C12.8807 3 14 4.11929 14 5.5V10.5C14 11.8807 12.8807 13 11.5 13H4.5C3.11929 13 2 11.8807 2 10.5V5.5ZM6.5 5.82056V10.1794C6.5 10.4293 6.77363 10.5828 6.98686 10.4525L10.246 8.46076C10.5906 8.2502 10.5906 7.74977 10.246 7.53921L6.98686 5.54751C6.77363 5.4172 6.5 5.57067 6.5 5.82056Z"/>
</SvgWrapper>
);

export const VideoFilled = (props: TSVGElementProps) => (
<SvgWrapper {...props}>
<path d="M1 5.5C1 4.11929 2.11929 3 3.5 3H7.5C8.88071 3 10 4.11929 10 5.5V10.5C10 11.8807 8.88071 13 7.5 13H3.5C2.11929 13 1 11.8807 1 10.5V5.5ZM13.0355 11.7782L10.8999 10.3036C10.9129 10.2115 10.9197 10.1173 10.9197 10.0215V5.98047C10.9197 5.88463 10.9129 5.79037 10.8999 5.69813L13.0355 4.22353C13.8647 3.65101 14.9958 4.24453 14.9958 5.25216V10.7496C14.9958 11.7572 13.8647 12.3507 13.0355 11.7782Z"/>
</SvgWrapper>
);
2 changes: 1 addition & 1 deletion _global/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ const sigpwnyConfig : ISiteConfig = {
{ name: `Publications`, url: `/publications/`},
// { name: `Events`, url: `/events/` },
{ name: `Sponsors`, url: `/sponsors/` },
{ name: `Join`, url: `/join/` },
],
navCallToActionLinks: [
{ name: `Join`, url: `/join/` }
],
socialLinks: [
{ name: `Discord`, url: `https://discord.gg/cWcZ6a9` },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Active Directory 1
title: Active Directory I
type: purple
time_start: 2024-10-16T00:00:00.000Z
duration: ""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Active Directory 3
title: Active Directory III
type: purple
time_start: 2024-11-05T19:00:00-06:00
duration: ""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: eCTF Kickoff
title: eCTF 2025 Kickoff
type: embedded
time_start: 2025-01-15T11:00:00-06:00
duration: PT2H
Expand Down
20 changes: 10 additions & 10 deletions _global/utils/meetingMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export const meetingMetatypes = [
'general',
'seminar',
'ctf',
'purple',
'embedded',
'purple',
];

export type MeetingMetatype = typeof meetingMetatypes[number];
Expand All @@ -18,26 +18,26 @@ export const meetingMetadata: Record<MeetingMetatype, MeetingMetadata> = {
'general': {
name: 'General Meetings',
shortName: 'General',
description: 'Attend our weekly general meetings to learn fundamental skills in cybersecurity.',
description: 'Attend our weekly general meetings to learn the fundamental of cybersecurity.',
},
'seminar': {
name: 'Seminar Meetings',
shortName: 'Seminar',
description: 'Attend our seminars to discuss advanced and novel research topics in cybersecurity.',
description: 'Discuss interesting, novel, and advanced research topics in security.',
},
'ctf': {
name: 'CTF Team',
shortName: 'CTF',
description: 'Compete in "Capture the Flag" events to hone your cybersecurity skills.',
},
'purple': {
name: 'Purple Team',
shortName: 'Purple',
description: 'Learn red-teaming (offensive) and blue-teaming (defensive) skills to secure systems and networks.',
description: 'Compete in Capture-the-Flag events to practice your cybersecurity skills.',
},
'embedded': {
name: 'Embedded Team',
shortName: 'Embedded',
description: 'Build secure embedded systems and learn about hardware hacking!',
description: 'Build secure embedded systems and learn about hardware hacking.',
},
'purple': {
name: 'Purple Team',
shortName: 'Purple',
description: 'Learn red-teaming and blue-teaming skills to secure systems and networks.',
},
};
41 changes: 0 additions & 41 deletions sigpwny.com/src/components/Meeting/Controls.tsx

This file was deleted.

201 changes: 201 additions & 0 deletions sigpwny.com/src/components/Meeting/Countdown.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
export interface CountdownBadgeProps {
time_start: Date;
time_close: Date;
}
const props = Astro.props as CountdownBadgeProps;
---
<script>
// function initCountdownBadges() {
// const countdownBadges = document.querySelectorAll('.astro-countdown-badge');
// for (let i = 0; i < countdownBadges.length; i++) {
// const countdownBadge = countdownBadges[i];
// const timeStartStr = countdownBadge.getAttribute('data-time-start');
// const timeCloseStr = countdownBadge.getAttribute('data-time-close');
// if (!timeStartStr || !timeCloseStr) {
// continue;
// }
// const timeStart = parseInt(timeStartStr);
// const timeClose = parseInt(timeCloseStr);
// // updateCountdown(new Date(timeStart), new Date(timeClose));
// }
// }

// function getCountdownStatusType(start_date: Date, close_date: Date, now: Date) {
// if (now >= close_date) {
// return null;
// } else if (now >= start_date) {
// return {
// status: {
// type: 'Live',
// message: 'LIVE',
// },
// interval: 1000,
// };
// }

// const diff = start_date.getTime() - now.getTime();
// const days = Math.floor(diff / (1000 * 60 * 60 * 24));
// const hours = Math.floor(diff / (1000 * 60 * 60));
// const minutes = Math.floor(diff / (1000 * 60));

// const result = {
// status: {
// type: 'Complete',
// message: '',
// },
// interval: 1000,
// };

// if (days > 7) {
// result.status.type = 'Upcoming';
// result.status.message = 'SCHEDULED';
// result.interval = 1000 * 60 * 60; // Every hour
// } else if (days > 0) {
// result.status.type = 'Upcoming';
// result.status.message = `in ${days} day${days === 1 ? '' : 's'}`;
// result.interval = 1000 * 60 * 60; // Every hour
// } else if (hours > 0) {
// result.status.type = 'Upcoming';
// result.status.message = `in ${hours} hour${hours === 1 ? '' : 's'}`;
// result.interval = 1000 * 60; // Every minute
// } else if (minutes > 0) {
// result.status.type = 'Upcoming';
// result.status.message = `in ${minutes} min`;
// result.interval = 1000; // Every second
// } else {
// result.status.type = 'Upcoming';
// result.status.message = 'in <1 min';
// result.interval = 1000; // Every second
// }
// return result;
// }

// function updateCountdown(start_date: Date, close_date: Date) {
// const now = new Date();
// const result = getCountdownStatusType(start_date, close_date, now);
// const countdownElement = document.getElementById('countdown-badge');

// if (!result || !countdownElement) {
// countdownElement.style.display = 'none';
// return;
// }

// countdownElement.textContent = result.status.message;
// countdownElement.className = `inline-flex self-center px-1 text-sm font-mono select-none whitespace-nowrap rounded-md ${(() => {
// switch (result.status.type) {
// case 'Upcoming':
// return 'bg-gradient-to-r from-purple-500 to-blue-500';
// case 'Live':
// return 'bg-red-600';
// default:
// return 'hidden';
// }
// })()}`;

// setTimeout(() => updateCountdown(start_date, close_date), result.interval);
// }

class CountdownManager {
private timers: Map<Element, number>;

constructor() {
this.timers = new Map();
this.initialize();
}

initialize() {
const countdowns = document.querySelectorAll('.astro-countdown-badge') as NodeListOf<HTMLDivElement>;
countdowns.forEach(element => {
const timeStartStr = element.getAttribute('data-time-start');
const timeCloseStr = element.getAttribute('data-time-close');
if (!timeStartStr || !timeCloseStr) {
return;
}
const timeStart = parseInt(timeStartStr);
const timeClose = parseInt(timeCloseStr);
this.setupTimer(element, timeStart, timeClose);
});
}

setupTimer(element: HTMLDivElement, timeStart: number, timeClose: number) {
const updateDisplay = () => {
const now = Date.now();

let baseClasses = 'astro-countdown-badge inline-flex self-center px-2 text-sm lg:text-base font-mono select-none whitespace-nowrap rounded-md ';

// Handle closed state
if (now >= timeClose) {
baseClasses += 'hidden';
element.className = baseClasses;
element.style.display = 'none';
this.clearTimer(element);
return null;
}

// Handle live state
if (now >= timeStart) {
baseClasses += 'bg-red-600';
element.className = baseClasses;
element.textContent = 'LIVE';
return 60000; // Update every minute
}

const diff = timeStart - now;
const weeks = Math.floor(diff / (1000 * 60 * 60 * 24 * 7));
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);

// Handle countdown state
baseClasses += 'bg-gradient-to-r from-purple-500 to-blue-500';
element.className = baseClasses;
// Determine display format and next update interval
if (weeks > 0) {
element.textContent = `in ${weeks} wk${weeks > 1 ? 's' : ''}`;
return 86400000; // Update every day
} else if (days > 0) {
element.textContent = `in ${days} day${days > 1 ? 's' : ''}`;
return 3600000; // Update every hour
} else if (hours > 0) {
element.textContent = `in ${hours} hr${hours > 1 ? 's' : ''}`;
return 60000; // Update every minute
} else {
element.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
return 1000; // Update every second
}
};

const scheduleNextUpdate = () => {
const interval = updateDisplay();
if (interval === null) return;
const timerId = window.setTimeout(() => {
scheduleNextUpdate();
}, interval);
this.timers.set(element, timerId);
};

scheduleNextUpdate();
}

clearTimer(element: HTMLDivElement) {
const timerId = this.timers.get(element);
if (timerId) {
clearTimeout(timerId);
this.timers.delete(element);
}
}
}

document.addEventListener('astro:page-load', () => {
new CountdownManager();
});
</script>

<div
class="astro-countdown-badge"
data-time-start={props.time_start.getTime()}
data-time-close={props.time_close.getTime()}
/>
Loading

0 comments on commit 4fe56ad

Please sign in to comment.