Skip to content

Commit 68161ee

Browse files
fix(web): improve sponsor data logic
1 parent 54c66ee commit 68161ee

File tree

4 files changed

+25
-109
lines changed

4 files changed

+25
-109
lines changed

apps/web/src/app/(home)/_components/sponsors-section.tsx

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ import {
1111
import Image from "next/image";
1212
import { useState } from "react";
1313
import {
14-
filterVisibleSponsors,
1514
formatSponsorUrl,
1615
getSponsorUrl,
17-
isSpecialSponsor,
16+
isLifetimeSpecialSponsor,
1817
shouldShowLifetimeTotal,
19-
sortSpecialSponsors,
2018
} from "@/lib/sponsor-utils";
2119
import type { SponsorsData } from "@/lib/types";
2220

@@ -27,13 +25,11 @@ export default function SponsorsSection({
2725
}) {
2826
const [showPastSponsors, setShowPastSponsors] = useState(false);
2927

30-
const allCurrentSponsors = [
31-
...sponsorsData.specialSponsors,
32-
...sponsorsData.sponsors,
33-
];
34-
const visibleSponsors = filterVisibleSponsors(allCurrentSponsors);
28+
const specialSponsors = sponsorsData.specialSponsors;
29+
const regularSponsors = sponsorsData.sponsors;
3530
const pastSponsors = sponsorsData.pastSponsors;
36-
const specialSponsors = sortSpecialSponsors(sponsorsData.specialSponsors);
31+
32+
const totalCurrentSponsors = specialSponsors.length + regularSponsors.length;
3733

3834
return (
3935
<div className="">
@@ -47,11 +43,11 @@ export default function SponsorsSection({
4743
<div className="hidden h-px flex-1 bg-border sm:block" />
4844
<div className="flex items-center gap-2">
4945
<span className="text-muted-foreground text-xs">
50-
[{visibleSponsors.length} RECORDS]
46+
[{totalCurrentSponsors} RECORDS]
5147
</span>
5248
</div>
5349
</div>
54-
{visibleSponsors.length === 0 ? (
50+
{totalCurrentSponsors === 0 ? (
5551
<div className="space-y-4">
5652
<div className="rounded border border-border p-8">
5753
<div className="text-center">
@@ -174,10 +170,10 @@ export default function SponsorsSection({
174170
</div>
175171
)}
176172

177-
{sponsorsData.sponsors.length > 0 && (
173+
{regularSponsors.length > 0 && (
178174
<div className="space-y-4">
179175
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
180-
{sponsorsData.sponsors.map((entry, index) => {
176+
{regularSponsors.map((entry, index) => {
181177
const sponsorUrl = getSponsorUrl(entry);
182178
return (
183179
<div
@@ -290,7 +286,7 @@ export default function SponsorsSection({
290286
{showPastSponsors && (
291287
<div className="slide-in-from-top-2 grid animate-in grid-cols-1 gap-4 duration-300 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
292288
{pastSponsors.map((entry, index) => {
293-
const wasSpecial = isSpecialSponsor(entry);
289+
const wasSpecial = isLifetimeSpecialSponsor(entry);
294290
const sponsorUrl = getSponsorUrl(entry);
295291

296292
return (

apps/web/src/lib/sponsor-utils.ts

Lines changed: 11 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2,114 +2,30 @@ import type { Sponsor } from "@/lib/types";
22

33
export const SPECIAL_SPONSOR_THRESHOLD = 100;
44

5-
export const getSponsorAmount = (sponsor: Sponsor): number => {
6-
// If totalProcessedAmount exists, use it, otherwise parse from tierName
7-
if (sponsor.totalProcessedAmount !== undefined) {
8-
return sponsor.totalProcessedAmount;
9-
}
10-
11-
// Parse amount from tierName as fallback
12-
const match = sponsor.tierName.match(/\$(\d+(?:\.\d+)?)/);
13-
return match ? Number.parseFloat(match[1]) : 0;
14-
};
15-
165
export const calculateLifetimeContribution = (sponsor: Sponsor): number => {
17-
// If totalProcessedAmount exists, use it, otherwise parse from tierName
18-
if (sponsor.totalProcessedAmount !== undefined) {
19-
return sponsor.totalProcessedAmount;
20-
}
21-
22-
// Parse amount from tierName as fallback
23-
const match = sponsor.tierName.match(/\$(\d+(?:\.\d+)?)/);
24-
return match ? Number.parseFloat(match[1]) : 0;
6+
// totalProcessedAmount is always provided by the API
7+
return sponsor.totalProcessedAmount || 0;
258
};
269

2710
export const shouldShowLifetimeTotal = (sponsor: Sponsor): boolean => {
28-
// Only show lifetime total if totalProcessedAmount exists
29-
return sponsor.totalProcessedAmount !== undefined;
30-
};
31-
32-
export const filterVisibleSponsors = (sponsors: Sponsor[]): Sponsor[] => {
33-
return sponsors.filter((sponsor) => {
34-
const amount = getSponsorAmount(sponsor);
35-
return amount >= 5;
36-
});
37-
};
38-
39-
export const isSpecialSponsor = (sponsor: Sponsor): boolean => {
40-
const amount = getSponsorAmount(sponsor);
41-
return amount >= SPECIAL_SPONSOR_THRESHOLD;
11+
// Only show lifetime total if totalProcessedAmount exists and tierName is present
12+
return sponsor.totalProcessedAmount !== undefined && !!sponsor.tierName;
4213
};
4314

4415
export const isLifetimeSpecialSponsor = (sponsor: Sponsor): boolean => {
4516
const lifetimeAmount = calculateLifetimeContribution(sponsor);
4617
return lifetimeAmount >= SPECIAL_SPONSOR_THRESHOLD;
4718
};
4819

49-
export const sortSponsors = (sponsors: Sponsor[]): Sponsor[] => {
50-
return sponsors.sort((a, b) => {
51-
const aAmount = getSponsorAmount(a);
52-
const bAmount = getSponsorAmount(b);
53-
const aIsSpecial = isSpecialSponsor(a);
54-
const bIsSpecial = isSpecialSponsor(b);
55-
56-
// 1. Special sponsors (>=$100) come first
57-
if (aIsSpecial && !bIsSpecial) return -1;
58-
if (!aIsSpecial && bIsSpecial) return 1;
59-
if (aIsSpecial && bIsSpecial) {
60-
if (aAmount !== bAmount) {
61-
return bAmount - aAmount;
62-
}
63-
// If amounts equal, sort by name
64-
return a.name.localeCompare(b.name);
65-
}
66-
67-
// 2. Regular sponsors sorted by amount (highest first)
68-
if (aAmount !== bAmount) {
69-
return bAmount - aAmount;
70-
}
71-
72-
// 3. If amounts equal, sort by name
73-
return a.name.localeCompare(b.name);
74-
});
75-
};
76-
77-
export const sortSpecialSponsors = (sponsors: Sponsor[]): Sponsor[] => {
78-
return sponsors.sort((a, b) => {
79-
const aLifetime = calculateLifetimeContribution(a);
80-
const bLifetime = calculateLifetimeContribution(b);
81-
82-
// Sort by lifetime contribution (highest first)
83-
if (aLifetime !== bLifetime) {
84-
return bLifetime - aLifetime;
85-
}
86-
87-
// If amounts equal, sort by name
88-
return a.name.localeCompare(b.name);
89-
});
90-
};
91-
92-
export const filterCurrentSponsors = (sponsors: Sponsor[]): Sponsor[] => {
93-
// In the new structure, all sponsors in the main arrays are current
94-
return sponsors;
95-
};
96-
97-
export const filterPastSponsors = (_sponsors: Sponsor[]): Sponsor[] => {
98-
// Past sponsors are handled separately in the new structure
99-
void _sponsors;
100-
return [];
101-
};
102-
103-
export const filterSpecialSponsors = (sponsors: Sponsor[]): Sponsor[] => {
104-
return sponsors.filter(isSpecialSponsor);
105-
};
20+
export const getSponsorUrl = (sponsor: Sponsor): string => {
21+
const url = sponsor.websiteUrl || sponsor.githubUrl;
10622

107-
export const filterRegularSponsors = (sponsors: Sponsor[]): Sponsor[] => {
108-
return sponsors.filter((sponsor) => !isSpecialSponsor(sponsor));
109-
};
23+
// Ensure URL has a protocol
24+
if (url && !url.startsWith("http://") && !url.startsWith("https://")) {
25+
return `https://${url}`;
26+
}
11027

111-
export const getSponsorUrl = (sponsor: Sponsor): string => {
112-
return sponsor.websiteUrl || sponsor.githubUrl;
28+
return url;
11329
};
11430

11531
export const formatSponsorUrl = (url: string): string => {

apps/web/src/lib/sponsors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ export async function fetchSponsors() {
2525
special_sponsors: 0,
2626
current_sponsors: 0,
2727
past_sponsors: 0,
28+
backers: 0,
2829
top_sponsor: { name: "", amount: 0 },
2930
},
3031
specialSponsors: [],
3132
sponsors: [],
3233
pastSponsors: [],
34+
backers: [],
3335
};
3436
}
3537
}

apps/web/src/lib/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export interface SponsorsData {
4747
special_sponsors: number;
4848
current_sponsors: number;
4949
past_sponsors: number;
50+
backers: number;
5051
top_sponsor: {
5152
name: string;
5253
amount: number;
@@ -55,4 +56,5 @@ export interface SponsorsData {
5556
specialSponsors: Sponsor[];
5657
sponsors: Sponsor[];
5758
pastSponsors: Sponsor[];
59+
backers: Sponsor[];
5860
}

0 commit comments

Comments
 (0)