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

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"astro": "^4.15.1",
"astro-embed": "^0.7.2",
"astro-icon": "^1.1.1",
"axios": "^1.7.9",
"axios": "^1.8.2",
"dotenv": "^16.4.7",
"gsap": "^3.12.5",
"i18next": "^24.2.0",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/images/portraits/portrait-img-04.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/components/blog/Headline.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { title = await Astro.slots.render('default'), subtitle = await Astro.slot
---

<header class="mb-8 md:mb-16 text-center max-w-3xl mx-auto">
<h1 class="text-4xl md:text-5xl font-bold leading-tighter er font-heading" set:html={title} />
<h1 class="text-4xl md:text-5xl font-bold leading-tighter font-heading" set:html={title} />
{
subtitle && (
Expand Down
72 changes: 37 additions & 35 deletions src/components/blog/SinglePost.astro
Original file line number Diff line number Diff line change
Expand Up @@ -55,43 +55,45 @@ const { post, url } = Astro.props;
</p>
</div>

<h1 class="px-4 sm:px-6 max-w-3xl mx-auto text-4xl md:text-5xl font-bold leading-tighter font-heading">
{post.title}
<h1 class="px-4 sm:px-6 max-w-3xl mx-auto text-4xl md:text-5xl font-bold leading-tighter er font-heading">
<h1 class="px-4 sm:px-6 max-w-3xl mx-auto text-4xl md:text-5xl font-bold leading-tighter font-heading">
{post.title}
</h1>
<p
class="max-w-3xl mx-auto mt-4 mb-8 px-4 sm:px-6 text-xl md:text-2xl text-muted dark:text-slate-400 text-justify"
>
{post.excerpt}
</p>

{
post.image ? (
<Image
src={post.image}
class="max-w-full lg:max-w-[900px] mx-auto mb-6 sm:rounded-md bg-gray-400 dark:bg-slate-700"
widths={[400, 900]}
sizes="(max-width: 900px) 400px, 900px"
alt={post?.excerpt || ''}
width={900}
height={506}
loading="eager"
decoding="async"
/>
) : (
<div class="max-w-3xl mx-auto px-4 sm:px-6">
<div class="border-t dark:border-slate-700" />
</div>
)
}
</h1>
<p
class="max-w-3xl mx-auto mt-4 mb-8 px-4 sm:px-6 text-xl md:text-2xl text-muted dark:text-slate-400 text-justify"
<div
class="mx-auto px-6 sm:px-6 max-w-3xl prose prose-md lg:prose-xl dark:prose-invert dark:prose-headings:text-slate-300 prose-headings:font-heading prose-headings:leading-tighter prose-headings:er prose-headings:font-bold prose-a:text-primary dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg mt-8 prose-headings:scroll-mt-[80px] prose-li:my-0"
>
{post.excerpt}
</p>

{
post.image ? (
<Image
src={post.image}
class="max-w-full lg:max-w-[900px] mx-auto mb-6 sm:rounded-md bg-gray-400 dark:bg-slate-700"
widths={[400, 900]}
sizes="(max-width: 900px) 400px, 900px"
alt={post?.excerpt || ''}
width={900}
height={506}
loading="eager"
decoding="async"
/>
) : (
<div class="max-w-3xl mx-auto px-4 sm:px-6">
<div class="border-t dark:border-slate-700" />
</div>
)
}
<slot />
</div>
<div class="mx-auto px-6 sm:px-6 max-w-3xl mt-8 flex justify-between flex-col sm:flex-row">
<PostTags tags={post.tags} class="mr-5 rtl:mr-0 rtl:ml-5" />
<SocialShare url={url} text={post.title} class="mt-5 sm:mt-1 align-middle text-gray-500 dark:text-slate-600" />
</div>
</header>
<div
class="mx-auto px-6 sm:px-6 max-w-3xl prose prose-md lg:prose-xl dark:prose-invert dark:prose-headings:text-slate-300 prose-headings:font-heading prose-headings:leading-tighter prose-headings:er prose-headings:font-bold prose-a:text-primary dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg mt-8 prose-headings:scroll-mt-[80px] prose-li:my-0"
>
<slot />
</div>
<div class="mx-auto px-6 sm:px-6 max-w-3xl mt-8 flex justify-between flex-col sm:flex-row">
<PostTags tags={post.tags} class="mr-5 rtl:mr-0 rtl:ml-5" />
<SocialShare url={url} text={post.title} class="mt-5 sm:mt-1 align-middle text-gray-500 dark:text-slate-600" />
</div>
</article>
</section>
85 changes: 82 additions & 3 deletions src/components/widgets/CafeFlutterSection.astro
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
import type { CafeFlutterItem, Widget } from '~/types';
import WidgetWrapper from '../ui/WidgetWrapper.astro';
import { cafeFlutterEvents } from '~/data/mockCafeFlutter';
import PastCafeFlutterCard from './PastCafeFlutterCard.astro';
import CafeFlutterCountdown from '~/components/widgets/cafeFlutterCountdown/CafeFlutterCountdown.astro';
import SectionTitle from '../widgets/SectionTitleTwo.astro';
import { getCollection, getEntry } from 'astro:content';

interface Props extends Widget {
upcomingEvent?: CafeFlutterItem;
Expand All @@ -13,9 +13,88 @@ interface Props extends Widget {

const { id, isDark = false, classes = {} } = Astro.props;

const rawCollection = await getCollection('cafeFlutter');
const cafeFlutterCollection = rawCollection.filter(({ slug }) => slug.startsWith(Astro.currentLocale!));

// Convert content collection to CafeFlutterItem model
const contentCollectionEvents: CafeFlutterItem[] = await Promise.all(
cafeFlutterCollection.map(async (item) => {
// Extract event number from ID or use a fallback
const numberMatch = item.id.match(/cafe-flutter-(\d+)/i);
const eventNumber = numberMatch ? parseInt(numberMatch[1], 10) : 0;

// Create speaker objects from talks
const speakers = await Promise.all(
item.data.talks.map(async (talk) => {
// Handle speaker reference safely
let speakerName = '';
let speakerImage = 'https://via.placeholder.com/50x50'; // Default placeholder image

if (talk.speaker) {
const speakerData = await getEntry(talk.speaker);
if (speakerData) {
// Use the name and family from the referenced collection
speakerName = `${speakerData.data.name} ${speakerData.data.family}`;

// Use the speaker's image if available
if (
speakerData.data.image &&
typeof speakerData.data.image === 'object' &&
'src' in speakerData.data.image
) {
speakerImage = speakerData.data.image.src;
}
}
} else if (typeof talk.speaker === 'string') {
// If the speaker is a string, use it directly
speakerName = talk.speaker;
} else {
// Default fallback
speakerName = 'Speaker';
}

return {
name: speakerName,
title: talk.talkTitle,
image: {
src: speakerImage,
alt: speakerName,
},
};
})
);

// Create image object
let imageSrc = '';
if (typeof item.data.image === 'string') {
imageSrc = item.data.image;
} else if (item.data.image && typeof item.data.image === 'object' && 'src' in item.data.image) {
imageSrc = item.data.image.src;
}

// Convert to CafeFlutterItem
return {
number: eventNumber,
image: {
src: imageSrc,
alt: item.data.title,
},
speakers: speakers,
dateTime: new Date(item.data.dateTime), // Ensure it's a Date object
youtubeLink: item.data.youtubeLink,
googleMeetLink: item.data.googleMeetLink,
googleCalendarLink: item.data.calendarLink,
};
})
);

// Use only content collection events now
const allEvents = contentCollectionEvents;

// Filter past events
const now = new Date();
const pastEvents = cafeFlutterEvents

const pastEvents = allEvents
.filter((event) => {
const eventDate = new Date(event.dateTime);
const eventEndTime = new Date(eventDate.getTime() + 3 * 60 * 60 * 1000);
Expand All @@ -31,7 +110,7 @@ const getServerTime = async () => {
const serverTime = await getServerTime();

// Find an upcoming event
const upcomingEvent = cafeFlutterEvents
const upcomingEvent = allEvents
.filter((event) => {
const eventDate = new Date(event.dateTime);
const serverTimeLocal = new Date(serverTime);
Expand Down
81 changes: 57 additions & 24 deletions src/components/widgets/hero/CurvedAnimation.astro
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,28 @@
* - Icon elements with position-specific classes (e.g., .top-left-icon)
* - Portrait containers with specific IDs (e.g., portrait-top-left)
*/

import portraitImage1 from '~/assets/images/portraits/portrait-img-01.jpg';
import portraitImage1_02 from '~/assets/images/portraits/portrait-img-01-02.jpg';
import portraitImage1_03 from '~/assets/images/portraits/portrait-img-01-03.jpg';
import portraitImage2 from '~/assets/images/portraits/portrait-img-02.jpg';
import portraitImage2_02 from '~/assets/images/portraits/portrait-img-02-02.jpg';
import portraitImage2_03 from '~/assets/images/portraits/portrait-img-02-03.jpg';
import portraitImage3 from '~/assets/images/portraits/portrait-img-03.jpg';
import portraitImage3_02 from '~/assets/images/portraits/portrait-img-03-02.jpg';
import portraitImage3_03 from '~/assets/images/portraits/portrait-img-03-03.jpg';
import portraitImage4 from '~/assets/images/portraits/portrait-img-04.jpg';
import portraitImage4_02 from '~/assets/images/portraits/portrait-img-04-02.jpg';
import portraitImage4_03 from '~/assets/images/portraits/portrait-img-04-03.jpg';
import portraitImage5 from '~/assets/images/portraits/portrait-img-05.jpg';
import portraitImage5_02 from '~/assets/images/portraits/portrait-img-05-02.jpg';
import portraitImage5_03 from '~/assets/images/portraits/portrait-img-05-03.jpg';
import portraitImage6 from '~/assets/images/portraits/portrait-img-06.jpg';
import portraitImage6_02 from '~/assets/images/portraits/portrait-img-06-02.jpg';
import portraitImage6_03 from '~/assets/images/portraits/portrait-img-06-03.jpg';
import portraitImage7 from '~/assets/images/portraits/portrait-img-07.jpg';
import portraitImage7_02 from '~/assets/images/portraits/portrait-img-07-02.jpg';
import portraitImage7_03 from '~/assets/images/portraits/portrait-img-07-03.jpg';
import portraitImage8 from '~/assets/images/portraits/portrait-img-08.jpg';
import portraitImage9 from '~/assets/images/portraits/portrait-img-09.jpg';
import portraitImage10 from '~/assets/images/portraits/portrait-img-10.jpg';
Expand All @@ -54,12 +69,26 @@ import portraitImage17 from '~/assets/images/portraits/portrait-img-17.jpg';

const portraitPaths = {
portrait1: portraitImage1.src,
portrait1_02: portraitImage1_02.src,
portrait1_03: portraitImage1_03.src,
portrait2: portraitImage2.src,
portrait2_02: portraitImage2_02.src,
portrait2_03: portraitImage2_03.src,
portrait3: portraitImage3.src,
portrait3_02: portraitImage3_02.src,
portrait3_03: portraitImage3_03.src,
portrait4: portraitImage4.src,
portrait4_02: portraitImage4_02.src,
portrait4_03: portraitImage4_03.src,
portrait5: portraitImage5.src,
portrait5_02: portraitImage5_02.src,
portrait5_03: portraitImage5_03.src,
portrait6: portraitImage6.src,
portrait6_02: portraitImage6_02.src,
portrait6_03: portraitImage6_03.src,
portrait7: portraitImage7.src,
portrait7_02: portraitImage7_02.src,
portrait7_03: portraitImage7_03.src,
portrait8: portraitImage8.src,
portrait9: portraitImage9.src,
portrait10: portraitImage10.src,
Expand All @@ -82,52 +111,56 @@ const portraitPaths = {
// Define portrait images mapping
const portraitImagePaths = {
0: portraitPaths.portrait1,
1: portraitPaths.portrait2,
2: portraitPaths.portrait3,
3: portraitPaths.portrait4,
4: portraitPaths.portrait5,
5: portraitPaths.portrait6,
6: portraitPaths.portrait7,
7: portraitPaths.portrait8,
8: portraitPaths.portrait9,
9: portraitPaths.portrait10,
10: portraitPaths.portrait11,
11: portraitPaths.portrait12,
12: portraitPaths.portrait13,
13: portraitPaths.portrait14,
14: portraitPaths.portrait15,
15: portraitPaths.portrait16,
16: portraitPaths.portrait17,
1: portraitPaths.portrait1_02,
2: portraitPaths.portrait1_03,
3: portraitPaths.portrait2,
4: portraitPaths.portrait2_02,
5: portraitPaths.portrait2_03,
6: portraitPaths.portrait3,
7: portraitPaths.portrait3_02,
8: portraitPaths.portrait3_03,
9: portraitPaths.portrait4,
10: portraitPaths.portrait4_02,
11: portraitPaths.portrait4_03,
12: portraitPaths.portrait5,
13: portraitPaths.portrait5_02,
14: portraitPaths.portrait5_03,
15: portraitPaths.portrait6,
16: portraitPaths.portrait6_02,
17: portraitPaths.portrait6_03,
18: portraitPaths.portrait7,
19: portraitPaths.portrait7_02,
20: portraitPaths.portrait7_03,
};

const imageMappings = {
topLeft: {
containerId: 'portrait-top-left',
imageIndices: [0, 4, 8, 12, 16],
imageIndices: [3, 4, 5],
},
topRight: {
containerId: 'portrait-top-right',
imageIndices: [1, 5, 9, 13, 2],
imageIndices: [0, 1, 2],
},
middleLeft: {
containerId: 'portrait-middle-left',
imageIndices: [2, 6, 10, 14, 15],
imageIndices: [12, 13, 14],
},
middleCenter: {
containerId: 'portrait-middle-center',
imageIndices: [3, 7, 11, 15, 16],
imageIndices: [9, 10, 11],
},
middleRight: {
containerId: 'portrait-middle-right',
imageIndices: [4, 8, 12, 16, 0],
imageIndices: [6, 7, 8],
},
bottomLeft: {
containerId: 'portrait-bottom-left',
imageIndices: [5, 9, 13, 3, 0],
imageIndices: [18, 19, 20],
},
bottomRight: {
containerId: 'portrait-bottom-right',
imageIndices: [6, 10, 14, 1, 2],
imageIndices: [15, 16, 17],
},
};

Expand Down Expand Up @@ -541,7 +574,7 @@ const portraitPaths = {

curves.forEach((curve, index) => {
if (curve.icon && curve.path) {
new CurvedAnimation(curve.icon, curve.path, curve.type, { delay: index * 0.3 });
new CurvedAnimation(curve.icon, curve.path, curve.type, { delay: index * 0.01 });
}
});
}
Expand Down
Loading
Loading