Skip to content
Merged
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
4 changes: 4 additions & 0 deletions package-lock.json

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

160 changes: 160 additions & 0 deletions src/components/Schedule.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
// import type { CitySchedule } from "../lib/cityContent"

// interface Props {
// props: CitySchedule[]
// }

// const { props } = Astro.props;
import { cityContent } from "../lib/cityContent"
---

<section class="schedule">
<h2 class="section-heading">Schedule</h2>
<div id="wrapper">
{cityContent.vancouver.schedule.map((event) => {
return <div class="item">
{event.endTime ? (
<p class="time">{event.startTime} - {event.endTime}</p>
) : (
<p class="time">{event.startTime}</p>
)}
<div class="details">
{event.activities.map((activity, idx) => (
<p class:list={["activity", idx === 0 ? "activity-title" : "activity-meta"]}>
{activity.trim()}
</p>
))}
</div>
</div>
})}
</div>
</section>

<script>
import { getCityStore } from '../lib/cityStore';
import type { City } from '../lib/content';

function syncScheduleVisibility(city: City) {
const el = document.querySelector('.schedule') as HTMLElement | null;
if (!el) return;
const show = city === 'vancouver';
el.classList.toggle('schedule--hidden', !show);
el.setAttribute('aria-hidden', show ? 'false' : 'true');
}

function initCityAwareSchedule() {
const cityStore = getCityStore();
cityStore.init();
syncScheduleVisibility(cityStore.getCity());
cityStore.subscribe(syncScheduleVisibility);
}

if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initCityAwareSchedule);
} else {
initCityAwareSchedule();
}
</script>

<style>
.schedule.schedule--hidden {
display: none !important;
}

.schedule {
display: flex;
flex-direction: column;
align-items: center;
padding: 4rem 1.5rem;
background: black;
}
.section-heading {
font-family: 'Squada One', system-ui, sans-serif;
font-size: 2.5rem;
text-align: center;
margin: 0 0 3rem 0;
color: rgb(255, 193, 77);
}
#wrapper {
width: 100%;
max-width: 1200px;
display: flex;
flex-direction: column;
background: rgba(61, 120, 171, 0.08);
border: 1px solid rgba(61, 120, 171, 0.2);
border-radius: 1rem;
overflow: hidden;
}
.item {
display: flex;
flex-direction: column;
gap: 0.75rem;
padding: 0.9rem 0.9rem;
border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.time {
margin: 0;
color: rgba(255, 255, 255, 0.88);
font-size: 1rem;
line-height: 1.4;
white-space: nowrap;
}
.details {
display: flex;
flex-direction: column;
gap: 0.35rem;
}
.activity {
margin: 0;
color: white;
line-height: 1.3;
}
.activity-title {
font-size: 1.25rem;
font-weight: 600;
color: white;
}
.activity-meta {
font-size: 0.875rem;
color: white;
opacity: 0.7;
}
.activity-meta::before {
content: "◉";
display: inline-block;
margin-right: 0.35rem;
font-size: 0.75em;
vertical-align: middle;
}
@media (min-width: 769px) {
.schedule {
padding: 6rem 2rem;
}
.section-heading {
font-size: 4rem;
}
.item {
display: grid;
grid-template-columns: 220px 1fr;
align-items: start;
gap: 1.5rem;
padding: 1.2rem 1.2rem;
}
.time {
font-size: 1.125rem;
font-weight: 500;
}
.activity-title {
font-size: 1.25rem;
}
.activity-meta {
font-size: 0.875rem;
}
}
@media (max-width: 768px) {
.activity-title {
font-size: 1.25rem;
}
}
</style>
62 changes: 62 additions & 0 deletions src/lib/cityContent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
export type City = 'vancouver' | 'toronto';

export interface CitySchedule {
startTime: string;
endTime?: string;
activities: string[]
}

export interface CityContent {
name: string;
displayName: string;
Expand All @@ -8,6 +14,7 @@ export interface CityContent {
description: string;
venue?: string;
date?: string;
schedule?: CitySchedule[]
}

export const cityContent: Record<City, CityContent> = {
Expand All @@ -19,6 +26,61 @@ export const cityContent: Record<City, CityContent> = {
description: 'Connect with over 1,000 cloud professionals and decision-makers. Showcase your brand at this premier gathering of AWS, Azure, Google Cloud, and IBM Cloud experts.',
venue: 'Science World',
date: 'Friday, May 1st, 2026 • 2pm-9pm',
schedule: [
{
startTime: "3:00 PM",
activities: ["Doors Open"]
},
{
startTime: "3:00 PM",
activities: ["Community Experience sponsored by AWS opens"]
},
{
startTime: "3:20 PM",
endTime: "3:30 PM",
activities: ["Opening Welcome Remarks", "Community Stage, streamed to Main Stage"]
},
{
startTime: "3:30 PM",
endTime: "4:00 PM",
activities: ["Main Stage Session 1", " Community Stage Session 1"]
},
{
startTime: "4:00 PM",
endTime: "4:30 PM",
activities: ["Main Stage Session 2", "Community Stage Session 2"]
},
{
startTime: "4:30 PM",
endTime: "5:00 PM",
activities: ["Main Stage Session 3", "Community Stage HackerRivals Round 1"]
},
{
startTime: "5:00 PM",
endTime: "5:30 PM",
activities: ["Main Stage Session 4", "Community Stage Session 3"]
},
{
startTime: "5:30 PM",
endTime: "6:00 PM",
activities: ["Main Stage Session 5", "Community Stage HackerRivals Elimination Round"]
},
{
startTime: "6:00 PM",
endTime: "6:30 PM",
activities: ["Main Stage Session 6", "Community Stage Session 4"]
},
{
startTime: "6:30 PM",
endTime: "7:00 PM",
activities: ["HackerRivals Final", " Live on the Community Stage, streamed to the Main Stage"]
},
{
startTime: "7:00 PM",
endTime: "7:30 PM",
activities: ["HackerRivals Awards", "Closing Remarks", "Live on the Community Stage, streamed to the Main Stage"]
}
]
},
toronto: {
name: 'toronto',
Expand Down
4 changes: 3 additions & 1 deletion src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import Newsletter from '../components/Newsletter.astro';
import Footer from '../components/Footer.astro';
import SeeYouThere from '../components/SeeYouThere.astro';
import ScrollAnimations from '../components/ScrollAnimations.astro';
import { heroContent, navigationContent, aboutCPCAContent, whatIsCloudSummitContent, cloudSummitActivitiesContent, eventHighlightsContent, tickerContent, eventMapContent, pastSponsorsContent, newsletterContent, footerContent, defaultCity } from '../lib/content';
import { heroContent, navigationContent, aboutCPCAContent, whatIsCloudSummitContent, cloudSummitActivitiesContent, eventHighlightsContent, tickerContent, pastSponsorsContent, newsletterContent, footerContent, defaultCity } from '../lib/content';
import Schedule from '../components/Schedule.astro';

// Use default city for SSR, will be updated client-side
const content = heroContent[defaultCity];
Expand Down Expand Up @@ -102,6 +103,7 @@ const torontoDescription =
<CloudSummitActivities content={cloudSummitActivitiesContent} />
<AboutCPCA content={aboutCPCAContent} />
<EventLocations />
<Schedule></Schedule>
<SummitSummary content={eventHighlightsContent} />
<HighlightReel content={eventHighlightsContent} />
<Ticker content={tickerContent} />
Expand Down