Refactoring - Version OK
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
/// Entité pour les statistiques du dashboard
|
||||
class DashboardStatsEntity extends Equatable {
|
||||
final int totalMembers;
|
||||
final int activeMembers;
|
||||
final int totalEvents;
|
||||
final int upcomingEvents;
|
||||
final int totalContributions;
|
||||
final double totalContributionAmount;
|
||||
final int pendingRequests;
|
||||
final int completedProjects;
|
||||
final double monthlyGrowth;
|
||||
final double engagementRate;
|
||||
final DateTime lastUpdated;
|
||||
|
||||
const DashboardStatsEntity({
|
||||
required this.totalMembers,
|
||||
required this.activeMembers,
|
||||
required this.totalEvents,
|
||||
required this.upcomingEvents,
|
||||
required this.totalContributions,
|
||||
required this.totalContributionAmount,
|
||||
required this.pendingRequests,
|
||||
required this.completedProjects,
|
||||
required this.monthlyGrowth,
|
||||
required this.engagementRate,
|
||||
required this.lastUpdated,
|
||||
});
|
||||
|
||||
// Méthodes utilitaires
|
||||
double get memberActivityRate => totalMembers > 0 ? activeMembers / totalMembers : 0.0;
|
||||
bool get hasGrowth => monthlyGrowth > 0;
|
||||
bool get isHighEngagement => engagementRate > 0.7;
|
||||
|
||||
String get formattedContributionAmount {
|
||||
if (totalContributionAmount >= 1000000) {
|
||||
return '${(totalContributionAmount / 1000000).toStringAsFixed(1)}M';
|
||||
} else if (totalContributionAmount >= 1000) {
|
||||
return '${(totalContributionAmount / 1000).toStringAsFixed(1)}K';
|
||||
}
|
||||
return totalContributionAmount.toStringAsFixed(0);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
totalMembers,
|
||||
activeMembers,
|
||||
totalEvents,
|
||||
upcomingEvents,
|
||||
totalContributions,
|
||||
totalContributionAmount,
|
||||
pendingRequests,
|
||||
completedProjects,
|
||||
monthlyGrowth,
|
||||
engagementRate,
|
||||
lastUpdated,
|
||||
];
|
||||
}
|
||||
|
||||
/// Entité pour les activités récentes
|
||||
class RecentActivityEntity extends Equatable {
|
||||
final String id;
|
||||
final String type;
|
||||
final String title;
|
||||
final String description;
|
||||
final String? userAvatar;
|
||||
final String userName;
|
||||
final DateTime timestamp;
|
||||
final String? actionUrl;
|
||||
final Map<String, dynamic>? metadata;
|
||||
|
||||
const RecentActivityEntity({
|
||||
required this.id,
|
||||
required this.type,
|
||||
required this.title,
|
||||
required this.description,
|
||||
this.userAvatar,
|
||||
required this.userName,
|
||||
required this.timestamp,
|
||||
this.actionUrl,
|
||||
this.metadata,
|
||||
});
|
||||
|
||||
// Méthodes utilitaires
|
||||
String get timeAgo {
|
||||
final now = DateTime.now();
|
||||
final difference = now.difference(timestamp);
|
||||
|
||||
if (difference.inDays > 0) {
|
||||
return '${difference.inDays}j';
|
||||
} else if (difference.inHours > 0) {
|
||||
return '${difference.inHours}h';
|
||||
} else if (difference.inMinutes > 0) {
|
||||
return '${difference.inMinutes}min';
|
||||
} else {
|
||||
return 'maintenant';
|
||||
}
|
||||
}
|
||||
|
||||
bool get isRecent => DateTime.now().difference(timestamp).inHours < 24;
|
||||
bool get hasAction => actionUrl != null && actionUrl!.isNotEmpty;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
type,
|
||||
title,
|
||||
description,
|
||||
userAvatar,
|
||||
userName,
|
||||
timestamp,
|
||||
actionUrl,
|
||||
metadata,
|
||||
];
|
||||
}
|
||||
|
||||
/// Entité pour les événements à venir
|
||||
class UpcomingEventEntity extends Equatable {
|
||||
final String id;
|
||||
final String title;
|
||||
final String description;
|
||||
final DateTime startDate;
|
||||
final DateTime? endDate;
|
||||
final String location;
|
||||
final int maxParticipants;
|
||||
final int currentParticipants;
|
||||
final String status;
|
||||
final String? imageUrl;
|
||||
final List<String> tags;
|
||||
|
||||
const UpcomingEventEntity({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.description,
|
||||
required this.startDate,
|
||||
this.endDate,
|
||||
required this.location,
|
||||
required this.maxParticipants,
|
||||
required this.currentParticipants,
|
||||
required this.status,
|
||||
this.imageUrl,
|
||||
required this.tags,
|
||||
});
|
||||
|
||||
// Méthodes utilitaires
|
||||
bool get isAlmostFull => currentParticipants >= (maxParticipants * 0.8);
|
||||
bool get isFull => currentParticipants >= maxParticipants;
|
||||
double get fillPercentage => maxParticipants > 0 ? currentParticipants / maxParticipants : 0.0;
|
||||
|
||||
String get daysUntilEvent {
|
||||
final now = DateTime.now();
|
||||
final difference = startDate.difference(now);
|
||||
|
||||
if (difference.inDays > 0) {
|
||||
return '${difference.inDays} jour${difference.inDays > 1 ? 's' : ''}';
|
||||
} else if (difference.inHours > 0) {
|
||||
return '${difference.inHours}h';
|
||||
} else if (difference.inMinutes > 0) {
|
||||
return '${difference.inMinutes}min';
|
||||
} else {
|
||||
return 'En cours';
|
||||
}
|
||||
}
|
||||
|
||||
bool get isToday {
|
||||
final now = DateTime.now();
|
||||
return startDate.year == now.year &&
|
||||
startDate.month == now.month &&
|
||||
startDate.day == now.day;
|
||||
}
|
||||
|
||||
bool get isTomorrow {
|
||||
final tomorrow = DateTime.now().add(const Duration(days: 1));
|
||||
return startDate.year == tomorrow.year &&
|
||||
startDate.month == tomorrow.month &&
|
||||
startDate.day == tomorrow.day;
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
startDate,
|
||||
endDate,
|
||||
location,
|
||||
maxParticipants,
|
||||
currentParticipants,
|
||||
status,
|
||||
imageUrl,
|
||||
tags,
|
||||
];
|
||||
}
|
||||
|
||||
/// Entité principale du dashboard
|
||||
class DashboardEntity extends Equatable {
|
||||
final DashboardStatsEntity stats;
|
||||
final List<RecentActivityEntity> recentActivities;
|
||||
final List<UpcomingEventEntity> upcomingEvents;
|
||||
final Map<String, dynamic> userPreferences;
|
||||
final String organizationId;
|
||||
final String userId;
|
||||
|
||||
const DashboardEntity({
|
||||
required this.stats,
|
||||
required this.recentActivities,
|
||||
required this.upcomingEvents,
|
||||
required this.userPreferences,
|
||||
required this.organizationId,
|
||||
required this.userId,
|
||||
});
|
||||
|
||||
// Méthodes utilitaires
|
||||
bool get hasRecentActivity => recentActivities.isNotEmpty;
|
||||
bool get hasUpcomingEvents => upcomingEvents.isNotEmpty;
|
||||
int get todayEventsCount => upcomingEvents.where((e) => e.isToday).length;
|
||||
int get tomorrowEventsCount => upcomingEvents.where((e) => e.isTomorrow).length;
|
||||
int get recentActivitiesCount => recentActivities.length;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
stats,
|
||||
recentActivities,
|
||||
upcomingEvents,
|
||||
userPreferences,
|
||||
organizationId,
|
||||
userId,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import '../entities/dashboard_entity.dart';
|
||||
import '../../../../core/error/failures.dart';
|
||||
|
||||
abstract class DashboardRepository {
|
||||
Future<Either<Failure, DashboardEntity>> getDashboardData(
|
||||
String organizationId,
|
||||
String userId,
|
||||
);
|
||||
|
||||
Future<Either<Failure, DashboardStatsEntity>> getDashboardStats(
|
||||
String organizationId,
|
||||
String userId,
|
||||
);
|
||||
|
||||
Future<Either<Failure, List<RecentActivityEntity>>> getRecentActivities(
|
||||
String organizationId,
|
||||
String userId, {
|
||||
int limit = 10,
|
||||
});
|
||||
|
||||
Future<Either<Failure, List<UpcomingEventEntity>>> getUpcomingEvents(
|
||||
String organizationId,
|
||||
String userId, {
|
||||
int limit = 5,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import '../entities/dashboard_entity.dart';
|
||||
import '../repositories/dashboard_repository.dart';
|
||||
import '../../../../core/error/failures.dart';
|
||||
import '../../../../core/usecases/usecase.dart';
|
||||
|
||||
class GetDashboardData implements UseCase<DashboardEntity, GetDashboardDataParams> {
|
||||
final DashboardRepository repository;
|
||||
|
||||
GetDashboardData(this.repository);
|
||||
|
||||
@override
|
||||
Future<Either<Failure, DashboardEntity>> call(GetDashboardDataParams params) async {
|
||||
return await repository.getDashboardData(
|
||||
params.organizationId,
|
||||
params.userId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GetDashboardDataParams extends Equatable {
|
||||
final String organizationId;
|
||||
final String userId;
|
||||
|
||||
const GetDashboardDataParams({
|
||||
required this.organizationId,
|
||||
required this.userId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [organizationId, userId];
|
||||
}
|
||||
|
||||
class GetDashboardStats implements UseCase<DashboardStatsEntity, GetDashboardStatsParams> {
|
||||
final DashboardRepository repository;
|
||||
|
||||
GetDashboardStats(this.repository);
|
||||
|
||||
@override
|
||||
Future<Either<Failure, DashboardStatsEntity>> call(GetDashboardStatsParams params) async {
|
||||
return await repository.getDashboardStats(
|
||||
params.organizationId,
|
||||
params.userId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GetDashboardStatsParams extends Equatable {
|
||||
final String organizationId;
|
||||
final String userId;
|
||||
|
||||
const GetDashboardStatsParams({
|
||||
required this.organizationId,
|
||||
required this.userId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [organizationId, userId];
|
||||
}
|
||||
|
||||
class GetRecentActivities implements UseCase<List<RecentActivityEntity>, GetRecentActivitiesParams> {
|
||||
final DashboardRepository repository;
|
||||
|
||||
GetRecentActivities(this.repository);
|
||||
|
||||
@override
|
||||
Future<Either<Failure, List<RecentActivityEntity>>> call(GetRecentActivitiesParams params) async {
|
||||
return await repository.getRecentActivities(
|
||||
params.organizationId,
|
||||
params.userId,
|
||||
limit: params.limit,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GetRecentActivitiesParams extends Equatable {
|
||||
final String organizationId;
|
||||
final String userId;
|
||||
final int limit;
|
||||
|
||||
const GetRecentActivitiesParams({
|
||||
required this.organizationId,
|
||||
required this.userId,
|
||||
this.limit = 10,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [organizationId, userId, limit];
|
||||
}
|
||||
|
||||
class GetUpcomingEvents implements UseCase<List<UpcomingEventEntity>, GetUpcomingEventsParams> {
|
||||
final DashboardRepository repository;
|
||||
|
||||
GetUpcomingEvents(this.repository);
|
||||
|
||||
@override
|
||||
Future<Either<Failure, List<UpcomingEventEntity>>> call(GetUpcomingEventsParams params) async {
|
||||
return await repository.getUpcomingEvents(
|
||||
params.organizationId,
|
||||
params.userId,
|
||||
limit: params.limit,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GetUpcomingEventsParams extends Equatable {
|
||||
final String organizationId;
|
||||
final String userId;
|
||||
final int limit;
|
||||
|
||||
const GetUpcomingEventsParams({
|
||||
required this.organizationId,
|
||||
required this.userId,
|
||||
this.limit = 5,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [organizationId, userId, limit];
|
||||
}
|
||||
Reference in New Issue
Block a user