baseproject
This commit is contained in:
252
base_project/lib/shared/widgets/navigation/modern_drawer.dart
Normal file
252
base_project/lib/shared/widgets/navigation/modern_drawer.dart
Normal file
@@ -0,0 +1,252 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/constants/ui_constants.dart';
|
||||
import '../../../utils/managers/user_manager.dart';
|
||||
import '../../../view_model/profile/profile_view_model.dart';
|
||||
import '../buttons/modern_button.dart';
|
||||
|
||||
class ModernDrawer extends StatelessWidget {
|
||||
final List<DrawerItem> items;
|
||||
final Widget? header;
|
||||
final Widget? footer;
|
||||
final Color? backgroundColor;
|
||||
final double? elevation;
|
||||
|
||||
const ModernDrawer({
|
||||
super.key,
|
||||
required this.items,
|
||||
this.header,
|
||||
this.footer,
|
||||
this.backgroundColor,
|
||||
this.elevation,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final colorScheme = theme.colorScheme;
|
||||
final email = UserManager().email;
|
||||
final userName = UserManager().userName;
|
||||
|
||||
return Drawer(
|
||||
backgroundColor: backgroundColor ?? colorScheme.surface,
|
||||
elevation: elevation ?? UIConstants.elevation8,
|
||||
child: Column(
|
||||
children: [
|
||||
// Header
|
||||
header ??
|
||||
_buildDefaultHeader(context, theme, colorScheme, userName, email),
|
||||
|
||||
// Navigation Items
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: items.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = items[index];
|
||||
return _buildDrawerItem(context, theme, colorScheme, item);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
// Footer
|
||||
if (footer != null) footer!,
|
||||
|
||||
// Logout Section
|
||||
_buildLogoutSection(context, theme, colorScheme),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDefaultHeader(
|
||||
BuildContext context,
|
||||
ThemeData theme,
|
||||
ColorScheme colorScheme,
|
||||
String? userName,
|
||||
String? email,
|
||||
) {
|
||||
return Consumer<ProfileViewModel>(
|
||||
builder: (context, provider, child) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(UIConstants.spacing24),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
colorScheme.primary,
|
||||
colorScheme.secondary,
|
||||
colorScheme.tertiary,
|
||||
],
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
// Profile Picture
|
||||
Container(
|
||||
width: UIConstants.logoSizeLarge,
|
||||
height: UIConstants.logoSizeLarge,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: Colors.white,
|
||||
width: 3,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: CircleAvatar(
|
||||
radius: UIConstants.logoSizeLarge / 2,
|
||||
backgroundColor: Colors.white.withOpacity(0.2),
|
||||
backgroundImage: provider.profileImageBytes != null
|
||||
? MemoryImage(provider.profileImageBytes!)
|
||||
: null,
|
||||
child: provider.profileImageBytes != null
|
||||
? null
|
||||
: Icon(
|
||||
Icons.person,
|
||||
size: UIConstants.iconSizeLarge,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: UIConstants.spacing16),
|
||||
|
||||
// User Name
|
||||
Text(
|
||||
"Hello, ${userName ?? 'User'}",
|
||||
style: theme.textTheme.titleLarge?.copyWith(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
|
||||
// User Email
|
||||
if (email != null) ...[
|
||||
const SizedBox(height: UIConstants.spacing8),
|
||||
Text(
|
||||
email,
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: Colors.white.withOpacity(0.8),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDrawerItem(
|
||||
BuildContext context,
|
||||
ThemeData theme,
|
||||
ColorScheme colorScheme,
|
||||
DrawerItem item,
|
||||
) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: UIConstants.spacing16,
|
||||
vertical: UIConstants.spacing4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(UIConstants.radius12),
|
||||
color: item.isSelected
|
||||
? colorScheme.primaryContainer.withOpacity(0.3)
|
||||
: Colors.transparent,
|
||||
),
|
||||
child: ListTile(
|
||||
leading: Container(
|
||||
padding: const EdgeInsets.all(UIConstants.spacing8),
|
||||
decoration: BoxDecoration(
|
||||
color: item.isSelected
|
||||
? colorScheme.primaryContainer
|
||||
: colorScheme.surfaceVariant.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(UIConstants.radius8),
|
||||
),
|
||||
child: Icon(
|
||||
item.icon,
|
||||
color: item.isSelected
|
||||
? colorScheme.onPrimaryContainer
|
||||
: item.color ?? colorScheme.onSurfaceVariant,
|
||||
size: UIConstants.iconSizeMedium,
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
item.title,
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
color:
|
||||
item.isSelected ? colorScheme.onSurface : colorScheme.onSurface,
|
||||
fontWeight: item.isSelected ? FontWeight.w600 : FontWeight.w500,
|
||||
),
|
||||
),
|
||||
subtitle: item.subtitle != null
|
||||
? Text(
|
||||
item.subtitle!,
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
trailing: item.trailing,
|
||||
onTap: () => item.onTap(context),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(UIConstants.radius12),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLogoutSection(
|
||||
BuildContext context,
|
||||
ThemeData theme,
|
||||
ColorScheme colorScheme,
|
||||
) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(UIConstants.spacing24),
|
||||
child: ModernButton(
|
||||
text: 'Logout',
|
||||
type: ModernButtonType.danger,
|
||||
size: ModernButtonSize.medium,
|
||||
icon: Icon(Icons.logout),
|
||||
onPressed: () async {
|
||||
await UserManager().clearUser();
|
||||
if (context.mounted) {
|
||||
Navigator.pushReplacementNamed(context, '/splash');
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DrawerItem {
|
||||
final IconData icon;
|
||||
final String title;
|
||||
final String? subtitle;
|
||||
final void Function(BuildContext) onTap;
|
||||
final Color? color;
|
||||
final bool isSelected;
|
||||
final Widget? trailing;
|
||||
|
||||
const DrawerItem({
|
||||
required this.icon,
|
||||
required this.title,
|
||||
this.subtitle,
|
||||
required this.onTap,
|
||||
this.color,
|
||||
this.isSelected = false,
|
||||
this.trailing,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user