@ludiks/react
Version:
Complete React library for Ludiks gamification platform - includes SDK and ready-to-use components
45 lines (44 loc) • 5.11 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useUserProfile } from '../../hooks/useUserProfile';
import { cn } from '../../utils/cn';
export function StreakCounter({ userId, showRecord = true, variant = 'detailed', animate = true, size = 'md', autoRefresh = false, refreshInterval = 30000, className, colors = {}, }) {
const { profile, loading, error } = useUserProfile({
userId,
autoRefresh,
refreshInterval,
});
const styles = {
flame: colors.primary || '#ff6b35',
background: colors.background || '#ffffff',
text: colors.text || '#1f2937',
};
const sizeClasses = {
sm: 'text-sm',
md: 'text-base',
lg: 'text-lg',
};
const flameSizes = {
sm: 'w-6 h-6',
md: 'w-8 h-8',
lg: 'w-12 h-12',
};
if (loading) {
return (_jsx("div", { className: cn('animate-pulse', sizeClasses[size], className), children: _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx("div", { className: cn('bg-gray-200 rounded', flameSizes[size]) }), _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-4 bg-gray-200 rounded w-16" }), showRecord && _jsx("div", { className: "h-3 bg-gray-200 rounded w-12" })] })] }) }));
}
if (error || !profile) {
return (_jsx("div", { className: cn('text-red-500', sizeClasses[size], className), children: "Error loading streak data" }));
}
const FlameIcon = ({ size: iconSize }) => (_jsx("svg", { className: cn(flameSizes[iconSize], animate && 'animate-pulse'), fill: "currentColor", style: { color: styles.flame }, viewBox: "0 0 24 24", children: _jsx("path", { d: "M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.28 2.92-.73 4.22C14.17 15.73 13.06 19 11.71 19z" }) }));
const CalendarIcon = ({ size: iconSize }) => (_jsxs("svg", { className: cn(flameSizes[iconSize]), fill: "none", stroke: "currentColor", strokeWidth: 2, style: { color: styles.flame }, viewBox: "0 0 24 24", children: [_jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2", ry: "2" }), _jsx("line", { x1: "16", y1: "2", x2: "16", y2: "6" }), _jsx("line", { x1: "8", y1: "2", x2: "8", y2: "6" }), _jsx("line", { x1: "3", y1: "10", x2: "21", y2: "10" }), _jsx("path", { d: "m9 16 2 2 4-4" })] }));
if (variant === 'minimal') {
return (_jsxs("div", { className: cn('flex items-center space-x-2', sizeClasses[size], className), children: [_jsx(FlameIcon, { size: size }), _jsx("span", { className: "font-bold", style: { color: styles.text }, children: profile.currentStreak })] }));
}
if (variant === 'calendar') {
return (_jsxs("div", { className: cn('flex items-center space-x-3 p-3 rounded-lg border', sizeClasses[size], className), style: { backgroundColor: styles.background }, children: [_jsx(CalendarIcon, { size: size }), _jsxs("div", { children: [_jsxs("div", { className: "font-bold", style: { color: styles.text }, children: [profile.currentStreak, " day", profile.currentStreak !== 1 ? 's' : ''] }), showRecord && profile.longestStreak > profile.currentStreak && (_jsxs("div", { className: "text-sm text-gray-500", children: ["Record: ", profile.longestStreak, " days"] }))] })] }));
}
if (variant === 'flame') {
return (_jsxs("div", { className: cn('flex flex-col items-center space-y-2', sizeClasses[size], className), children: [_jsx(FlameIcon, { size: size }), _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "font-bold", style: { color: styles.text }, children: profile.currentStreak }), _jsx("div", { className: "text-sm text-gray-500", children: "day streak" }), showRecord && profile.longestStreak > profile.currentStreak && (_jsxs("div", { className: "text-xs text-gray-400 mt-1", children: ["Record: ", profile.longestStreak] }))] })] }));
}
// Default: detailed variant
return (_jsxs("div", { className: cn('flex items-center space-x-3 p-4 rounded-lg border', sizeClasses[size], className), style: { backgroundColor: styles.background }, children: [_jsx("div", { className: "flex-shrink-0", children: _jsx(FlameIcon, { size: size }) }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-baseline space-x-2", children: [_jsx("span", { className: "text-2xl font-bold", style: { color: styles.text }, children: profile.currentStreak }), _jsxs("span", { className: "text-sm text-gray-500", children: ["day", profile.currentStreak !== 1 ? 's' : '', " streak"] })] }), showRecord && (_jsx("div", { className: "mt-1", children: profile.longestStreak === profile.currentStreak ? (_jsx("div", { className: "text-sm font-medium", style: { color: styles.flame }, children: "\uD83C\uDFC6 Personal best!" })) : (_jsxs("div", { className: "text-sm text-gray-500", children: ["Record: ", profile.longestStreak, " days"] })) }))] })] }));
}