updated branding & added analytics

This commit is contained in:
Prince
2026-06-19 12:44:57 +02:00
parent f3ae5ca791
commit bb9dbac2a3
41 changed files with 181 additions and 110 deletions

View File

@@ -59,6 +59,7 @@ class AccountProvider extends ChangeNotifier {
notifyListeners();
return ApiResponse.failure(_accountError!);
} catch (e, s) {
logger.e(e);
logger.e(s);
_isLoadingAccount = false;
_accountError = 'An unexpected error occurred. Please try again.';

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:qpay/screens/accounts/account_provider.dart';
import 'package:qpay/screens/accounts/models/account_model.dart';
@@ -21,19 +22,21 @@ class AccountBalanceWidget extends StatefulWidget {
class _AccountBalanceWidgetState extends State<AccountBalanceWidget> {
late AccountProvider _accountProvider;
bool _isLoggedIn = false;
String? _phoneNumber;
AccountModel? _usdAccount;
AccountModel? _zwgAccount;
bool _isLoadingUsd = false;
bool _isLoadingZwG = false;
String? _usdError;
String? _zwgError;
String? _phoneNumber;
@override
void initState() {
super.initState();
_accountProvider = AccountProvider();
_loadBalances();
_loadAuthStateAndBalances();
}
@override
@@ -42,11 +45,21 @@ class _AccountBalanceWidgetState extends State<AccountBalanceWidget> {
super.dispose();
}
Future<void> _loadBalances() async {
Future<void> _loadAuthStateAndBalances() async {
final prefs = await SharedPreferences.getInstance();
// Determine login state from persisted token
if (prefs.getString("token") != null) {
setState(() {
_isLoggedIn = true;
});
}
_phoneNumber = prefs.getString('phone');
if (_phoneNumber == null || _phoneNumber!.isEmpty) return;
if (_phoneNumber == null || _phoneNumber!.isEmpty) {
return;
}
setState(() {
_isLoadingUsd = true;
@@ -84,6 +97,67 @@ class _AccountBalanceWidgetState extends State<AccountBalanceWidget> {
}
});
}
// If both fetches failed, mark as not logged in
if (mounted &&
!usdResult.isSuccess &&
!zwgResult.isSuccess &&
_isLoggedIn) {
setState(() {
_isLoggedIn = false;
});
}
}
Future<void> _refreshBalances() async {
final prefs = await SharedPreferences.getInstance();
_phoneNumber = prefs.getString('phone');
if (_phoneNumber == null || _phoneNumber!.isEmpty) return;
setState(() {
_isLoadingUsd = true;
_isLoadingZwG = true;
});
final usdResult = await _accountProvider.fetchAccount(
'USD$_phoneNumber',
);
if (mounted) {
setState(() {
_isLoadingUsd = false;
if (usdResult.isSuccess && usdResult.data != null) {
_usdAccount = usdResult.data;
_usdError = null;
} else {
_usdError = usdResult.error;
}
});
}
final zwgResult = await _accountProvider.fetchAccount(
'ZWG$_phoneNumber',
);
if (mounted) {
setState(() {
_isLoadingZwG = false;
if (zwgResult.isSuccess && zwgResult.data != null) {
_zwgAccount = zwgResult.data;
_zwgError = null;
} else {
_zwgError = zwgResult.error;
}
});
}
if (mounted &&
!usdResult.isSuccess &&
!zwgResult.isSuccess &&
_isLoggedIn) {
setState(() {
_isLoggedIn = false;
});
}
}
@override
@@ -91,6 +165,10 @@ class _AccountBalanceWidgetState extends State<AccountBalanceWidget> {
final theme = Theme.of(context);
final isDark = theme.brightness == Brightness.dark;
if (!_isLoggedIn) {
return _buildLoginPrompt(theme, isDark);
}
if (_phoneNumber == null || _phoneNumber!.isEmpty) {
return const SizedBox.shrink();
}
@@ -143,7 +221,7 @@ class _AccountBalanceWidgetState extends State<AccountBalanceWidget> {
onPressed: _isLoadingUsd || _isLoadingZwG
? null
: () {
_loadBalances();
_refreshBalances();
},
icon: Icon(
Icons.refresh_rounded,
@@ -176,6 +254,70 @@ class _AccountBalanceWidgetState extends State<AccountBalanceWidget> {
);
}
// ──────────────────────────────────────────────────────────────
// Login Prompt
// ──────────────────────────────────────────────────────────────
Widget _buildLoginPrompt(ThemeData theme, bool isDark) {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 18),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
theme.colorScheme.primary.withValues(alpha: 0.12),
theme.colorScheme.primary.withValues(alpha: 0.04),
],
),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: theme.colorScheme.primary.withValues(alpha: 0.15),
width: 1,
),
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Register or Login for more features',
style: TextStyle(
fontSize: 14,
color: isDark ? Colors.white : Colors.black87,
),
),
],
),
),
ElevatedButton(
onPressed: () {
context.push('/onboarding/landing');
},
style: ElevatedButton.styleFrom(
backgroundColor: theme.colorScheme.primary,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 0,
),
child: const Text(
'Get Started',
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600),
),
),
],
),
),
);
}
Widget _buildCompactCard({
required ThemeData theme,
required bool isDark,