Skip to content

Commit

Permalink
[ADD]: Home screen views stats
Browse files Browse the repository at this point in the history
  • Loading branch information
SandroMaglione committed Dec 1, 2020
1 parent 30858bd commit e87ffa9
Show file tree
Hide file tree
Showing 8 changed files with 355 additions and 29 deletions.
58 changes: 30 additions & 28 deletions lib/app/goal/presentation/screens/home_screen.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mobile_polimi_project/app/activity/domain/entities/summary_activity.dart';
import 'package:mobile_polimi_project/app/activity/presentation/controllers/cubit/activity_list_cubit.dart';
import 'package:mobile_polimi_project/app/goal/presentation/widgets/summary_activity_card.dart';
import 'package:mobile_polimi_project/app/goal/presentation/views/calendar_view.dart';
import 'package:mobile_polimi_project/app/goal/presentation/views/profile_view.dart';
import 'package:mobile_polimi_project/app/goal/presentation/views/stats_view.dart';
import 'package:mobile_polimi_project/app/goal/presentation/views/summary_activity_view.dart';
import 'package:mobile_polimi_project/app/presentation/controller/cubit/theme_cubit.dart';
import 'package:mobile_polimi_project/app/presentation/widgets/build_provider.dart';
import 'package:mobile_polimi_project/core/routes/router.gr.dart';
import 'package:mobile_polimi_project/core/utils/async_state.dart';
import 'package:mobile_polimi_project/injectable.dart';
import 'package:auto_route/auto_route.dart';

class HomeScreen extends StatelessWidget {
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
int tabIndex = 0;

@override
Widget build(BuildContext context) {
return SafeArea(
Expand All @@ -25,32 +30,14 @@ class HomeScreen extends StatelessWidget {
final theme = context.watch<ThemeCubit>().state;

return Scaffold(
body: BlocBuilder<ActivityListCubit,
AsyncState<IList<SummaryActivity>>>(
builder: (context, state) => state.maybeWhen(
orElse: () => const Center(
child: const CircularProgressIndicator(),
),
success: (activityList) => ListView(
padding: const EdgeInsets.all(15),
children: [
...activityList
.map(
(summaryActivity) => SummaryActivityCard(
summaryActivity: summaryActivity,
),
)
.toIterable(),
],
),
),
),
body: _currentView,
bottomNavigationBar: BottomNavigationBar(
currentIndex: tabIndex,
backgroundColor: theme.customColorTheme.primaryColor,
selectedItemColor: theme.customColorTheme.accentColor,
unselectedItemColor:
theme.customColorTheme.primaryColorExtraLight,
onTap: (index) => context.navigator.push(Routes.CreateGoalScreen),
onTap: (index) => setState(() => tabIndex = index),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
Expand All @@ -75,4 +62,19 @@ class HomeScreen extends StatelessWidget {
),
);
}

Widget get _currentView {
switch (tabIndex) {
case 0:
return const SummaryActivityView();
case 1:
return const CalendarView();
case 2:
return const StatsView();
case 3:
return const ProfileView();
default:
return const SummaryActivityView();
}
}
}
112 changes: 112 additions & 0 deletions lib/app/goal/presentation/views/calendar_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import 'package:dartz/dartz.dart' as dartz;
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mobile_polimi_project/app/activity/domain/entities/summary_activity.dart';
import 'package:mobile_polimi_project/app/activity/presentation/controllers/cubit/activity_list_cubit.dart';
import 'package:mobile_polimi_project/app/goal/presentation/widgets/summary_activity_card.dart';
import 'package:mobile_polimi_project/app/presentation/controller/cubit/theme_cubit.dart';
import 'package:mobile_polimi_project/core/utils/async_state.dart';
import 'package:table_calendar/table_calendar.dart';

class CalendarView extends StatefulWidget {
const CalendarView({Key key}) : super(key: key);

@override
_CalendarViewState createState() => _CalendarViewState();
}

class _CalendarViewState extends State<CalendarView> {
CalendarController _calendarController;
List<SummaryActivity> _selectedEvents = [];

@override
void initState() {
super.initState();
_calendarController = CalendarController();
}

@override
void dispose() {
_calendarController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
final theme = context.watch<ThemeCubit>().state;

return BlocBuilder<ActivityListCubit,
AsyncState<dartz.IList<SummaryActivity>>>(
builder: (context, state) => state.maybeWhen(
orElse: () => const Center(
child: const CircularProgressIndicator(),
),
success: (activityList) => SingleChildScrollView(
child: Column(
children: [
OutlineButton(
onPressed: () => setState(
() => _calendarController.setSelectedDay(
activityList.foldLeft(
DateTime.now(),
(previous, a) => a.startDate.isBefore(previous)
? a.startDate
: previous,
),
animate: true,
),
),
),
TableCalendar(
calendarController: _calendarController,
events: activityList.foldLeft(
{},
(previous, a) => {
...previous,
a.startDate: <SummaryActivity>[a]
},
),
calendarStyle: CalendarStyle(
markersColor: Colors.deepOrange,
contentPadding: const EdgeInsets.only(
top: 10,
left: 30,
right: 30,
),
contentDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: theme.customColorTheme.accentColor,
border: Border.all(
width: 1,
color: theme.customColorTheme.primaryColor,
),
),
eventDayStyle: theme.customTextTheme.textTheme.headline4,
outsideDaysVisible: false,
renderDaysOfWeek: true,
weekendStyle: theme.customTextTheme.textTheme.caption,
),
onDaySelected: (dateTime, events, _) {
setState(
() => _selectedEvents = [
...events.map((dynamic e) => e as SummaryActivity),
],
);
},
),
Column(
children: [
..._selectedEvents.map(
(e) => SummaryActivityCard(
summaryActivity: e,
),
),
],
),
],
),
),
),
);
}
}
84 changes: 84 additions & 0 deletions lib/app/goal/presentation/views/profile_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mobile_polimi_project/app/activity/domain/entities/summary_activity.dart';
import 'package:mobile_polimi_project/app/activity/presentation/controllers/cubit/activity_list_cubit.dart';
import 'package:mobile_polimi_project/app/presentation/controller/cubit/theme_cubit.dart';
import 'package:mobile_polimi_project/core/utils/async_state.dart';
import 'package:step_progress_indicator/step_progress_indicator.dart';

class ProfileView extends StatelessWidget {
const ProfileView({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
final theme = context.watch<ThemeCubit>().state;

return BlocBuilder<ActivityListCubit, AsyncState<IList<SummaryActivity>>>(
builder: (context, state) => state.maybeWhen(
orElse: () => const Center(
child: const CircularProgressIndicator(),
),
success: (activityList) {
final listDateRange = activityList.filter(
(a) =>
a.startDate.isBefore(DateTime(2019, 11)) &&
a.startDate.isAfter(
DateTime(2019, 11).subtract(const Duration(days: 100))),
);

return SingleChildScrollView(
padding: const EdgeInsets.all(30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Total activities: ${listDateRange.length()}',
),
Text(
'Total moving time: ${listDateRange.foldLeft<double>(0, (previous, a) => previous + a.movingTime)}',
),
Text('Points: ${activityPoints(listDateRange)}'),
Column(
children: [
...listDateRange.map(
(a) {
final pts = a.movingTime /
DateTime(2019, 11).difference(a.startDate).inDays;

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Value: +$pts pts',
),
StepProgressIndicator(
totalSteps: 100,
padding: 0,
currentStep: 100 - pts.toInt(),
selectedColor: theme.customColorTheme.accentColor,
unselectedColor:
theme.customColorTheme.errorColor,
),
],
);
},
).toIterable()
],
),
],
),
);
},
),
);
}

