diff --git a/components/clubs/ClubDetail.tsx b/components/clubs/ClubDetail.tsx
index 4e6f964..18a9661 100644
--- a/components/clubs/ClubDetail.tsx
+++ b/components/clubs/ClubDetail.tsx
@@ -1,24 +1,156 @@
'use client';
-import Image from 'next/image';
-import { ctfSrc } from '@/lib/contentful-src';
import Link from 'next/link';
-import { documentToReactComponents, Options } from '@contentful/rich-text-react-renderer';
-import { BLOCKS } from '@contentful/rich-text-types';
-import { Globe, ArrowLeft, ExternalLink } from 'lucide-react';
+import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
+import { BLOCKS, type TopLevelBlock } from '@contentful/rich-text-types';
+import { ArrowLeft, ArrowUpRight } from 'lucide-react';
import { ClubItems } from '@/hooks/useClubs';
import Container from '../custom/Container';
-import { richTextParagraphRenderer } from '@/lib/richTextOptions';
+import { proseRichTextOptions, type EmbeddedAsset } from '@/lib/richTextOptions';
+import { contentfulImage } from '@/lib/contentful-image';
+import ClubLogo from './ClubLogo';
import { useStore } from '@/store/useStore';
-import { useEffect } from 'react';
+import { Fragment, useEffect } from 'react';
interface ClubDetailProps {
club: ClubItems;
}
+type ContentGroup = { kind: 'nodes'; nodes: TopLevelBlock[] } | { kind: 'assets'; ids: string[] };
+
+function groupAssetRuns(nodes: TopLevelBlock[]): ContentGroup[] {
+ const groups: ContentGroup[] = [];
+ for (const node of nodes) {
+ const id = node.nodeType === BLOCKS.EMBEDDED_ASSET ? node.data?.target?.sys?.id : undefined;
+ const last = groups[groups.length - 1];
+ if (id) {
+ if (last?.kind === 'assets') last.ids.push(id);
+ else groups.push({ kind: 'assets', ids: [id] });
+ } else if (last?.kind === 'nodes') {
+ last.nodes.push(node);
+ } else {
+ groups.push({ kind: 'nodes', nodes: [node] });
+ }
+ }
+ return groups;
+}
+
+interface AssetGridProps {
+ ids: string[];
+ findAsset: (id: string) => EmbeddedAsset | undefined;
+}
+
+const isPortrait = (asset: EmbeddedAsset) => Boolean(asset.width && asset.height && asset.height > asset.width);
+
+const AssetGrid = ({ ids, findAsset }: AssetGridProps) => {
+ const items = ids.map(findAsset).filter((asset): asset is EmbeddedAsset => Boolean(asset?.url));
+ if (items.length === 0) return null;
+
+ const single = items.length === 1;
+ const captioned = items.every((asset) => asset.description);
+ const people = captioned && (!single || isPortrait(items[0]));
+
+ if (single && !people) {
+ const image = contentfulImage(items[0].url, { intrinsicWidth: items[0].width, intrinsicHeight: items[0].height });
+ return (
+
+ {items[0].description && (
+
{asset.title}
+ {asset.description && ( +{asset.description}
+ )} ++ + {recruiting ? 'Accepting new members' : 'Recruitment currently closed'} +
+); + +const JoinButton = ({ clubLink, className = '' }: { clubLink: string; className?: string }) => ( + + Join the community +Membership is open to all GESA students.
+{clubType}
-Open to all GESA Students
-- Currently accepting new members for the academic year. -
-- Membership recruitment is currently closed. Please check back later. -
-{description}
+ )}{club.description}
diff --git a/components/home/HomeClubsPreview.tsx b/components/home/HomeClubsPreview.tsx index a7e2c56..aa60234 100644 --- a/components/home/HomeClubsPreview.tsx +++ b/components/home/HomeClubsPreview.tsx @@ -1,12 +1,11 @@ 'use client' import Container from '../custom/Container' -import { ctfSrc } from '@/lib/contentful-src'; import { Button } from '../ui/button' import { ArrowRight } from 'lucide-react' import Link from 'next/link' import { useClubs } from '@/hooks/useClubs' import type { ClubItems } from '@/lib/data/club' -import Image from 'next/image' +import ClubLogo from '../clubs/ClubLogo' import EmptyState from '../events/EmptyState' import { Users, TriangleAlert } from 'lucide-react' @@ -73,15 +72,14 @@ const HomeClubsPreview = ({ initialClubs }: { initialClubs?: ClubItems[] }) => { key={club.sys?.id ?? index} className='bg-white p-8 rounded-3xl shadow-sm border border-slate-100 hover:shadow-xl transition-all duration-500 flex flex-col gap-6 group hover:-translate-y-1' > -{club.description}