Skip to content

Commit 6d54f04

Browse files
committed
fix: update community calls from weekly to bi-weekly schedule
- Changed all references from "weekly" to "bi-weekly" across the site - Updated meeting calculation logic to show meetings every 2 weeks - Added RRULE for bi-weekly recurrence in ICS and Google Calendar - Fixed "Join Meeting Now" button timing calculation (was dividing by 30 instead of 60) - Embedded YouTube playlist directly on community calls page - Updated reference date to Feb 3, 2026 for correct bi-weekly calculation
1 parent e3f6e7a commit 6d54f04

File tree

3 files changed

+90
-51
lines changed

3 files changed

+90
-51
lines changed

app/app/api/community-call-ics/route.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const MEETING_CONFIG = {
1616
};
1717

1818
// Generate description
19-
const MEETING_DESCRIPTION = `Join us for our weekly community call!\\n\\nCheck the agenda in our Slack community: https://join.slack.com/t/archestracommunity/shared_invite/zt-39yk4skox-zBF1NoJ9u4t59OU8XxQChg\\n\\nGoogle Meet: ${MEETING_CONFIG.meetingLink}\\n\\nMore info: https://archestra.ai/community-calls`;
19+
const MEETING_DESCRIPTION = `Join us for our bi-weekly community call!\\n\\nCheck the agenda in our Slack community: https://join.slack.com/t/archestracommunity/shared_invite/zt-39yk4skox-zBF1NoJ9u4t59OU8XxQChg\\n\\nGoogle Meet: ${MEETING_CONFIG.meetingLink}\\n\\nMore info: https://archestra.ai/community-calls`;
2020

