From dde59486a85ca90ebeb673b9eb3c162521dced35 Mon Sep 17 00:00:00 2001 From: Erick Namukolo Date: Mon, 25 Aug 2025 10:27:27 +0200 Subject: [PATCH 1/7] .. --- lib/features/websites/screens/websites_screen.dart | 8 +++++++- pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/features/websites/screens/websites_screen.dart b/lib/features/websites/screens/websites_screen.dart index f855b17..e626d17 100644 --- a/lib/features/websites/screens/websites_screen.dart +++ b/lib/features/websites/screens/websites_screen.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:pulse/features/auth/repo/auth_repo.dart'; import 'package:pulse/features/settings/screens/settings_screen.dart'; import 'package:pulse/features/websites/cubit/website_cubit.dart'; import 'package:pulse/features/websites/screens/add_website_screen.dart'; @@ -77,7 +78,12 @@ class _WebsitesScreenState extends State { icon: Icons.replay_outlined, title: 'Refresh', click: context.read().getWebsites, - ) + ), + MordernBtn( + icon: Icons.logout_rounded, + title: 'Logout', + click: () => AuthRepo().signOut(context), + ), ], ) : ListView.separated( diff --git a/pubspec.yaml b/pubspec.yaml index 8dd12d0..5e60c5b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: "A new Flutter project." # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.0.9+10 +version: 1.0.10+11 environment: sdk: ^3.6.1 From 2446942565d6b377d79e699871d3152739456343 Mon Sep 17 00:00:00 2001 From: Erick Namukolo Date: Mon, 25 Aug 2025 22:10:09 +0200 Subject: [PATCH 2/7] added a coffe btn --- lib/features/settings/screens/settings_screen.dart | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/features/settings/screens/settings_screen.dart b/lib/features/settings/screens/settings_screen.dart index 34bd027..69ac906 100644 --- a/lib/features/settings/screens/settings_screen.dart +++ b/lib/features/settings/screens/settings_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:icons_plus/icons_plus.dart'; import 'package:pulse/features/auth/repo/auth_repo.dart'; import 'package:pulse/features/settings/screens/model/btn.dart'; import 'package:pulse/utils/colors.dart'; @@ -78,9 +79,18 @@ class _SettingsScreenState extends State { Links.goToLink('https://ericknamukolo.com'); }, ), + Btn( + title: 'Coffee', + des: 'Buy me a coffe 🍵', + type: 'app', + icon: Bootstrap.cup_hot_fill, + click: () { + Links.goToLink('https://www.sonka.io/creator/erick'); + }, + ), // contact Btn( - title: 'Help & Support', + title: 'Help & Support/Feature Suggestions', des: 'Contact Me', type: 'contact', icon: Icons.contact_support_rounded, @@ -109,7 +119,6 @@ class _SettingsScreenState extends State { } }, ), - Btn( title: 'Logout', des: 'Logout of your account', From 50ff32ff926b3a6aa9ce085cccaaf7c6d2f86011 Mon Sep 17 00:00:00 2001 From: Erick Namukolo Date: Mon, 25 Aug 2025 22:11:05 +0200 Subject: [PATCH 3/7] . --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 5e60c5b..031ab07 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: "A new Flutter project." # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.0.10+11 +version: 1.0.11+12 environment: sdk: ^3.6.1 From ccb4cf480597e6ccbb1634f91cfbf4886e21ce0b Mon Sep 17 00:00:00 2001 From: Erick Namukolo Date: Sat, 30 Aug 2025 20:58:24 +0200 Subject: [PATCH 4/7] .. --- lib/features/sessions/widget/session_card.dart | 1 - lib/utils/extensions.dart | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/features/sessions/widget/session_card.dart b/lib/features/sessions/widget/session_card.dart index c9f5f6c..520959a 100644 --- a/lib/features/sessions/widget/session_card.dart +++ b/lib/features/sessions/widget/session_card.dart @@ -8,7 +8,6 @@ import 'package:pulse/features/sessions/screens/session_details_screen.dart'; import 'package:pulse/utils/colors.dart'; import 'package:pulse/utils/navigation.dart'; import 'package:pulse/utils/text.dart'; -import 'package:pulse/utils/utils.dart'; import 'package:pulse/widgets/container_wrapper.dart'; import '../../../widgets/icon_btn.dart'; diff --git a/lib/utils/extensions.dart b/lib/utils/extensions.dart index 21fd1e3..375a833 100644 --- a/lib/utils/extensions.dart +++ b/lib/utils/extensions.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:icons_plus/icons_plus.dart'; -import 'package:pulse/utils/utils.dart'; extension StringExtensions on String { IconData get toDeviceIcon { From 76bed669ba256b8152c8f9e294570880cc438728 Mon Sep 17 00:00:00 2001 From: Erick Namukolo Date: Fri, 10 Oct 2025 19:54:33 +0200 Subject: [PATCH 5/7] fixed overview screen --- .../overview/cubit/overview_cubit.dart | 5 +- .../overview/cubit/overview_state.dart | 2 +- lib/features/overview/repo/overview_repo.dart | 1 + .../overview/screens/overview_screen.dart | 61 +++++++++++++------ lib/features/overview/widgets/stat_card.dart | 13 ++-- .../screens/session_details_screen.dart | 4 ++ lib/utils/requests.dart | 5 +- 7 files changed, 66 insertions(+), 25 deletions(-) diff --git a/lib/features/overview/cubit/overview_cubit.dart b/lib/features/overview/cubit/overview_cubit.dart index 0e68c4d..8bbcbbe 100644 --- a/lib/features/overview/cubit/overview_cubit.dart +++ b/lib/features/overview/cubit/overview_cubit.dart @@ -17,6 +17,7 @@ class OverviewCubit extends Cubit { try { var stats = await OverviewRepo().getSummaryStats(id: id, start: start, end: end); + logger.i(stats); emit(state.copyWith(stats: stats, appState: AppState.complete)); } catch (e) { emit( @@ -52,7 +53,9 @@ class OverviewCubit extends Cubit { var res = await OverviewRepo().getPageviewStats( id: id, unit: unit ?? state.unit, start: start, end: end); emit(state.copyWith(pageview: res)); - } catch (e) { + } catch (e, st) { + logger.i(e); + logger.i(st); emit( state.copyWith(errorMessage: e.toString(), appState: AppState.error)); } diff --git a/lib/features/overview/cubit/overview_state.dart b/lib/features/overview/cubit/overview_state.dart index db8456e..1f61aa3 100644 --- a/lib/features/overview/cubit/overview_state.dart +++ b/lib/features/overview/cubit/overview_state.dart @@ -10,7 +10,7 @@ class OverviewState extends Equatable { final Pageview? pageview; const OverviewState( {this.appState = AppState.initial, - this.metric = 'Url', + this.metric = 'Path', this.unit = 'Day', this.stats, this.errorMessage, diff --git a/lib/features/overview/repo/overview_repo.dart b/lib/features/overview/repo/overview_repo.dart index 4f9cd1e..75b0a3d 100644 --- a/lib/features/overview/repo/overview_repo.dart +++ b/lib/features/overview/repo/overview_repo.dart @@ -37,6 +37,7 @@ class OverviewRepo { var res = await Requests.get( endpoint: '${Endpoints.websites}/$id/metrics?startAt=$startAt&endAt=$endAt&type=${metric.toLowerCase()}'); + logger.d(res); return Metric.toList(res); } diff --git a/lib/features/overview/screens/overview_screen.dart b/lib/features/overview/screens/overview_screen.dart index c3c293e..912e205 100644 --- a/lib/features/overview/screens/overview_screen.dart +++ b/lib/features/overview/screens/overview_screen.dart @@ -100,7 +100,13 @@ class _OverviewScreenState extends State { radius: 16, fadeTheme: FadeTheme.light, ) - : StatCard(stat: state.stats!.entries.toList()[0]), + : StatCard( + stat: state.stats!.entries.first, + comp: + (state.stats!['comparison'] as Map) + .entries + .first, + ), GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, @@ -108,21 +114,42 @@ class _OverviewScreenState extends State { mainAxisSpacing: 15, childAspectRatio: 1.3, ), - itemBuilder: (_, i) => - state.stats == null || state.appState == AppState.loading - ? FadeShimmer( - height: 8, - width: 150, - radius: 16, - fadeTheme: FadeTheme.light, - ) - : StatCard( - stat: state.stats!.entries - .toList() - .getRange(1, state.stats!.length) - .toList()[i], - ), - itemCount: (state.stats?.length ?? 5) - 1, + itemBuilder: (_, i) { + Map stats = {...state.stats!}; + stats.removeWhere((key, value) => key == "comparison"); + + return state.stats == null || + state.appState == AppState.loading + ? FadeShimmer( + height: 8, + width: 150, + radius: 16, + fadeTheme: FadeTheme.light, + ) + : StatCard( + stat: stats.entries + .toList() + .getRange(1, stats.length) + .toList()[i], + comp: (state.stats!['comparison'] + as Map) + .entries + .toList() + .getRange( + 1, + (state.stats!['comparison'] + as Map) + .entries + .toList() + .length) + .toList()[i], + ); + }, + itemCount: (state.stats?.entries + .where((val) => val.key != 'comparison') + .length ?? + 5) - + 1, shrinkWrap: true, physics: NeverScrollableScrollPhysics(), ), @@ -161,7 +188,7 @@ class _OverviewScreenState extends State { removePadding: true, selectedItem: state.metric, items: [ - 'Url', + 'Path', 'Referrer', 'Browser', 'OS', diff --git a/lib/features/overview/widgets/stat_card.dart b/lib/features/overview/widgets/stat_card.dart index 5be4992..f5ab34a 100644 --- a/lib/features/overview/widgets/stat_card.dart +++ b/lib/features/overview/widgets/stat_card.dart @@ -9,15 +9,18 @@ import '../../../widgets/container_wrapper.dart'; class StatCard extends StatelessWidget { final MapEntry stat; + final MapEntry comp; + const StatCard({ super.key, required this.stat, + required this.comp, }); @override Widget build(BuildContext context) { - double percentage = OverviewRepo().getPercentage( - current: stat.value['value'], previous: stat.value['prev']); + double percentage = + OverviewRepo().getPercentage(current: stat.value, previous: comp.value); return ContainerWrapper( padding: 15.0, bRadius: 16, @@ -28,15 +31,15 @@ class StatCard extends StatelessWidget { style: kBodyTitleTextStyle.copyWith(color: kGreyColor)), if (stat.key.toLowerCase() == 'totaltime') FittedBox( - child: Text(formatDuration((stat.value as Map)['value']), + child: Text(formatDuration((stat.value)), style: kTitleTextStyle.copyWith( fontSize: kTitleTextStyle.fontSize! + 8)), ) else - Text(NumberFormat.compact().format((stat.value as Map)['value']), + Text(NumberFormat.compact().format((stat.value)), style: kTitleTextStyle.copyWith( fontSize: kTitleTextStyle.fontSize! + 8)), - if (stat.value['prev'] != -1) + if (comp.value != -1) Container( padding: EdgeInsets.symmetric(horizontal: 14.0, vertical: 4), decoration: BoxDecoration( diff --git a/lib/features/sessions/screens/session_details_screen.dart b/lib/features/sessions/screens/session_details_screen.dart index 5b30169..9d328e4 100644 --- a/lib/features/sessions/screens/session_details_screen.dart +++ b/lib/features/sessions/screens/session_details_screen.dart @@ -108,12 +108,14 @@ class _SessionDetailsScreenState extends State { children: [ Expanded( child: StatCard( + comp: MapEntry('', ''), stat: MapEntry( 'views', {'value': widget.session.views, 'prev': -1}), ), ), Expanded( child: StatCard( + comp: MapEntry('', ''), stat: MapEntry('visits', {'value': widget.session.visits, 'prev': -1}), ), @@ -132,12 +134,14 @@ class _SessionDetailsScreenState extends State { children: [ Expanded( child: StatCard( + comp: MapEntry('', ''), stat: MapEntry('events', {'value': _session!.events, 'prev': -1}), ), ), Expanded( child: StatCard( + comp: MapEntry('', ''), stat: MapEntry('totaltime', {'value': _session!.totaltime, 'prev': -1}), ), diff --git a/lib/utils/requests.dart b/lib/utils/requests.dart index 8bf9817..2a8496f 100644 --- a/lib/utils/requests.dart +++ b/lib/utils/requests.dart @@ -138,11 +138,14 @@ class Requests { try { http.Response res; res = await fn.timeout(const Duration(seconds: 10)); - logger.i(endpoint); + if (endpoint.contains('auth/login') && res.statusCode == 404) { return throw Exception('Invalid host url'); } + if (res.statusCode != okStatusCode) { + logger.i(res.body); + logger.i(endpoint); return throw Exception( json.decode(res.body)?['error'] ?? 'Error occurred'); } From 1bd2e4c7b57b83fbd179a7fe81588ee1dcd7ec24 Mon Sep 17 00:00:00 2001 From: Erick Namukolo Date: Fri, 10 Oct 2025 20:04:29 +0200 Subject: [PATCH 6/7] fixed breaking changes --- lib/features/overview/widgets/stat_card.dart | 2 ++ .../screens/session_details_screen.dart | 20 ++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/features/overview/widgets/stat_card.dart b/lib/features/overview/widgets/stat_card.dart index f5ab34a..63b185c 100644 --- a/lib/features/overview/widgets/stat_card.dart +++ b/lib/features/overview/widgets/stat_card.dart @@ -19,6 +19,8 @@ class StatCard extends StatelessWidget { @override Widget build(BuildContext context) { + logger.i(stat); + logger.i(comp); double percentage = OverviewRepo().getPercentage(current: stat.value, previous: comp.value); return ContainerWrapper( diff --git a/lib/features/sessions/screens/session_details_screen.dart b/lib/features/sessions/screens/session_details_screen.dart index 9d328e4..d869fb4 100644 --- a/lib/features/sessions/screens/session_details_screen.dart +++ b/lib/features/sessions/screens/session_details_screen.dart @@ -108,16 +108,14 @@ class _SessionDetailsScreenState extends State { children: [ Expanded( child: StatCard( - comp: MapEntry('', ''), - stat: MapEntry( - 'views', {'value': widget.session.views, 'prev': -1}), + comp: MapEntry('pageviews', -1), + stat: MapEntry('pageviews', widget.session.views), ), ), Expanded( child: StatCard( - comp: MapEntry('', ''), - stat: MapEntry('visits', - {'value': widget.session.visits, 'prev': -1}), + comp: MapEntry('visits', -1), + stat: MapEntry('visits', widget.session.visits), ), ) ], @@ -134,16 +132,14 @@ class _SessionDetailsScreenState extends State { children: [ Expanded( child: StatCard( - comp: MapEntry('', ''), - stat: MapEntry('events', - {'value': _session!.events, 'prev': -1}), + comp: MapEntry('events', -1), + stat: MapEntry('events', _session!.events), ), ), Expanded( child: StatCard( - comp: MapEntry('', ''), - stat: MapEntry('totaltime', - {'value': _session!.totaltime, 'prev': -1}), + comp: MapEntry('totaltime', -1), + stat: MapEntry('totaltime', _session!.totaltime), ), ) ], From a61cd50c9d23cfcf2a99245206c07fb1217b6ab7 Mon Sep 17 00:00:00 2001 From: Erick Namukolo Date: Fri, 10 Oct 2025 20:14:58 +0200 Subject: [PATCH 7/7] version++ --- lib/features/overview/screens/overview_screen.dart | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/features/overview/screens/overview_screen.dart b/lib/features/overview/screens/overview_screen.dart index 912e205..d62fb7a 100644 --- a/lib/features/overview/screens/overview_screen.dart +++ b/lib/features/overview/screens/overview_screen.dart @@ -115,7 +115,7 @@ class _OverviewScreenState extends State { childAspectRatio: 1.3, ), itemBuilder: (_, i) { - Map stats = {...state.stats!}; + Map stats = {...state.stats ?? {}}; stats.removeWhere((key, value) => key == "comparison"); return state.stats == null || diff --git a/pubspec.yaml b/pubspec.yaml index 031ab07..4a10b4e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: "A new Flutter project." # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.0.11+12 +version: 1.0.12+13 environment: sdk: ^3.6.1