diff --git a/src/lib/cards/index.ts b/src/lib/cards/index.ts --- a/src/lib/cards/index.ts +++ b/src/lib/cards/index.ts @@ -40,6 +40,7 @@ import { GitHubContributorsCardDefinition } from './social/GitHubContributorsCard'; import { ProductHuntCardDefinition } from './social/ProductHuntCard'; import { KickstarterCardDefinition } from './social/KickstarterCard'; +import { NpmxLikesCardDefinition } from './social/NpmxLikesCard'; // import { Model3DCardDefinition } from './visual/Model3DCard'; export const AllCardDefinitions = [ @@ -84,7 +85,8 @@ FriendsCardDefinition, GitHubContributorsCardDefinition, ProductHuntCardDefinition, - KickstarterCardDefinition + KickstarterCardDefinition, + NpmxLikesCardDefinition ] as const; export const CardDefinitionsByType = AllCardDefinitions.reduce( diff --git a/src/routes/api/npmx-leaderboard/+server.ts b/src/routes/api/npmx-leaderboard/+server.ts new file mode 100644 --- /dev/null +++ b/src/routes/api/npmx-leaderboard/+server.ts @@ -0,0 +1,44 @@ +import { json } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; + +const LEADERBOARD_API_URL = + 'https://npmx-likes-leaderboard-api-production.up.railway.app/api/leaderboard/likes'; + +export const GET: RequestHandler = async ({ platform }) => { + const cacheKey = '#npmx-leaderboard:likes'; + const cachedData = await platform?.env?.USER_DATA_CACHE?.get(cacheKey); + + if (cachedData) { + const parsedCache = JSON.parse(cachedData); + + const TWELVE_HOURS = 12 * 60 * 60 * 1000; + const now = Date.now(); + + if (now - (parsedCache.updatedAt || 0) < TWELVE_HOURS) { + return json(parsedCache.data); + } + } + + try { + const response = await fetch(LEADERBOARD_API_URL); + + if (!response.ok) { + return json( + { error: 'Failed to fetch npmx leaderboard ' + response.statusText }, + { status: response.status } + ); + } + + const data = await response.json(); + + await platform?.env?.USER_DATA_CACHE?.put( + cacheKey, + JSON.stringify({ data, updatedAt: Date.now() }) + ); + + return json(data); + } catch (error) { + console.error('Error fetching npmx leaderboard:', error); + return json({ error: 'Failed to fetch npmx leaderboard' }, { status: 500 }); + } +}; diff --git a/src/lib/cards/social/NpmxLikesCard/NpmxLikesCard.svelte b/src/lib/cards/social/NpmxLikesCard/NpmxLikesCard.svelte new file mode 100644 --- /dev/null +++ b/src/lib/cards/social/NpmxLikesCard/NpmxLikesCard.svelte @@ -0,0 +1,103 @@ + + +{#snippet likeItem(like: NpmxLike)} +