Skip to content

Commit 56f5281

Browse files
committed
Improve members pages
- Rename /members/subscriptions → /members/list - Clean names: strip @ and everything after it - Sort members alphabetically by first name - Move 'Become a Member' CTA to top of page - Add 'Active Commoners' stat to /members page (links to /members/list) - Change title from 'Membership Subscriptions' to 'Active Commoners'
1 parent bd6173b commit 56f5281

2 files changed

Lines changed: 82 additions & 36 deletions

File tree

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ function formatDate(dateStr: string): string {
4242
});
4343
}
4444

45+
/**
46+
* Clean name: remove @ and everything after it
47+
*/
48+
function cleanName(name: string): string {
49+
if (name.includes("@")) {
50+
return name.split("@")[0].trim();
51+
}
52+
return name;
53+
}
54+
4555
function getStatusColor(status: Member["status"]): string {
4656
switch (status) {
4757
case "active":
@@ -92,7 +102,7 @@ function getMonthOptions(): Array<{ value: string; label: string }> {
92102
return options;
93103
}
94104

95-
export default function MemberSubscriptionsPage() {
105+
export default function MemberListPage() {
96106
const [data, setData] = useState<MembersFile | null>(null);
97107
const [loading, setLoading] = useState(true);
98108
const [error, setError] = useState<string | null>(null);
@@ -120,6 +130,10 @@ export default function MemberSubscriptionsPage() {
120130
return res.json();
121131
})
122132
.then((data: MembersFile) => {
133+
// Sort members alphabetically by firstName
134+
data.members.sort((a, b) =>
135+
cleanName(a.firstName).localeCompare(cleanName(b.firstName))
136+
);
123137
setData(data);
124138
setLoading(false);
125139
})
@@ -143,7 +157,7 @@ export default function MemberSubscriptionsPage() {
143157
</Link>
144158
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
145159
<div>
146-
<h1 className="text-3xl font-bold">Membership Subscriptions</h1>
160+
<h1 className="text-3xl font-bold">Active Commoners</h1>
147161
<p className="text-muted-foreground mt-1">
148162
Supporting members who contribute financially to the Commons Hub
149163
</p>
@@ -163,6 +177,36 @@ export default function MemberSubscriptionsPage() {
163177
</div>
164178
</div>
165179

180+
{/* Join CTA - at the top */}
181+
<Card className="mb-8 bg-gradient-to-r from-primary/10 to-primary/5">
182+
<CardHeader>
183+
<CardTitle>Become a Member</CardTitle>
184+
<CardDescription>
185+
Support the Commons Hub Brussels and get access to member benefits
186+
</CardDescription>
187+
</CardHeader>
188+
<CardContent>
189+
<div className="flex flex-wrap gap-4">
190+
<a
191+
href="https://buy.stripe.com/00g9C7dFH8EI07eaEJ"
192+
target="_blank"
193+
rel="noopener noreferrer"
194+
className="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow hover:bg-primary/90"
195+
>
196+
Monthly — €10/month
197+
</a>
198+
<a
199+
href="https://buy.stripe.com/5kA4hNbxz4os2fm3cl"
200+
target="_blank"
201+
rel="noopener noreferrer"
202+
className="inline-flex items-center justify-center rounded-md border border-primary bg-background px-4 py-2 text-sm font-medium text-primary shadow-sm hover:bg-primary/10"
203+
>
204+
Yearly — €100/year (save €20)
205+
</a>
206+
</div>
207+
</CardContent>
208+
</Card>
209+
166210
{loading ? (
167211
<div className="flex items-center justify-center min-h-[400px]">
168212
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
@@ -262,7 +306,7 @@ export default function MemberSubscriptionsPage() {
262306
<TableRow key={member.id}>
263307
<TableCell>
264308
<div className="flex flex-col">
265-
<span className="font-medium">{member.firstName}</span>
309+
<span className="font-medium">{cleanName(member.firstName)}</span>
266310
{member.accounts.discord && (
267311
<span className="text-xs text-muted-foreground">
268312
@{member.accounts.discord}
@@ -317,36 +361,6 @@ export default function MemberSubscriptionsPage() {
317361
</CardContent>
318362
</Card>
319363

320-
{/* Join CTA */}
321-
<Card className="mt-8 bg-gradient-to-r from-primary/10 to-primary/5">
322-
<CardHeader>
323-
<CardTitle>Become a Member</CardTitle>
324-
<CardDescription>
325-
Support the Commons Hub Brussels and get access to member benefits
326-
</CardDescription>
327-
</CardHeader>
328-
<CardContent>
329-
<div className="flex flex-wrap gap-4">
330-
<a
331-
href="https://buy.stripe.com/00g9C7dFH8EI07eaEJ"
332-
target="_blank"
333-
rel="noopener noreferrer"
334-
className="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow hover:bg-primary/90"
335-
>
336-
Monthly — €10/month
337-
</a>
338-
<a
339-
href="https://buy.stripe.com/5kA4hNbxz4os2fm3cl"
340-
target="_blank"
341-
rel="noopener noreferrer"
342-
className="inline-flex items-center justify-center rounded-md border border-primary bg-background px-4 py-2 text-sm font-medium text-primary shadow-sm hover:bg-primary/10"
343-
>
344-
Yearly — €100/year (save €20)
345-
</a>
346-
</div>
347-
</CardContent>
348-
</Card>
349-
350364
{/* Data info */}
351365
<p className="text-xs text-muted-foreground text-center mt-8">
352366
Data generated: {new Date(data.generatedAt).toLocaleString()}

src/app/members/page.tsx

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"use client";
22

3-
import type { Metadata } from "next";
3+
import { useEffect, useState } from "react";
44
import Link from "next/link";
55
import Image from "next/image";
66
import { RecentContributors } from "@/components/recent-contributors";
77
import { DiscordStatsDisplay } from "@/components/discord-stats";
88
import { CommunityActivityGallery } from "@/components/community-activity-gallery";
99
import { Button } from "@/components/ui/button";
10-
import { ArrowRight, Building2, Utensils, Users, Leaf } from "lucide-react";
10+
import { ArrowRight, Building2, Utensils, Users, Leaf, Heart } from "lucide-react";
1111
import partnersData from "@/settings/partners.json";
1212
import settings from "@/settings/settings.json";
1313
import {
@@ -26,6 +26,25 @@ interface Partner {
2626
const partners: Partner[] = partnersData;
2727

2828
export default function MembersPage() {
29+
const [activeCommoners, setActiveCommoners] = useState<number | null>(null);
30+
31+
useEffect(() => {
32+
// Fetch current month's active members count
33+
const now = new Date();
34+
const year = now.getFullYear();
35+
const month = String(now.getMonth() + 1).padStart(2, "0");
36+
37+
fetch(`/api/members?year=${year}&month=${month}`)
38+
.then(res => res.ok ? res.json() : null)
39+
.then(data => {
40+
if (data?.summary?.activeMembers) {
41+
setActiveCommoners(data.summary.activeMembers);
42+
}
43+
})
44+
.catch(() => {
45+
// Silently fail - the stat just won't show
46+
});
47+
}, []);
2948
return (
3049
<div className="min-h-screen bg-background">
3150
<main className="pt-24">
@@ -46,7 +65,7 @@ export default function MembersPage() {
4665
{/* Stats */}
4766
<section className="py-12 px-4 sm:px-6 lg:px-8 border-b border-border">
4867
<div className="max-w-6xl mx-auto">
49-
<div className="grid grid-cols-3 gap-8 text-center">
68+
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 text-center">
5069
<div>
5170
<div className="flex justify-center mb-3">
5271
<Building2 className="w-8 h-8 text-primary" />
@@ -58,6 +77,19 @@ export default function MembersPage() {
5877
Partner Organizations
5978
</p>
6079
</div>
80+
{activeCommoners !== null && (
81+
<Link href="/members/list" className="group">
82+
<div className="flex justify-center mb-3">
83+
<Heart className="w-8 h-8 text-primary group-hover:scale-110 transition-transform" />
84+
</div>
85+
<p className="text-3xl font-bold text-foreground group-hover:text-primary transition-colors">
86+
{activeCommoners}
87+
</p>
88+
<p className="text-sm text-muted-foreground group-hover:text-primary/80 transition-colors">
89+
Active Commoners
90+
</p>
91+
</Link>
92+
)}
6193
<DiscordStatsDisplay />
6294
</div>
6395
</div>

0 commit comments

Comments
 (0)