UNPKG

@ludiks/react

Version:

Complete React library for Ludiks gamification platform - includes SDK and ready-to-use components

163 lines (162 loc) 16.5 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useUserProfile } from '../../hooks/useUserProfile'; export function UserProfile({ userId, showCircuits = true, showRewards = true, showMetadata = false, showStreak = true, circuitLimit = 5, variant = 'card', orientation = 'vertical', autoRefresh = false, refreshInterval = 30000, className, colors = {}, }) { const { profile, loading, error } = useUserProfile({ userId, autoRefresh, refreshInterval, }); const styles = { primary: colors.primary || '#8b5cf6', secondary: colors.secondary || '#06d6a0', success: colors.success || '#10b981', background: colors.background || '#ffffff', text: colors.text || '#1f2937', }; if (loading) { return (_jsx("div", { style: { padding: '24px', animation: 'fadeIn 0.3s ease-in-out' }, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '16px' }, children: [_jsx("div", { style: { width: '64px', height: '64px', backgroundColor: '#e5e7eb', borderRadius: '50%' } }), _jsxs("div", { style: { flex: 1, display: 'flex', flexDirection: 'column', gap: '8px' }, children: [_jsx("div", { style: { height: '16px', backgroundColor: '#e5e7eb', borderRadius: '4px', width: '75%' } }), _jsx("div", { style: { height: '12px', backgroundColor: '#e5e7eb', borderRadius: '4px', width: '50%' } })] })] }) })); } if (error || !profile) { return (_jsx("div", { style: { padding: '24px', textAlign: 'center', color: '#ef4444' }, children: error || 'Failed to load user profile' })); } const getStatusColor = (status) => { switch (status) { case 'completed': return styles.success; case 'in_progress': return styles.primary; default: return '#9ca3af'; } }; const getStatusIcon = (status) => { switch (status) { case 'completed': return '✅'; case 'in_progress': return '⏳'; default: return '⏸️'; } }; const renderCircuitProgress = (circuit) => { const completedSteps = circuit.stepProgressions.filter(s => s.status === 'completed').length; const totalSteps = circuit.stepProgressions.length; const progressPercentage = totalSteps > 0 ? (completedSteps / totalSteps) * 100 : 0; return (_jsxs("div", { style: { border: '1px solid #e5e7eb', borderRadius: '8px', padding: '16px', marginBottom: '16px', backgroundColor: 'white' }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px' }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '12px' }, children: [_jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '32px', height: '32px', borderRadius: '50%', backgroundColor: getStatusColor(circuit.status), color: 'white', fontSize: '16px' }, children: getStatusIcon(circuit.status) }), _jsxs("div", { children: [_jsx("h4", { style: { fontWeight: '600', color: styles.text, margin: 0 }, children: circuit.name }), _jsxs("p", { style: { fontSize: '14px', color: '#6b7280', margin: '4px 0 0 0', textTransform: 'capitalize' }, children: [circuit.type, " \u2022 ", circuit.status.replace('_', ' ')] })] })] }), _jsxs("div", { style: { textAlign: 'right' }, children: [_jsxs("div", { style: { fontWeight: 'bold', color: styles.primary }, children: [circuit.points, " pts"] }), _jsxs("div", { style: { fontSize: '14px', color: '#6b7280' }, children: [completedSteps, "/", totalSteps, " \u00E9tapes"] })] })] }), _jsxs("div", { style: { marginBottom: '12px' }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', fontSize: '14px', color: '#6b7280', marginBottom: '4px' }, children: [_jsx("span", { children: "Progression" }), _jsxs("span", { children: [Math.round(progressPercentage), "%"] })] }), _jsx("div", { style: { width: '100%', height: '8px', backgroundColor: '#e5e7eb', borderRadius: '4px', overflow: 'hidden' }, children: _jsx("div", { style: { height: '100%', borderRadius: '4px', backgroundColor: getStatusColor(circuit.status), width: `${progressPercentage}%`, transition: 'width 0.3s ease' } }) })] }), circuit.stepProgressions.length > 0 && (_jsxs("div", { children: [circuit.stepProgressions.slice(0, 3).map((step) => (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px', fontSize: '14px', marginBottom: '4px' }, children: [_jsx("div", { style: { width: '16px', height: '16px', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: step.status === 'completed' ? styles.success : '#e5e7eb', color: 'white', fontSize: '10px' }, children: step.status === 'completed' ? '✓' : '○' }), _jsx("span", { style: { color: step.status === 'completed' ? '#6b7280' : styles.text, textDecoration: step.status === 'completed' ? 'line-through' : 'none' }, children: step.name }), _jsxs("span", { style: { marginLeft: 'auto', fontSize: '12px', color: styles.primary }, children: [step.points, " pts"] })] }, step.id))), circuit.stepProgressions.length > 3 && (_jsxs("div", { style: { fontSize: '12px', color: '#9ca3af', textAlign: 'center', marginTop: '8px' }, children: ["+", circuit.stepProgressions.length - 3, " \u00E9tapes suppl\u00E9mentaires"] }))] }))] }, circuit.id)); }; if (variant === 'minimal') { return (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '16px', padding: '16px' }, children: [profile.picture ? (_jsx("img", { src: profile.picture, alt: profile.fullName, style: { width: '48px', height: '48px', borderRadius: '50%', objectFit: 'cover' } })) : (_jsx("div", { style: { width: '48px', height: '48px', borderRadius: '50%', background: `linear-gradient(135deg, ${styles.primary} 0%, ${styles.secondary} 100%)`, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontWeight: 'bold', fontSize: '20px' }, children: profile.fullName.charAt(0) })), _jsxs("div", { children: [_jsx("h3", { style: { fontWeight: '600', color: styles.text, margin: 0 }, children: profile.fullName }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '16px', fontSize: '14px', color: '#6b7280', marginTop: '4px' }, children: [showStreak && (_jsxs("span", { children: ["\uD83D\uDD25 ", profile.currentStreak, " jours de s\u00E9rie"] })), _jsxs("span", { style: { color: styles.primary }, children: [profile.progressions.reduce((sum, c) => sum + c.points, 0), " pts"] })] })] })] })); } const headerContent = (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '16px', marginBottom: '24px' }, children: [profile.picture ? (_jsx("img", { src: profile.picture, alt: profile.fullName, style: { width: '64px', height: '64px', borderRadius: '50%', border: `2px solid ${styles.primary}`, objectFit: 'cover' } })) : (_jsx("div", { style: { width: '64px', height: '64px', borderRadius: '50%', background: `linear-gradient(135deg, ${styles.primary} 0%, ${styles.secondary} 100%)`, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontWeight: 'bold', fontSize: '24px', border: `2px solid ${styles.primary}` }, children: profile.fullName.charAt(0) })), _jsxs("div", { style: { flex: 1 }, children: [_jsx("h2", { style: { fontSize: '20px', fontWeight: 'bold', color: styles.text, margin: 0 }, children: profile.fullName }), profile.email && (_jsx("p", { style: { color: '#6b7280', margin: '4px 0 0 0' }, children: profile.email })), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '24px', marginTop: '8px' }, children: [showStreak && (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [_jsx("span", { style: { color: '#f59e0b' }, children: "\uD83D\uDD25" }), _jsxs("span", { style: { fontWeight: '500' }, children: [profile.currentStreak, " jours"] }), profile.longestStreak > profile.currentStreak && (_jsxs("span", { style: { fontSize: '12px', color: '#9ca3af' }, children: ["(record: ", profile.longestStreak, ")"] }))] })), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [_jsx("span", { style: { color: styles.primary }, children: "\u2B50" }), _jsxs("span", { style: { fontWeight: '500' }, children: [profile.progressions.reduce((sum, c) => sum + c.points, 0), " points"] })] }), showRewards && profile.rewards.length > 0 && (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [_jsx("span", { style: { color: styles.secondary }, children: "\uD83C\uDFC6" }), _jsxs("span", { style: { fontWeight: '500' }, children: [profile.rewards.length, " r\u00E9compenses"] })] }))] })] })] })); if (variant === 'dashboard') { return (_jsxs("div", { style: { display: 'grid', gap: '24px', gridTemplateColumns: orientation === 'horizontal' ? '1fr 1fr' : '1fr' }, children: [_jsxs("div", { children: [headerContent, showMetadata && Object.keys(profile.metadata).length > 0 && (_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsx("h3", { style: { fontWeight: '600', color: '#374151', marginBottom: '12px' }, children: "M\u00E9tadonn\u00E9es" }), _jsx("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '8px', fontSize: '14px' }, children: Object.entries(profile.metadata).map(([key, value]) => (_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [_jsxs("span", { style: { color: '#6b7280' }, children: [key, ":"] }), _jsx("span", { style: { fontWeight: '500' }, children: String(value) })] }, key))) })] }))] }), showCircuits && profile.progressions.length > 0 && (_jsxs("div", { children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '16px' }, children: [_jsx("h3", { style: { fontWeight: '600', color: styles.text }, children: "Progression des circuits" }), _jsxs("span", { style: { fontSize: '14px', color: '#6b7280' }, children: [profile.progressions.slice(0, circuitLimit).length, " sur ", profile.progressions.length] })] }), _jsx("div", { children: profile.progressions.slice(0, circuitLimit).map(renderCircuitProgress) })] }))] })); } // Default: card variant return (_jsxs("div", { style: { borderRadius: '12px', border: '1px solid #e5e7eb', padding: '24px', backgroundColor: styles.background, width: '100%', maxWidth: '600px' }, children: [headerContent, showCircuits && profile.progressions.length > 0 && (_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsx("h3", { style: { fontWeight: '600', fontSize: '18px', color: styles.text, marginBottom: '16px' }, children: "Circuits actifs" }), _jsx("div", { children: profile.progressions.slice(0, circuitLimit).map(renderCircuitProgress) }), profile.progressions.length > circuitLimit && (_jsxs("div", { style: { textAlign: 'center', fontSize: '14px', color: '#6b7280', marginTop: '16px' }, children: ["+", profile.progressions.length - circuitLimit, " circuits suppl\u00E9mentaires"] }))] })), showRewards && profile.rewards.length > 0 && (_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsx("h3", { style: { fontWeight: '600', fontSize: '18px', color: styles.text, marginBottom: '16px' }, children: "R\u00E9compenses r\u00E9centes" }), _jsx("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '12px' }, children: profile.rewards.slice(0, 6).map((reward) => (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '12px', padding: '12px', backgroundColor: '#f9fafb', borderRadius: '8px', border: '1px solid #e5e7eb' }, children: [_jsx("div", { style: { width: '32px', height: '32px', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: styles.secondary, color: 'white', fontSize: '16px' }, children: "\uD83C\uDFC6" }), _jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [_jsx("p", { style: { fontWeight: '500', fontSize: '14px', margin: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, children: reward.name }), _jsx("p", { style: { fontSize: '12px', color: '#6b7280', margin: '4px 0 0 0', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, children: reward.circuitName })] })] }, reward.id))) }), profile.rewards.length > 6 && (_jsxs("div", { style: { textAlign: 'center', fontSize: '14px', color: '#6b7280', marginTop: '16px' }, children: ["+", profile.rewards.length - 6, " r\u00E9compenses suppl\u00E9mentaires"] }))] })), showMetadata && Object.keys(profile.metadata).length > 0 && (_jsxs("div", { children: [_jsx("h3", { style: { fontWeight: '600', fontSize: '18px', color: styles.text, marginBottom: '16px' }, children: "M\u00E9tadonn\u00E9es utilisateur" }), _jsx("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '8px', fontSize: '14px' }, children: Object.entries(profile.metadata).map(([key, value]) => (_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', padding: '8px 12px', backgroundColor: '#f9fafb', borderRadius: '6px', border: '1px solid #e5e7eb' }, children: [_jsxs("span", { style: { color: '#6b7280' }, children: [key, ":"] }), _jsx("span", { style: { fontWeight: '500', color: '#111827' }, children: String(value) })] }, key))) })] }))] })); }