Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 138 additions & 84 deletions README.md

Large diffs are not rendered by default.

30 changes: 27 additions & 3 deletions analytics/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Analytics System

A comprehensive analytics system for tracking platform performance, user engagement, and mandatory feedback statistics.
A comprehensive analytics system for tracking platform performance, user
engagement, and mandatory feedback statistics.

## Overview

The analytics system provides insights into:

- Platform-wide statistics and performance metrics
- User account analytics and engagement tracking
- Mandatory feedback analysis and trends
Expand All @@ -29,6 +31,7 @@ The analytics system provides insights into:
### Types

Comprehensive TypeScript interfaces for:

- Platform statistics
- Account analytics
- Feedback analytics
Expand All @@ -38,27 +41,31 @@ Comprehensive TypeScript interfaces for:
## Features

### Platform Analytics

- Total users and accounts
- Demo completion statistics
- Badge and points tracking
- User engagement metrics
- Performance indicators

### Account Analytics

- User account management
- Engagement scoring
- Activity tracking
- Sorting and filtering
- Search functionality

### Feedback Analytics

- Rating distribution
- Difficulty analysis
- Demo-specific feedback
- Recent feedback display
- Recommendation rates

### Navigation

- Tabbed interface
- Responsive design
- Mobile-friendly navigation
Expand All @@ -67,16 +74,19 @@ Comprehensive TypeScript interfaces for:
## Usage

### Accessing Analytics

Navigate to `/analytics` or click the "Analytics" link in the header navigation.

### Dashboard Views

- **Overview** - Platform-wide statistics
- **Users** - Account analytics and management
- **Feedback** - Mandatory feedback analysis
- **Demos** - Demo performance metrics (coming soon)
- **Engagement** - User engagement insights (coming soon)

### Data Sources

- Firebase Firestore collections
- Mandatory feedback collection
- Account data
Expand All @@ -86,18 +96,21 @@ Navigate to `/analytics` or click the "Analytics" link in the header navigation.
## Implementation Details

### Data Flow

1. Analytics components request data from AnalyticsService
2. AnalyticsService aggregates data from multiple Firebase services
3. Data is processed and formatted for display
4. Components render analytics with loading and error states

### Performance Considerations

- Lazy loading of analytics data
- Efficient data aggregation
- Caching strategies (future enhancement)
- Pagination for large datasets

### Security

- User authentication required
- Admin-level access for sensitive analytics
- Data privacy compliance
Expand All @@ -106,6 +119,7 @@ Navigate to `/analytics` or click the "Analytics" link in the header navigation.
## Future Enhancements

### Planned Features

- Real-time analytics updates
- Advanced filtering and search
- Export functionality
Expand All @@ -114,6 +128,7 @@ Navigate to `/analytics` or click the "Analytics" link in the header navigation.
- Automated reporting

### Technical Improvements

