Service_Project_Branching #82
@ -2,6 +2,7 @@ import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_lucide/flutter_lucide.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
||||
import 'package:marco/helpers/widgets/my_spacing.dart';
|
||||
@ -15,7 +16,6 @@ import 'package:marco/view/tenant/tenant_selection_screen.dart';
|
||||
import 'package:marco/controller/tenant/tenant_switch_controller.dart';
|
||||
import 'package:marco/helpers/theme/theme_editor_widget.dart';
|
||||
|
||||
|
||||
class UserProfileBar extends StatefulWidget {
|
||||
final bool isCondensed;
|
||||
const UserProfileBar({Key? key, this.isCondensed = false}) : super(key: key);
|
||||
@ -30,6 +30,7 @@ class _UserProfileBarState extends State<UserProfileBar>
|
||||
bool _isLoading = true;
|
||||
bool hasMpin = true;
|
||||
bool _isThemeEditorVisible = false;
|
||||
String _appVersion = '';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -40,6 +41,11 @@ class _UserProfileBarState extends State<UserProfileBar>
|
||||
Future<void> _initData() async {
|
||||
employeeInfo = LocalStorage.getEmployeeInfo()!;
|
||||
hasMpin = await LocalStorage.getIsMpin();
|
||||
|
||||
// Fetch app version
|
||||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||
_appVersion = '${packageInfo.version}+${packageInfo.buildNumber}';
|
||||
|
||||
setState(() => _isLoading = false);
|
||||
}
|
||||
|
||||
@ -79,55 +85,155 @@ class _UserProfileBarState extends State<UserProfileBar>
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: true,
|
||||
child: Stack(
|
||||
children: [
|
||||
Offstage(
|
||||
offstage: _isThemeEditorVisible,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_isLoading
|
||||
? const _LoadingSection()
|
||||
: _userProfileSection(isCondensed),
|
||||
if (!_isLoading && !isCondensed) _switchTenantRow(),
|
||||
MySpacing.height(12),
|
||||
Divider(
|
||||
indent: 18,
|
||||
endIndent: 18,
|
||||
thickness: 0.7,
|
||||
color: Colors.grey.withOpacity(0.25),
|
||||
),
|
||||
MySpacing.height(12),
|
||||
_supportAndSettingsMenu(isCondensed),
|
||||
const Spacer(),
|
||||
Divider(
|
||||
indent: 18,
|
||||
endIndent: 18,
|
||||
thickness: 0.35,
|
||||
color: Colors.grey.withOpacity(0.18),
|
||||
),
|
||||
_logoutButton(isCondensed),
|
||||
],
|
||||
),
|
||||
bottom: true,
|
||||
child: Stack(
|
||||
children: [
|
||||
Offstage(
|
||||
offstage: _isThemeEditorVisible,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_isLoading
|
||||
? const _LoadingSection()
|
||||
: _userProfileSection(isCondensed),
|
||||
if (!_isLoading && !isCondensed) _switchTenantRow(),
|
||||
MySpacing.height(12),
|
||||
Divider(
|
||||
indent: 18,
|
||||
endIndent: 18,
|
||||
thickness: 0.7,
|
||||
color: Colors.grey.withOpacity(0.25),
|
||||
),
|
||||
MySpacing.height(12),
|
||||
_supportAndSettingsMenu(isCondensed),
|
||||
MySpacing.height(12),
|
||||
|
||||
// Subtle version text for expanded mode
|
||||
if (!isCondensed && _appVersion.isNotEmpty)
|
||||
_versionText(),
|
||||
|
||||
const Spacer(),
|
||||
Divider(
|
||||
indent: 18,
|
||||
endIndent: 18,
|
||||
thickness: 0.35,
|
||||
color: Colors.grey.withOpacity(0.18),
|
||||
),
|
||||
_logoutButton(isCondensed),
|
||||
],
|
||||
),
|
||||
Offstage(
|
||||
offstage: !_isThemeEditorVisible,
|
||||
child: ThemeEditorWidget(
|
||||
onClose: () {
|
||||
setState(() => _isThemeEditorVisible = false);
|
||||
},
|
||||
),
|
||||
),
|
||||
Offstage(
|
||||
offstage: !_isThemeEditorVisible,
|
||||
child: ThemeEditorWidget(
|
||||
onClose: () {
|
||||
setState(() => _isThemeEditorVisible = false);
|
||||
},
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
|
||||
// Floating badge for condensed mode
|
||||
if (isCondensed && _appVersion.isNotEmpty) _versionBadge(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== CONTINUE EXISTING CODE =====================
|
||||
// =================== Version Widgets ===================
|
||||
|
||||
Widget _versionText() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 4, bottom: 12),
|
||||
child: Center(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade100.withOpacity(0.85),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: Colors.grey.shade200,
|
||||
width: 0.7,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.12),
|
||||
blurRadius: 3,
|
||||
offset: const Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.info_outline, size: 14, color: Colors.grey[700]),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'Version: $_appVersion',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey[800],
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _versionBadge() {
|
||||
return Positioned(
|
||||
bottom: 10,
|
||||
right: 14,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade100.withOpacity(0.85),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: Colors.grey.shade300,
|
||||
width: 1,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.17),
|
||||
blurRadius: 6,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Text(
|
||||
_appVersion,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
letterSpacing: 0.4,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// =================== Existing methods ===================
|
||||
|
||||
Widget _switchTenantRow() {
|
||||
final TenantSwitchController tenantSwitchController =
|
||||
Get.put(TenantSwitchController());
|
||||
@ -443,24 +549,20 @@ class _UserProfileBarState extends State<UserProfileBar>
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Top icon
|
||||
Icon(LucideIcons.log_out, size: 56, color: primaryColor),
|
||||
MySpacing.height(18),
|
||||
// Title
|
||||
MyText.titleLarge(
|
||||
"Logout Confirmation",
|
||||
fontWeight: 700,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
MySpacing.height(14),
|
||||
// Subtitle
|
||||
MyText.bodyMedium(
|
||||
"Are you sure you want to logout?\nYou will need to login again to continue.",
|
||||
color: Colors.grey[700],
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
MySpacing.height(30),
|
||||
// Buttons
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
|
||||
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.0+14
|
||||
version: 1.0.0+15
|
||||
environment:
|
||||
sdk: ^3.5.3
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user