From 782611c79e69838734bd9aaf2a0e4d31f1c71dcc Mon Sep 17 00:00:00 2001 From: WojciechMat Date: Mon, 16 Jun 2025 14:04:39 +0200 Subject: [PATCH] Remove organizer stats page --- .../common_widgets/adaptive_navigation.dart | 12 --- .../cubit/organizer_stats_cubit.dart | 47 ---------- .../cubit/organizer_stats_state.dart | 39 -------- .../organizer/pages/organizer_stats_page.dart | 90 ------------------- .../organizer/widgets/quick_actions.dart | 13 +-- .../organizer/widgets/stats_summary_card.dart | 47 ---------- 6 files changed, 1 insertion(+), 247 deletions(-) delete mode 100644 frontend/lib/presentation/organizer/cubit/organizer_stats_cubit.dart delete mode 100644 frontend/lib/presentation/organizer/cubit/organizer_stats_state.dart delete mode 100644 frontend/lib/presentation/organizer/pages/organizer_stats_page.dart delete mode 100644 frontend/lib/presentation/organizer/widgets/stats_summary_card.dart diff --git a/frontend/lib/presentation/common_widgets/adaptive_navigation.dart b/frontend/lib/presentation/common_widgets/adaptive_navigation.dart index ea7d201..535fb9e 100644 --- a/frontend/lib/presentation/common_widgets/adaptive_navigation.dart +++ b/frontend/lib/presentation/common_widgets/adaptive_navigation.dart @@ -9,7 +9,6 @@ import 'package:resellio/presentation/profile/pages/profile_page.dart'; import 'package:resellio/presentation/organizer/pages/organizer_dashboard_page.dart'; import 'package:resellio/presentation/admin/pages/admin_dashboard_page.dart'; import 'package:resellio/presentation/organizer/pages/organizer_events_page.dart'; -import 'package:resellio/presentation/organizer/pages/organizer_stats_page.dart'; import 'package:resellio/core/models/user_model.dart'; class AdaptiveNavigation extends StatefulWidget { @@ -42,7 +41,6 @@ class _AdaptiveNavigationState extends State { return [ const OrganizerDashboardPage(), const OrganizerEventsPage(), - const OrganizerStatsPage(), const ProfilePage(), ]; case UserRole.admin: @@ -92,11 +90,6 @@ class _AdaptiveNavigationState extends State { selectedIcon: Icon(Icons.event_note), label: 'My Events', ), - NavigationDestination( - icon: Icon(Icons.bar_chart_outlined), - selectedIcon: Icon(Icons.bar_chart), - label: 'Statistics', - ), NavigationDestination( icon: Icon(Icons.person_outline), selectedIcon: Icon(Icons.person), @@ -166,11 +159,6 @@ class _AdaptiveNavigationState extends State { selectedIcon: Icon(Icons.event_note), label: Text('My Events'), ), - NavigationRailDestination( - icon: Icon(Icons.bar_chart_outlined), - selectedIcon: Icon(Icons.bar_chart), - label: Text('Statistics'), - ), NavigationRailDestination( icon: Icon(Icons.person_outline), selectedIcon: Icon(Icons.person), diff --git a/frontend/lib/presentation/organizer/cubit/organizer_stats_cubit.dart b/frontend/lib/presentation/organizer/cubit/organizer_stats_cubit.dart deleted file mode 100644 index 6c45ab0..0000000 --- a/frontend/lib/presentation/organizer/cubit/organizer_stats_cubit.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:resellio/core/models/user_model.dart'; -import 'package:resellio/core/network/api_exception.dart'; -import 'package:resellio/core/repositories/event_repository.dart'; -import 'package:resellio/core/services/auth_service.dart'; -import 'package:resellio/presentation/organizer/cubit/organizer_stats_state.dart'; - -class OrganizerStatsCubit extends Cubit { - final EventRepository _eventRepository; - final AuthService _authService; - - OrganizerStatsCubit(this._eventRepository, this._authService) - : super(OrganizerStatsInitial()); - - Future loadStatistics() async { - try { - emit(OrganizerStatsLoading()); - - final profile = _authService.detailedProfile; - if (profile is! OrganizerProfile) { - emit(const OrganizerStatsError("User is not a valid organizer.")); - return; - } - - final events = - await _eventRepository.getOrganizerEvents(profile.organizerId); - - final totalEvents = events.length; - final activeEvents = - events.where((e) => e.status.toLowerCase() == 'created').length; - final pendingEvents = - events.where((e) => e.status.toLowerCase() == 'pending').length; - final totalTickets = events.fold(0, (sum, e) => sum + e.totalTickets); - - emit(OrganizerStatsLoaded( - totalEvents: totalEvents, - activeEvents: activeEvents, - pendingEvents: pendingEvents, - totalTickets: totalTickets, - )); - } on ApiException catch (e) { - emit(OrganizerStatsError(e.message)); - } catch (e) { - emit(OrganizerStatsError("An unexpected error occurred: $e")); - } - } -} diff --git a/frontend/lib/presentation/organizer/cubit/organizer_stats_state.dart b/frontend/lib/presentation/organizer/cubit/organizer_stats_state.dart deleted file mode 100644 index b665a8e..0000000 --- a/frontend/lib/presentation/organizer/cubit/organizer_stats_state.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:equatable/equatable.dart'; - -abstract class OrganizerStatsState extends Equatable { - const OrganizerStatsState(); - - @override - List get props => []; -} - -class OrganizerStatsInitial extends OrganizerStatsState {} - -class OrganizerStatsLoading extends OrganizerStatsState {} - -class OrganizerStatsLoaded extends OrganizerStatsState { - final int totalEvents; - final int activeEvents; - final int pendingEvents; - final int totalTickets; - - const OrganizerStatsLoaded({ - required this.totalEvents, - required this.activeEvents, - required this.pendingEvents, - required this.totalTickets, - }); - - @override - List get props => - [totalEvents, activeEvents, pendingEvents, totalTickets]; -} - -class OrganizerStatsError extends OrganizerStatsState { - final String message; - - const OrganizerStatsError(this.message); - - @override - List get props => [message]; -} diff --git a/frontend/lib/presentation/organizer/pages/organizer_stats_page.dart b/frontend/lib/presentation/organizer/pages/organizer_stats_page.dart deleted file mode 100644 index db58b33..0000000 --- a/frontend/lib/presentation/organizer/pages/organizer_stats_page.dart +++ /dev/null @@ -1,90 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:resellio/core/repositories/repositories.dart'; -import 'package:resellio/core/services/auth_service.dart'; -import 'package:resellio/presentation/common_widgets/bloc_state_wrapper.dart'; -import 'package:resellio/presentation/main_page/page_layout.dart'; -import 'package:resellio/presentation/organizer/cubit/organizer_stats_cubit.dart'; -import 'package:resellio/presentation/organizer/cubit/organizer_stats_state.dart'; -import 'package:resellio/presentation/organizer/widgets/stats_summary_card.dart'; - -class OrganizerStatsPage extends StatelessWidget { - const OrganizerStatsPage({super.key}); - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => OrganizerStatsCubit( - context.read(), - context.read(), - )..loadStatistics(), - child: const _OrganizerStatsView(), - ); - } -} - -class _OrganizerStatsView extends StatelessWidget { - const _OrganizerStatsView(); - - @override - Widget build(BuildContext context) { - return PageLayout( - title: 'Statistics', - showCartButton: false, - actions: [ - IconButton( - icon: const Icon(Icons.refresh), - tooltip: 'Refresh Statistics', - onPressed: () => context.read().loadStatistics(), - ), - ], - body: RefreshIndicator( - onRefresh: () => context.read().loadStatistics(), - child: BlocBuilder( - builder: (context, state) { - return BlocStateWrapper( - state: state, - onRetry: () => - context.read().loadStatistics(), - builder: (loadedState) { - return GridView.count( - padding: const EdgeInsets.all(16), - crossAxisCount: 2, - crossAxisSpacing: 16, - mainAxisSpacing: 16, - childAspectRatio: 1.5, - children: [ - StatsSummaryCard( - title: 'Total Events', - value: loadedState.totalEvents.toString(), - icon: Icons.event, - color: Colors.blue, - ), - StatsSummaryCard( - title: 'Active Events', - value: loadedState.activeEvents.toString(), - icon: Icons.event_available, - color: Colors.green, - ), - StatsSummaryCard( - title: 'Pending Approval', - value: loadedState.pendingEvents.toString(), - icon: Icons.pending, - color: Colors.orange, - ), - StatsSummaryCard( - title: 'Total Tickets', - value: loadedState.totalTickets.toString(), - icon: Icons.confirmation_number, - color: Colors.purple, - ), - ], - ); - }, - ); - }, - ), - ), - ); - } -} diff --git a/frontend/lib/presentation/organizer/widgets/quick_actions.dart b/frontend/lib/presentation/organizer/widgets/quick_actions.dart index d901a72..7ab1687 100644 --- a/frontend/lib/presentation/organizer/widgets/quick_actions.dart +++ b/frontend/lib/presentation/organizer/widgets/quick_actions.dart @@ -24,18 +24,7 @@ class QuickActions extends StatelessWidget { icon: Icons.add_circle_outline, color: Colors.green, onTap: () => context.push('/organizer/create-event'), - ), - _ActionCard( - title: 'View Analytics', - icon: Icons.bar_chart, - color: Colors.blue, - onTap: () { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Statistics page - Coming Soon!')), - ); - }, - ), + ) ], ), ), diff --git a/frontend/lib/presentation/organizer/widgets/stats_summary_card.dart b/frontend/lib/presentation/organizer/widgets/stats_summary_card.dart deleted file mode 100644 index b3ffdb9..0000000 --- a/frontend/lib/presentation/organizer/widgets/stats_summary_card.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; - -class StatsSummaryCard extends StatelessWidget { - final String title; - final String value; - final IconData icon; - final Color color; - - const StatsSummaryCard({ - super.key, - required this.title, - required this.value, - required this.icon, - required this.color, - }); - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - return Card( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - title, - style: theme.textTheme.titleMedium, - ), - Icon(icon, color: color), - ], - ), - const SizedBox(height: 16), - Text( - value, - style: - theme.textTheme.headlineMedium?.copyWith(color: color), - ), - ], - ), - ), - ); - } -}