@ludustack/react
v0.0.11
Published
Pure rendering React components for displaying gamification data
Readme
@ludustack/react
Beautiful React components for displaying gamification data.
🎮 LuduStack - The complete gamification platform for developers.
Overview
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
Installation
npm install @ludustack/react @ludustack/sdkInstall
@ludustack/sdkfor server-side data fetching.
Quick Start
1. Fetch Data Server-Side
// 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>
);
}2. Client-Side Operations
// 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);
}Available Components
<PlayerCard />
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
/><PlayerBadge />
Compact player information display.
<PlayerBadge player={player} onClick={() => console.log("Badge clicked")} /><LeaderboardTable />
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
/><PointsDisplay />
Shows player points with optional animations.
<PointsDisplay
points={150}
singular="point"
plural="points"
animateChanges={true}
/>Data Fetching Examples
Next.js Server Components
// 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>
);
}API Routes
// 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 });
}
}Server Actions
// 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;
}Animation Utilities
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>
);
}Data Models
Player Model
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;
}Game Model
interface Game {
id: string;
name: string;
status?: string;
description?: string;
type?: string;
}TypeScript Support
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,
},
};Styling
Components use Tailwind CSS classes and support custom styling:
<PlayerCard player={player} className="bg-blue-50 border-blue-200" />Performance
- 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
Support
For support, please:
- Visit our main website
- Contact us
- Check our documentation
License
MIT
