Beautiful React components for displaying gamification data.
🎮 LuduStack - The complete gamification platform for developers.
The @ludustack/react
package provides pure rendering UI components for displaying gamification data. These components take data as props and render beautiful, responsive interfaces.
- 🎨 Pure Rendering: Components only display data passed as props
- 📊 Beautiful UI: Responsive, accessible components with animations
- ⚡ Lightweight: No data fetching, no complex state management
- 🔧 Customizable: Flexible styling and behavior options
npm install @ludustack/react @ludustack/sdk
Install
@ludustack/sdk
for server-side data fetching.
// app/page.tsx (Next.js Server Component)
import { LudustackSDK } from "@ludustack/sdk";
import { PlayerCard } from "@ludustack/react";
export default async function GamePage() {
// Server-side data fetching
const sdk = new LudustackSDK({
apiKey: process.env.LUDUSTACK_API_KEY!,
gameId: "your-game-id",
});
const player = await sdk.player.getById("player-123");
const game = await sdk.game.getById("your-game-id");
return (
<div>
<h1>Player Dashboard</h1>
<PlayerCard
player={player}
game={game}
onViewProfileClick={(player) => {
// Handle navigation
console.log("View profile for", player.displayName);
}}
/>
</div>
);
}
// app/components/player-actions.tsx
"use client";
import { givePointsAction } from "../actions/gamification";
export function PlayerActions({ playerId }: { playerId: string }) {
const handleGivePoints = async () => {
await givePointsAction(playerId, 100, "manual_award");
};
return <button onClick={handleGivePoints}>Give 100 Points</button>;
}
// app/actions/gamification.ts (Server Action)
"use server";
import { LudustackSDK } from "@ludustack/sdk";
export async function givePointsAction(
playerId: string,
points: number,
action: string
) {
const sdk = new LudustackSDK({
apiKey: process.env.LUDUSTACK_API_KEY!,
gameId: process.env.LUDUSTACK_GAME_ID!,
});
return await sdk.operations.givePoints(playerId, points, action);
}
Displays comprehensive player information including avatar, points, level, and progress.
<PlayerCard
player={player} // Required: Player data
game={game} // Optional: Game data for context
showGameInfo={true} // Optional: Show game information
sortIndex={0} // Optional: Position in ranking
onViewProfileClick={(player) => {}} // Optional: Profile click handler
onEditPlayerClick={(player) => {}} // Optional: Edit click handler
/>
Compact player information display.
<PlayerBadge player={player} onClick={() => console.log("Badge clicked")} />
Displays ranked players in a table format.
<LeaderboardTable
players={players} // Required: Array of players
title="Top Players" // Optional: Table title
highlightedPlayerId="player-123" // Optional: Highlight specific player
/>
Shows player points with optional animations.
<PointsDisplay
points={150}
singular="point"
plural="points"
animateChanges={true}
/>
// app/leaderboard/page.tsx
import { LudustackSDK } from "@ludustack/sdk";
import { LeaderboardTable } from "@ludustack/react";
export default async function LeaderboardPage() {
const sdk = new LudustackSDK({
apiKey: process.env.LUDUSTACK_API_KEY!,
gameId: "your-game-id",
});
const players = await sdk.player.list({
gameId: "your-game-id",
sortBy: "points",
order: "desc",
limit: 10,
});
return (
<div>
<h1>Leaderboard</h1>
<LeaderboardTable players={players} title="Top 10 Players" />
</div>
);
}
// app/api/players/[id]/route.ts
import { NextRequest, NextResponse } from "next/server";
import { LudustackSDK } from "@ludustack/sdk";
export async function GET(
request: NextRequest,
{ params }: { params: { id: string } }
) {
const sdk = new LudustackSDK({
apiKey: process.env.LUDUSTACK_API_KEY!,
gameId: process.env.LUDUSTACK_GAME_ID!,
});
try {
const player = await sdk.player.getById(params.id);
return NextResponse.json(player);
} catch (error) {
return NextResponse.json({ error: "Player not found" }, { status: 404 });
}
}
// app/actions/achievements.ts
"use server";
import { LudustackSDK } from "@ludustack/sdk";
import { revalidatePath } from "next/cache";
export async function processAchievementAction(
playerId: string,
achievementId: string,
options?: { forceComplete?: boolean }
) {
const sdk = new LudustackSDK({
apiKey: process.env.LUDUSTACK_API_KEY!,
gameId: process.env.LUDUSTACK_GAME_ID!,
});
const result = await sdk.operations.processAchievement(
playerId,
achievementId,
options
);
revalidatePath("/player/[id]", "page");
return result;
}
import { useAnimationStyles } from "@ludustack/react";
function MyComponent() {
// Ensures animation styles are loaded
useAnimationStyles();
return (
<div className="animate-in fade-in duration-200">Animated content</div>
);
}
interface Player {
id: string;
displayName?: string;
username?: string;
email?: string;
externalId?: string;
avatarUrl?: string;
points?: number;
level?: {
currentLevelNumber?: number;
currentLevelName?: string;
levelProgress?: number;
nextLevelThreshold?: number | null;
};
gameId?: string;
}
interface Game {
id: string;
name: string;
status?: string;
description?: string;
type?: string;
}
Full TypeScript support with strict type definitions:
import { Player, Game, PlayerCardProps } from "@ludustack/react";
const player: Player = {
id: "player-123",
displayName: "Player Name",
points: 250,
level: {
currentLevelNumber: 3,
currentLevelName: "Explorer",
levelProgress: 65,
nextLevelThreshold: 500,
},
};
Components use Tailwind CSS classes and support custom styling:
<PlayerCard player={player} className="bg-blue-50 border-blue-200" />
- No API calls: Components only render data, no network requests
- Server-side rendering: Compatible with SSR/SSG for faster initial loads
- Efficient animations: Lightweight CSS-based animations
- Small bundle: No SDK or complex dependencies in client bundle
For support, please:
- Visit our main website
- Contact us
- Check our documentation
MIT