- Data caching
- Performance optimization
- Error handling improvements
Expand Down Expand Up @@ -171,9 +186,12 @@ interface FeedbackAnalyticsProps {
## Configuration

### Environment Variables
No additional environment variables required. Uses existing Firebase configuration.

No additional environment variables required. Uses existing Firebase
configuration.

### Dependencies

- React 18+
- TypeScript
- Firebase SDK
Expand All @@ -182,28 +200,34 @@ No additional environment variables required. Uses existing Firebase configurati
## Troubleshooting

### Common Issues

1. **No data displayed** - Check Firebase connection and permissions
2. **Slow loading** - Consider implementing data caching
3. **Permission errors** - Verify user authentication and admin access

### Debug Mode
Enable debug logging by setting `localStorage.setItem('analytics-debug', 'true')` in browser console.

Enable debug logging by setting
`localStorage.setItem('analytics-debug', 'true')` in browser console.

## Contributing

### Development Setup

1. Ensure Firebase is properly configured
2. Install dependencies: `npm install`
3. Start development server: `npm run dev`
4. Navigate to `/analytics` to test

### Code Style

- Follow existing TypeScript conventions
- Use Tailwind CSS for styling
- Implement proper error handling
- Add loading states for async operations

### Testing

- Test with different user roles
- Verify responsive design
- Check data accuracy
Expand Down
20 changes: 12 additions & 8 deletions analytics/components/AccountAnalytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,29 @@ export const AccountAnalytics: React.FC<AccountAnalyticsProps> = ({ className =
const getThemeClasses = () => {
if (theme === 'light') {
return {
container: 'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 text-gray-800 backdrop-blur-sm rounded-2xl shadow-2xl',
container:
'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 text-gray-800 backdrop-blur-sm rounded-2xl shadow-2xl',
card: 'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 hover:from-gray-50 hover:to-gray-100 backdrop-blur-sm rounded-xl shadow-lg',
text: 'text-gray-800',
textSecondary: 'text-gray-600',
textMuted: 'text-gray-500',
input: 'bg-white border-gray-300 text-gray-800 placeholder-gray-500',
select: 'bg-white border-gray-300 text-gray-800',
statsCard: 'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 backdrop-blur-sm rounded-xl shadow-lg',
statsCard:
'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 backdrop-blur-sm rounded-xl shadow-lg',
};
} else {
return {
container: 'bg-gradient-to-br from-slate-900 to-slate-800 border-white/20 text-white backdrop-blur-sm rounded-2xl shadow-2xl',
container:
'bg-gradient-to-br from-slate-900 to-slate-800 border-white/20 text-white backdrop-blur-sm rounded-2xl shadow-2xl',
card: 'bg-gradient-to-br from-slate-800/60 to-slate-900/60 border-white/20 hover:from-slate-700/60 hover:to-slate-800/60 backdrop-blur-sm rounded-xl shadow-lg',
text: 'text-white',
textSecondary: 'text-gray-300',
textMuted: 'text-gray-400',
input: 'bg-white/5 border-white/20 text-white placeholder-gray-400',
select: 'bg-white/5 border-white/20 text-white',
statsCard: 'bg-gradient-to-br from-slate-800/60 to-slate-900/60 border-white/20 backdrop-blur-sm rounded-xl shadow-lg',
statsCard:
'bg-gradient-to-br from-slate-800/60 to-slate-900/60 border-white/20 backdrop-blur-sm rounded-xl shadow-lg',
};
}
};
Expand Down Expand Up @@ -203,23 +207,23 @@ export const AccountAnalytics: React.FC<AccountAnalyticsProps> = ({ className =

{/* Summary Stats */}
<div className='grid grid-cols-2 md:grid-cols-4 gap-4 mb-6'>
<div className={`p-3 ${themeClasses.statsCard}`}>
<div className={`p-3 ${themeClasses.statsCard}`}>
<p className={`text-2xl font-bold ${themeClasses.text}`}>{accounts.length}</p>
<p className={`text-sm ${themeClasses.textSecondary}`}>Total Users</p>
</div>
<div className={`p-3 ${themeClasses.statsCard}`}>
<div className={`p-3 ${themeClasses.statsCard}`}>
<p className='text-2xl font-bold text-green-600'>
{accounts.filter(a => a.isActive).length}
</p>
<p className={`text-sm ${themeClasses.textSecondary}`}>Active Users</p>
</div>
<div className={`p-3 ${themeClasses.statsCard}`}>
<div className={`p-3 ${themeClasses.statsCard}`}>
<p className='text-2xl font-bold text-blue-600'>
{accounts.reduce((sum, a) => sum + a.totalPoints, 0).toLocaleString()}
</p>
<p className={`text-sm ${themeClasses.textSecondary}`}>Total Points</p>
</div>
<div className={`p-3 ${themeClasses.statsCard}`}>
<div className={`p-3 ${themeClasses.statsCard}`}>
<p className='text-2xl font-bold text-purple-600'>
{accounts.reduce((sum, a) => sum + a.demosCompleted.length, 0)}
</p>
Expand Down
13 changes: 9 additions & 4 deletions analytics/components/AnalyticsDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ export const AnalyticsDashboard: React.FC<AnalyticsDashboardProps> = ({ classNam
<div className={themeClasses.headerContainer}>
<div className='flex items-center justify-between'>
<div>
<div className='flex items-center space-x-2 cursor-pointer' onClick={() => router.push('/')}>
<div
className='flex items-center space-x-2 cursor-pointer'
onClick={() => router.push('/')}
>
<Image src='/images/logo/logoicon.png' alt='Nexus Logo' width={100} height={100} />
<Image src='/images/logo/iconletter.png' alt='Nexus Logo' width={100} height={100} />
</div>
Expand Down Expand Up @@ -129,9 +132,11 @@ export const AnalyticsDashboard: React.FC<AnalyticsDashboardProps> = ({ classNam
<span className='mr-2'>{view.icon}</span>
{view.label}
{view.comingSoon && (
<div className={`absolute -top-2 -right-2 bg-gradient-to-r from-orange-400 to-red-500 text-white text-xs font-bold px-2 py-1 rounded-full border-2 ${
theme === 'light' ? 'border-white' : 'border-gray-900'
} animate-pulse shadow-lg`}>
<div
className={`absolute -top-2 -right-2 bg-gradient-to-r from-orange-400 to-red-500 text-white text-xs font-bold px-2 py-1 rounded-full border-2 ${
theme === 'light' ? 'border-white' : 'border-gray-900'
} animate-pulse shadow-lg`}
>
Soon
</div>
)}
Expand Down
27 changes: 14 additions & 13 deletions analytics/components/FeedbackAnalytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ export const FeedbackAnalytics: React.FC<FeedbackAnalyticsProps> = ({ className
const getThemeClasses = () => {
if (theme === 'light') {
return {
container: 'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 text-gray-800 backdrop-blur-sm rounded-2xl shadow-2xl',
container:
'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 text-gray-800 backdrop-blur-sm rounded-2xl shadow-2xl',
card: 'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 hover:from-gray-50 hover:to-gray-100 backdrop-blur-sm rounded-xl shadow-lg',
text: 'text-gray-800',
textSecondary: 'text-gray-600',
textMuted: 'text-gray-500',
};
} else {
return {
container: 'bg-gradient-to-br from-slate-900 to-slate-800 border-white/20 text-white backdrop-blur-sm rounded-2xl shadow-2xl',
container:
'bg-gradient-to-br from-slate-900 to-slate-800 border-white/20 text-white backdrop-blur-sm rounded-2xl shadow-2xl',
card: 'bg-gradient-to-br from-slate-800/60 to-slate-900/60 border-white/20 hover:from-slate-700/60 hover:to-slate-800/60 backdrop-blur-sm rounded-xl shadow-lg',
text: 'text-white',
textSecondary: 'text-gray-300',
Expand Down Expand Up @@ -105,7 +107,7 @@ export const FeedbackAnalytics: React.FC<FeedbackAnalyticsProps> = ({ className
return (
<div className={`space-y-6 ${className}`}>
{/* Overview Stats */}
<div className={`p-6 ${themeClasses.container}`}>
<div className={`p-6 ${themeClasses.container}`}>
<h2 className={`text-xl font-semibold ${themeClasses.text} mb-6`}>Feedback Overview</h2>

<div className='grid grid-cols-2 md:grid-cols-4 gap-4'>
Expand Down Expand Up @@ -141,7 +143,7 @@ export const FeedbackAnalytics: React.FC<FeedbackAnalyticsProps> = ({ className
</div>

{/* Rating Distribution */}
<div className={`p-6 ${themeClasses.container}`}>
<div className={`p-6 ${themeClasses.container}`}>
<h2 className={`text-xl font-semibold ${themeClasses.text} mb-6`}>Rating Distribution</h2>

<div className='space-y-3'>
Expand Down Expand Up @@ -178,7 +180,7 @@ export const FeedbackAnalytics: React.FC<FeedbackAnalyticsProps> = ({ className
</div>

{/* Difficulty Distribution */}
<div className={`p-6 ${themeClasses.container}`}>
<div className={`p-6 ${themeClasses.container}`}>
<h2 className={`text-xl font-semibold ${themeClasses.text} mb-6`}>
Difficulty Distribution
</h2>
Expand All @@ -195,10 +197,7 @@ export const FeedbackAnalytics: React.FC<FeedbackAnalyticsProps> = ({ className
};

return (
<div
key={difficulty}
className={`p-4 ${themeClasses.card}`}
>
<div key={difficulty} className={`p-4 ${themeClasses.card}`}>
<div className='text-center'>
<p className={`text-2xl font-bold ${themeClasses.text}`}>{count}</p>
<p className={`text-sm ${themeClasses.textMuted} capitalize`}>{difficulty}</p>
Expand All @@ -221,7 +220,7 @@ export const FeedbackAnalytics: React.FC<FeedbackAnalyticsProps> = ({ className
</div>

{/* Feedback by Demo */}
<div className={`p-6 ${themeClasses.container}`}>
<div className={`p-6 ${themeClasses.container}`}>
<h2 className={`text-xl font-semibold ${themeClasses.text} mb-6`}>Feedback by Demo</h2>

<div className='space-y-4'>
Expand Down Expand Up @@ -267,7 +266,7 @@ export const FeedbackAnalytics: React.FC<FeedbackAnalyticsProps> = ({ className
</div>

{/* Recent Feedback */}
<div className={`p-6 ${themeClasses.container}`}>
<div className={`p-6 ${themeClasses.container}`}>
<h2 className={`text-xl font-semibold ${themeClasses.text} mb-6`}>Recent Feedback</h2>

<div className='space-y-3'>
Expand Down Expand Up @@ -339,12 +338,14 @@ const StatCard: React.FC<StatCardProps> = ({ title, value, icon, color, theme })
const themeClasses =
theme === 'light'
? {
container: 'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 hover:from-gray-50 hover:to-gray-100 backdrop-blur-sm rounded-xl shadow-lg',
container:
'bg-gradient-to-br from-white to-gray-50 border-gray-200/50 hover:from-gray-50 hover:to-gray-100 backdrop-blur-sm rounded-xl shadow-lg',
text: 'text-gray-800',
textSecondary: 'text-gray-600',
}
: {
container: 'bg-gradient-to-br from-slate-800/60 to-slate-900/60 border-white/20 hover:from-slate-700/60 hover:to-slate-800/60 backdrop-blur-sm rounded-xl shadow-lg',
container:
'bg-gradient-to-br from-slate-800/60 to-slate-900/60 border-white/20 hover:from-slate-700/60 hover:to-slate-800/60 backdrop-blur-sm rounded-xl shadow-lg',
text: 'text-white',
textSecondary: 'text-gray-300',
};
Expand Down
7 changes: 4 additions & 3 deletions analytics/components/PlatformAnalytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ export const PlatformAnalytics: React.FC<PlatformAnalyticsProps> = ({ className
};
} else {
return {
container: 'p-6 bg-gradient-to-br from-slate-900 to-slate-800 backdrop-blur-sm rounded-2xl border border-white/20 shadow-2xl',
container:
'p-6 bg-gradient-to-br from-slate-900 to-slate-800 backdrop-blur-sm rounded-2xl border border-white/20 shadow-2xl',
card: 'p-4 bg-gradient-to-br from-slate-800/60 to-slate-900/60 backdrop-blur-sm rounded-xl border border-white/20 hover:from-slate-700/60 hover:to-slate-800/60 shadow-lg',
text: 'text-white',
textSecondary: 'text-gray-300',
Expand Down Expand Up @@ -342,8 +343,8 @@ export const PlatformAnalytics: React.FC<PlatformAnalyticsProps> = ({ className
</div>
<div className='text-right'>
<p className={`${themeClasses.text} font-medium`}>
{user.totalPoints.toLocaleString()} pts /
{(user.experience || 0).toLocaleString()} XP
{user.totalPoints.toLocaleString()} pts /{(user.experience || 0).toLocaleString()}{' '}
XP
</p>
<p className={`${themeClasses.textMuted} text-sm`}>
{user.demosCompleted} demos, {user.badgesEarned} badges
Expand Down
Loading
Loading