2121
export async function GET() {
2222
// Get the next meeting day
@@ -118,13 +118,14 @@ RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
118118
END:STANDARD
119119
END:VTIMEZONE
120120
BEGIN:VEVENT
121-
UID:archestra-community-call-${eventDate}@archestra.ai
121+
UID:archestra-community-call-recurring@archestra.ai
122122
DTSTAMP:${new Date()
123123
.toISOString()
124124
.replace(/[-:]/g, '')
125125
.replace(/\.\d{3}/, '')}Z
126126
DTSTART;TZID=Europe/London:${eventDate}T${String(MEETING_CONFIG.hour).padStart(2, '0')}${String(MEETING_CONFIG.minute).padStart(2, '0')}00
127127
DTEND;TZID=Europe/London:${eventDate}T${String(MEETING_CONFIG.hour).padStart(2, '0')}${String(MEETING_CONFIG.minute + MEETING_CONFIG.durationMinutes).padStart(2, '0')}00
128+
RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU
128129
SUMMARY:${MEETING_CONFIG.title}
129130
DESCRIPTION:${MEETING_DESCRIPTION}
130131
LOCATION:${MEETING_CONFIG.meetingLink}

app/app/community-calls/page.tsx

Lines changed: 85 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { TZDate } from '@date-fns/tz';
44
import { addDays, getDay, setHours, setMilliseconds, setMinutes, setSeconds } from 'date-fns';
5-
import { Bell, Calendar, Users, Video } from 'lucide-react';
5+
import { Bell, Calendar, Users, Video, Play } from 'lucide-react';
66
import Image from 'next/image';
77

88
import CommunityCallsNewsletterForm from '@components/CommunityCallsNewsletterForm';
@@ -42,38 +42,60 @@ const MEETING_DETAILS = {
4242
};
4343

4444
// Generate description from agenda items
45-
const MEETING_DESCRIPTION = `Join us for our weekly community call!
45+
const MEETING_DESCRIPTION = `Join us for our bi-weekly community call!
4646
4747
Check the agenda in our Slack community: ${constants.slack.joinCommunityUrl}
4848
4949
Google Meet: ${MEETING_CONFIG.meetingLink}`;
5050

51-
const DESCRIPTION = `Join our weekly community calls every ${MEETING_CONFIG.dayOfWeek} at ${MEETING_CONFIG.time} (${MEETING_CONFIG.timezone}). Connect with the Archestra team and community members.`;
51+
const DESCRIPTION = `Join our bi-weekly community calls every other ${MEETING_CONFIG.dayOfWeek} at ${MEETING_CONFIG.time} (${MEETING_CONFIG.timezone}). Connect with the Archestra team and community members.`;
5252

5353
export default function CommunityCallsPage() {
54-
// Calculate next meeting date (2pm London time)
54+
// Calculate next meeting date (2pm London time) - bi-weekly schedule
5555
const getNextMeetingDate = (): Date => {
56+
// Define a reference date for the bi-weekly schedule (a known meeting date)
57+
// Using February 3, 2026 as a reference Tuesday (midnight for date calculation)
58+
const referenceDate = new Date('2026-02-03T00:00:00Z');
59+
5660
// Get current time in London timezone using TZDate
5761
const nowInLondon = TZDate.tz(MEETING_CONFIG.timezone);
62+
const nowTime = nowInLondon.getTime();
63+
64+
// Calculate the number of days since the reference date
65+
const daysSinceReference = Math.floor((nowTime - referenceDate.getTime()) / (1000 * 60 * 60 * 24));
66+
67+
// Calculate the number of weeks since reference
68+
const weeksSinceReference = Math.floor(daysSinceReference / 7);
69+
70+
// Determine if we're in an "on" week (even weeks) or "off" week (odd weeks)
71+
const isOnWeek = weeksSinceReference % 2 === 0;
72+
5873
const londonDay = getDay(nowInLondon);
59-
6074
let daysUntilMeeting = MEETING_CONFIG.dayNumber - londonDay;
6175

62-
// If today is meeting day in London, check if the meeting time has passed
76+
// If today is Tuesday in London
6377
if (londonDay === MEETING_CONFIG.dayNumber) {
6478
const londonHour = nowInLondon.getHours();
6579
const londonMinute = nowInLondon.getMinutes();
66-
67-
if (
68-
londonHour > MEETING_CONFIG.hour ||
69-
(londonHour === MEETING_CONFIG.hour && londonMinute >= MEETING_CONFIG.minute)
70-
) {
71-
daysUntilMeeting = 7; // Next week
80+
81+
const hasMeetingPassed = londonHour > MEETING_CONFIG.hour ||
82+
(londonHour === MEETING_CONFIG.hour && londonMinute >= MEETING_CONFIG.minute);
83+
84+
if (isOnWeek && !hasMeetingPassed) {
85+
daysUntilMeeting = 0; // Today is a meeting day
7286
} else {
73-
daysUntilMeeting = 0; // Today
87+
// Next meeting is in 2 weeks if we're on an "on" week after meeting time,
88+
// or 1 week if we're on an "off" week
89+
daysUntilMeeting = isOnWeek ? 14 : 7;
7490
}
7591
} else if (daysUntilMeeting < 0) {
76-
daysUntilMeeting += 7;
92+
// Tuesday has passed this week
93+
daysUntilMeeting += isOnWeek ? 14 : 7;
94+
} else {
95+
// Tuesday is coming up this week
96+
if (!isOnWeek) {
97+
daysUntilMeeting += 7; // Skip to next week's Tuesday
98+
}
7799
}
78100

79101
// Create meeting date at 2pm London time using TZDate
@@ -93,7 +115,7 @@ export default function CommunityCallsPage() {
93115

94116
// Check if meeting is within 30 minutes
95117
const now = new Date();
96-
const minutesUntilMeeting = Math.floor((nextMeetingDate.getTime() - now.getTime()) / (1000 * 30));
118+
const minutesUntilMeeting = Math.floor((nextMeetingDate.getTime() - now.getTime()) / (1000 * 60));
97119
const canJoinMeeting = minutesUntilMeeting <= 30 && minutesUntilMeeting >= -30; // Allow joining 30 min before and during
98120

99121
// Format date for display
@@ -123,7 +145,7 @@ export default function CommunityCallsPage() {
123145
const structuredData = {
124146
'@context': 'https://schema.org',
125147
'@type': 'Event',
126-
name: 'Archestra Weekly Community Call',
148+
name: 'Archestra Bi-Weekly Community Call',
127149
description: DESCRIPTION,
128150
startDate: nextMeetingDate.toISOString(),
129151
endDate: new Date(nextMeetingDate.getTime() + MEETING_CONFIG.durationMinutes * 60000).toISOString(),
@@ -183,11 +205,11 @@ export default function CommunityCallsPage() {
183205
<div className="text-center mb-12">
184206
<div className="inline-flex items-center gap-2 bg-gradient-to-r from-teal-500 to-blue-500 text-white px-4 py-1 rounded-full text-sm font-medium mb-4">
185207
<Users className="w-4 h-4" />
186-
Every {MEETING_CONFIG.dayOfWeek} at {getLocalTime(nextMeetingDate)} ({localTimezoneName})
208+
Every Other {MEETING_CONFIG.dayOfWeek} at {getLocalTime(nextMeetingDate)} ({localTimezoneName})
187209
</div>
188-
<h1 className="text-4xl sm:text-5xl font-bold text-gray-900 mb-4">Weekly Community Calls</h1>
210+
<h1 className="text-4xl sm:text-5xl font-bold text-gray-900 mb-4">Bi-Weekly Community Calls</h1>
189211
<p className="text-xl text-gray-600 max-w-2xl mx-auto mb-8">
190-
Join us every Tuesday for our community calls where we discuss Archestra, share updates, and connect
212+
Join us every other Tuesday for our community calls where we discuss Archestra, share updates, and connect
191213
with fellow developers and AI enthusiasts.
192214
</p>
193215

@@ -262,7 +284,7 @@ export default function CommunityCallsPage() {
262284
Add to Calendar (.ics)
263285
</Button>
264286
<a
265-
href={`https://calendar.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(MEETING_CONFIG.title)}&dates=${getGoogleCalendarDate()}&details=${encodeURIComponent(MEETING_DESCRIPTION)}&location=${encodeURIComponent(MEETING_CONFIG.meetingLink)}&recur=${encodeURIComponent('RRULE:FREQ=WEEKLY;BYDAY=TU')}`}
287+
href={`https://calendar.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(MEETING_CONFIG.title)}&dates=${getGoogleCalendarDate()}&details=${encodeURIComponent(MEETING_DESCRIPTION)}&location=${encodeURIComponent(MEETING_CONFIG.meetingLink)}&recur=${encodeURIComponent('RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU')}`}
266288
target="_blank"
267289
rel="noopener noreferrer"
268290
className="bg-white hover:bg-gray-50 text-gray-700 border border-gray-300 font-medium py-2 px-4 rounded-lg transition-colors flex items-center gap-1.5 text-sm"
@@ -287,35 +309,51 @@ export default function CommunityCallsPage() {
287309
</CardContent>
288310
</Card>
289311

290-
{/* Two column grid for Watch Recordings and Get Notified */}
291-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
292-
{/* Recordings Card */}
293-
<Card className="border-2 hover:border-blue-200 transition-colors">
294-
<CardContent className="p-8">
295-
<div className="flex items-start gap-4">
296-
<div className="bg-blue-100 p-3 rounded-lg">
297-
<Video className="w-6 h-6 text-blue-600" />
298-
</div>
299-
<div className="flex-1">
300-
<h2 className="text-2xl font-bold mb-2">Watch Recordings</h2>
301-
<p className="text-gray-600 mb-4">
302-
Can't make it to the live call? All our community calls are recorded and available on YouTube.
303-
</p>
304-
<a
305-
href="https://www.youtube.com/@ArchestraAI"
306-
target="_blank"
307-
rel="noopener noreferrer"
308-
className="inline-flex items-center gap-2 bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-lg transition-colors text-sm"
309-
>
310-
<Video className="w-4 h-4" />
311-
Watch on YouTube
312-
</a>
313-
</div>
312+
{/* Watch Past Recordings Section */}
313+
<Card className="border-2 hover:border-blue-200 transition-colors mb-8">
314+
<CardContent className="p-8">
315+
<div className="flex items-start gap-4 mb-6">
316+
<div className="bg-blue-100 p-3 rounded-lg">
317+
<Video className="w-6 h-6 text-blue-600" />
314318
</div>
315-
</CardContent>
316-
</Card>
319+
<div className="flex-1">
320+
<h2 className="text-2xl font-bold mb-2">Past Community Calls</h2>
321+
<p className="text-gray-600 mb-4">
322+
Watch recordings of our previous community calls to catch up on discussions, demos, and updates.
323+
</p>
324+
</div>
325+
</div>
326+
327+
{/* YouTube Playlist Embed */}
328+
<div className="aspect-video rounded-lg overflow-hidden bg-gray-100 mb-4">
329+
<iframe
330+
src="https://www.youtube.com/embed/videoseries?list=PL2L0p-cygIJC8XSiOsLyCwN8D_uUakX75"
331+
title="Archestra Community Calls Playlist"
332+
className="w-full h-full"
333+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
334+
allowFullScreen
335+
/>
336+
</div>
337+
338+
<div className="flex justify-between items-center">
339+
<p className="text-sm text-gray-500">
340+
Subscribe to our YouTube channel to get notified when new recordings are available.
341+
</p>
342+
<a
343+
href="https://www.youtube.com/@ArchestraAI"
344+
target="_blank"
345+
rel="noopener noreferrer"
346+
className="inline-flex items-center gap-2 bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-lg transition-colors text-sm"
347+
>
348+
<Video className="w-4 h-4" />
349+
View All Videos
350+
</a>
351+
</div>
352+
</CardContent>
353+
</Card>
317354

318-
{/* Email Notification Card */}
355+
{/* Email Notification Card */}
356+
<div className="grid grid-cols-1 gap-8">
319357
<Card className="border-2 hover:border-purple-200 transition-colors">
320358
<CardContent className="p-8">
321359
<div className="flex items-start gap-4">

app/app/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,8 +1674,8 @@ export default function Home() {
16741674
<section className="py-12 bg-gradient-to-r from-teal-500 to-blue-600 text-white">
16751675
<div className="container px-4 md:px-6 max-w-7xl mx-auto">
16761676
<div className="text-center">
1677-
<h2 className="text-3xl sm:text-4xl font-bold mb-3">Weekly Community Calls</h2>
1678-
<p className="text-lg mb-6 max-w-xl mx-auto opacity-95">Every Tuesday at 2:00 PM London Time</p>
1677+
<h2 className="text-3xl sm:text-4xl font-bold mb-3">Bi-Weekly Community Calls</h2>
1678+
<p className="text-lg mb-6 max-w-xl mx-auto opacity-95">Every Other Tuesday at 2:00 PM London Time</p>
16791679
<Link
16801680
href="/community-calls"
16811681
className="inline-flex items-center gap-2 px-6 py-3 bg-white text-teal-600 font-semibold rounded-lg hover:bg-gray-50 transition-colors"

0 commit comments

Comments
 (0)