double activityPoints(IList<SummaryActivity> activityList) =>
activityList.foldLeft(
0,
(prev, a) =>
prev +
(a.movingTime / DateTime(2019, 11).difference(a.startDate).inDays),
);
}
65 changes: 65 additions & 0 deletions lib/app/goal/presentation/views/stats_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'package:dartz/dartz.dart' as dartz;
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:mobile_polimi_project/app/activity/domain/entities/summary_activity.dart';
import 'package:mobile_polimi_project/app/activity/presentation/controllers/cubit/activity_list_cubit.dart';
import 'package:mobile_polimi_project/core/utils/async_state.dart';

class StatsView extends StatefulWidget {
const StatsView({Key key}) : super(key: key);

@override
_StatsViewState createState() => _StatsViewState();
}

class _StatsViewState extends State<StatsView> {
DateTime startDateFilter =
DateTime(2019, 10).subtract(const Duration(days: 30));
DateTime endDateFilter = DateTime(2019, 10);

@override
Widget build(BuildContext context) {
return BlocBuilder<ActivityListCubit,
AsyncState<dartz.IList<SummaryActivity>>>(
builder: (context, state) => state.maybeWhen(
orElse: () => const Center(
child: const CircularProgressIndicator(),
),
success: (activityList) {
final listDateRange = activityList.filter(
(a) =>
a.startDate.isBefore(endDateFilter) &&
a.startDate.isAfter(startDateFilter),
);

return SingleChildScrollView(
padding: const EdgeInsets.all(30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'From ${DateFormat('dd MMMM yyyy').format(startDateFilter)} - To ${DateFormat('dd MMMM yyyy').format(endDateFilter)}',
),
const Divider(),
Text('Num activities: ${listDateRange.length()}'),
Text(
'Mean avg speed: ${listDateRange.foldLeft<double>(0, (previous, a) => previous + a.averageSpeed) / listDateRange.length()}',
),
Text(
'Mean distance: ${listDateRange.foldLeft<double>(0, (previous, a) => previous + a.distance) / listDateRange.length()}',
),
Text(
'Mean elapsed time: ${listDateRange.foldLeft<double>(0, (previous, a) => previous + a.elapsedTime) / listDateRange.length()}',
),
Text(
'Total elapsed time: ${listDateRange.foldLeft<double>(0, (previous, a) => previous + a.elapsedTime)}',
),
],
),
);
},
),
);
}
}
34 changes: 34 additions & 0 deletions lib/app/goal/presentation/views/summary_activity_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mobile_polimi_project/app/activity/domain/entities/summary_activity.dart';
import 'package:mobile_polimi_project/app/activity/presentation/controllers/cubit/activity_list_cubit.dart';
import 'package:mobile_polimi_project/app/goal/presentation/widgets/summary_activity_card.dart';
import 'package:mobile_polimi_project/core/utils/async_state.dart';

class SummaryActivityView extends StatelessWidget {
const SummaryActivityView({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
return BlocBuilder<ActivityListCubit, AsyncState<IList<SummaryActivity>>>(
builder: (context, state) => state.maybeWhen(
orElse: () => const Center(
child: const CircularProgressIndicator(),
),
success: (activityList) => ListView(
padding: const EdgeInsets.all(15),
children: [
...activityList
.map(
(summaryActivity) => SummaryActivityCard(
summaryActivity: summaryActivity,
),
)
.toIterable(),
],
),
),
);
}
}
Loading

0 comments on commit e87ffa9

Please sign in to comment.