Why we use mixins
Application of mixins
Coding example of mixins
Reuse App bar action
Why we use mixins
Mixins in Flutter (and Dart) are a way to reuse a class’s code in multiple class hierarchies. Mixins allow you to add functionality to classes without needing inheritance, making it easier to maintain and reuse code. They are used to encapsulate and share behavior between classes.
Key Points about Mixins
Code Reusability: Mixins allow you to reuse methods and properties in multiple classes.
Avoid Multiple Inheritance: Dart does not support multiple inheritance, but mixins offer a way to achieve similar behavior.
Flexibility: You can mix in multiple mixins into a single class, providing a flexible way to combine functionality.
In other words mixins are normal classes from which we can borrow methods(or variables) from without extending the class. In dart we can do this by
For Java developers, it is a completely new concept to learn as Java does not supports multiple inheritance or mixins. Java tries to make up for this by using Interfaces, but that is not as useful or flexible as mixins.
class B {  //B is not allowed to extend any other class other than object
  method(){
     ....
  }
}
class A with B {
  ....
     ......
}
void main() {
  A a = A();
  a.method();  //we got the method without inheriting B
}
Defining a Mixin
In Dart, a mixin is created using the mixin keyword.
Example: LoggerMixin
Let's define a mixin for logging purposes.
import 'package:logger/logger.dart';
// Define the LoggerMixin
mixin LoggerMixin {
  final Logger _logger = Logger();
  void logInfo(String message) {
    _logger.i(message);
  }
  void logError(String message) {
    _logger.e(message);
  }
}
Using the LoggerMixin
To use the mixin, you simply include it in the class definition using the with keyword.
class MyClass with LoggerMixin {
  final String name;
  MyClass(this.name);
  void doSomething() {
    logInfo('$name is doing something.');
    try {
      // Simulate an error
      int result = 1 ~/ 0;
    } catch (e) {
      logError('Error occurred: $e');
    }
  }
}
Complete Example in a Flutter App
Let's put everything together and create a simple Flutter app that uses the LoggerMixin.
Step 1: Add Dependencies
Add the logger package to your pubspec.yaml file.
dependencies:
  flutter:
    sdk: flutter
  logger: ^1.0.0
Step 2: Create the LoggerMixin
Create a file logger_mixin.dart and define the LoggerMixin.
// logger_mixin.dart
import 'package:logger/logger.dart';
mixin LoggerMixin {
  final Logger _logger = Logger();
  void logInfo(String message) {
    _logger.i(message);
  }
  void logError(String message) {
    _logger.e(message);
  }
}
Step 3: Create a Class Using the LoggerMixin
Create a file my_class.dart and define the MyClass which uses the LoggerMixin.
// my_class.dart
import 'logger_mixin.dart';
class MyClass with LoggerMixin {
  final String name;
  MyClass(this.name);
  void doSomething() {
    logInfo('$name is doing something.');
    try {
      // Simulate an error
      int result = 1 ~/ 0;
    } catch (e) {
      logError('Error occurred: $e');
    }
  }
}
Step 4: Integrate MyClass in Flutter App
Update your main.dart to use MyClass and display the log output.
import 'package:flutter/material.dart';
import 'my_class.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatelessWidget {
  final MyClass myInstance = MyClass('TestInstance');
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mixin Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            myInstance.doSomething();
          },
          child: Text('Do Something'),
        ),
      ),
    );
  }
}
Explanation
LoggerMixin: This mixin provides logging functionality through logInfo and logError methods.
MyClass: This class uses the LoggerMixin to gain logging capabilities. It logs messages when performing actions and handling errors.
Flutter App: The main Flutter app integrates MyClass and demonstrates how to use the logging functionality. When you press the "Do Something" button, the doSomething method is called, and log messages are printed to the console.
Running the Example
When you run the Flutter app and press the "Do Something" button, you should see log messages in the console, demonstrating the logging functionality added to MyClass via the LoggerMixin.
This example showcases how mixins in Flutter can be used to encapsulate and reuse functionality across different classes, promoting clean and maintainable code.
Application of mixins
LoggerMixin
A mixin to provide logging capabilities.
import 'package:logger/logger.dart';
mixin LoggerMixin {
  final Logger _logger = Logger();
  void logInfo(String message) {
    _logger.i(message);
  }
  void logError(String message) {
    _logger.e(message);
  }
}
class MyClass with LoggerMixin {
  void doSomething() {
    logInfo('Doing something');
  }
}
- ValidationMixin A mixin to provide form validation methods.
 
mixin ValidationMixin {
  bool isValidEmail(String email) {
    return email.contains('@');
  }
  bool isValidPassword(String password) {
    return password.length > 6;
  }
}
class LoginForm with ValidationMixin {
  final String email;
  final String password;
  LoginForm(this.email, this.password);
  bool validate() {
    return isValidEmail(email) && isValidPassword(password);
  }
}
- DisposalMixin A mixin to provide a method to dispose resources.
 
mixin DisposalMixin {
  final List<void Function()> _disposeCallbacks = [];
  void addDisposeCallback(void Function() callback) {
    _disposeCallbacks.add(callback);
  }
  void dispose() {
    for (var callback in _disposeCallbacks) {
      callback();
    }
  }
}
class MyResource with DisposalMixin {
  void initialize() {
    // Initialize resources
    addDisposeCallback(() {
      // Dispose resource
      print('Resource disposed');
    });
  }
}
- StateHelperMixin A mixin to provide common state management methods for stateful widgets.
 
import 'package:flutter/material.dart';
mixin StateHelperMixin<T extends StatefulWidget> on State<T> {
  void showSnackbar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message)));
  }
}
class MyStatefulWidget extends StatefulWidget {
  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> with StateHelperMixin<MyStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('State Helper Mixin Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            showSnackbar('Hello, World!');
          },
          child: Text('Show Snackbar'),
        ),
      ),
    );
  }
}
- ConnectivityMixin A mixin to check network connectivity.
 
import 'package:connectivity_plus/connectivity_plus.dart';
mixin ConnectivityMixin {
  final Connectivity _connectivity = Connectivity();
  Future<bool> isConnected() async {
    var connectivityResult = await _connectivity.checkConnectivity();
    return connectivityResult != ConnectivityResult.none;
  }
}
class MyService with ConnectivityMixin {
  Future<void> fetchData() async {
    if (await isConnected()) {
      // Fetch data
      print('Fetching data...');
    } else {
      print('No internet connection');
    }
  }
}
- NavigationMixin A mixin to provide navigation methods.
 
import 'package:flutter/material.dart';
mixin NavigationMixin<T extends StatefulWidget> on State<T> {
  void navigateTo(Widget page) {
    Navigator.of(context).push(MaterialPageRoute(builder: (context) => page));
  }
}
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with NavigationMixin<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Navigation Mixin Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            navigateTo(SecondPage());
          },
          child: Text('Go to Second Page'),
        ),
      ),
    );
  }
}
class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: Text('This is the second page'),
      ),
    );
  }
}
- ErrorHandlingMixin A mixin to provide error handling methods.
 
mixin ErrorHandlingMixin {
  void handleError(dynamic error) {
    print('An error occurred: $error');
  }
}
class MyErrorProneClass with ErrorHandlingMixin {
  void riskyOperation() {
    try {
      // Simulate an error
      throw Exception('Something went wrong');
    } catch (error) {
      handleError(error);
    }
  }
}
LifecycleMixin
A mixin to provide lifecycle methods, especially useful for handling logic when widgets are initialized and disposed.
import 'package:flutter/widgets.dart';
mixin LifecycleMixin<T extends StatefulWidget> on State<T> {
  @override
  void initState() {
    super.initState();
    onInit();
  }
  @override
  void dispose() {
    onDispose();
    super.dispose();
  }
  void onInit() {
    // Override this method in the class using this mixin
  }
  void onDispose() {
    // Override this method in the class using this mixin
  }
}
class MyStatefulWidget extends StatefulWidget {
  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> with LifecycleMixin<MyStatefulWidget> {
  @override
  void onInit() {
    super.onInit();
    print('Widget Initialized');
  }
  @override
  void onDispose() {
    super.onDispose();
    print('Widget Disposed');
  }
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
- CacheMixin A mixin to provide caching capabilities for data.
 
mixin CacheMixin<T> {
  final Map<String, T> _cache = {};
  void cacheData(String key, T value) {
    _cache[key] = value;
  }
  T? getCachedData(String key) {
    return _cache[key];
  }
  void clearCache() {
    _cache.clear();
  }
}
class DataService with CacheMixin<String> {
  void fetchData() {
    // Fetch and cache data
    cacheData('key1', 'value1');
  }
  String? retrieveData() {
    return getCachedData('key1');
  }
}
- AnimationMixin A mixin to provide common animation utilities.
 
import 'package:flutter/animation.dart';
mixin AnimationMixin<T extends StatefulWidget> on State<T>, SingleTickerProviderStateMixin<T> {
  late AnimationController animationController;
  @override
  void initState() {
    super.initState();
    animationController = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..forward();
  }
  @override
  void dispose() {
    animationController.dispose();
    super.dispose();
  }
}
class AnimatedWidgetExample extends StatefulWidget {
  @override
  _AnimatedWidgetExampleState createState() => _AnimatedWidgetExampleState();
}
class _AnimatedWidgetExampleState extends State<AnimatedWidgetExample> with AnimationMixin<AnimatedWidgetExample> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FadeTransition(
          opacity: animationController,
          child: Text('Hello, World!'),
        ),
      ),
    );
  }
}
- LocalizationMixin A mixin to provide localization capabilities.
 
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
mixin LocalizationMixin {
  String getTranslatedText(BuildContext context, String key) {
    // Implement your localization logic here
    // For example, using a localization package
    return key;
  }
}
class LocalizedWidget extends StatelessWidget with LocalizationMixin {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(getTranslatedText(context, 'title')),
      ),
      body: Center(
        child: Text(getTranslatedText(context, 'hello_world')),
      ),
    );
  }
}
- ThemeMixin A mixin to provide theme management.
 
import 'package:flutter/material.dart';
mixin ThemeMixin<T extends StatefulWidget> on State<T> {
  ThemeData get currentTheme => Theme.of(context);
  bool get isDarkMode => currentTheme.brightness == Brightness.dark;
}
class ThemedWidget extends StatefulWidget {
  @override
  _ThemedWidgetState createState() => _ThemedWidgetState();
}
class _ThemedWidgetState extends State<ThemedWidget> with ThemeMixin<ThemedWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Themed Widget'),
      ),
      body: Center(
        child: Text(
          isDarkMode ? 'Dark Mode' : 'Light Mode',
          style: TextStyle(color: isDarkMode ? Colors.white : Colors.black),
        ),
      ),
    );
  }
}
- StateManagementMixin A mixin to provide state management utilities.
 
mixin StateManagementMixin<T extends StatefulWidget> on State<T> {
  bool _isLoading = false;
  bool get isLoading => _isLoading;
  void setLoading(bool loading) {
    setState(() {
      _isLoading = loading;
    });
  }
}
class StateManagedWidget extends StatefulWidget {
  @override
  _StateManagedWidgetState createState() => _StateManagedWidgetState();
}
class _StateManagedWidgetState extends State<StateManagedWidget> with StateManagementMixin<StateManagedWidget> {
  void loadData() async {
    setLoading(true);
    await Future.delayed(Duration(seconds: 2));
    setLoading(false);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('State Management Mixin'),
      ),
      body: Center(
        child: isLoading
            ? CircularProgressIndicator()
            : ElevatedButton(
                onPressed: loadData,
                child: Text('Load Data'),
              ),
      ),
    );
  }
}
- PermissionMixin A mixin to handle permission requests.
 
import 'package:permission_handler/permission_handler.dart';
mixin PermissionMixin {
  Future<bool> requestPermission(Permission permission) async {
    final status = await permission.request();
    return status == PermissionStatus.granted;
  }
  Future<bool> checkPermission(Permission permission) async {
    final status = await permission.status;
    return status == PermissionStatus.granted;
  }
}
class PermissionWidget extends StatelessWidget with PermissionMixin {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Permission Mixin Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            if (await requestPermission(Permission.camera)) {
              print('Camera permission granted');
            } else {
              print('Camera permission denied');
            }
          },
          child: Text('Request Camera Permission'),
        ),
      ),
    );
  }
}
Coding example of mixins
save the data using flutter secure storage dependency
  final secureStorage = FlutterSecureStorage();
     await secureStorage.write(key: 'orgRoleId', value: orgRoleId.toString()); // Save orgRoleId
Get data using flutter secure storage
  final orgSlug = widget.orgSlug;
     final secureStorage = FlutterSecureStorage();
  final orgRoleId = await secureStorage.read(key: 'orgRoleId');  
     setState(() {
      _userRole = determineUserRole(orgRoleId); // Use the mixin to determine the role
    });
apply logic in mixins dart file
 if (_userRole != 'User') 
              ElevatedButton(
                onPressed: () {                 
                  _showSendMailDialog(context);
                },
                child: Text('Add Email'),
              ),
SizedBox(height: 8),// Row for action icons
                                      Row(
                                        mainAxisAlignment: MainAxisAlignment.end,
                                        children: [
                                           if (_userRole != 'User') 
                                          IconButton(
                                            icon: Icon(Icons.edit, color: Colors.blue),
                                            onPressed: () {
                                              _showEditEmailDialog(emailItem); // Implement your edit logic
                                            },
                                            tooltip: 'Edit Email',
                                          ),
                                           if (_userRole != 'Manager' && _userRole != 'User') 
                                          IconButton(
                                            icon: Icon(Icons.delete, color: Colors.red),
                                            onPressed: () {
                                              _showDeleteEmailDialog(context, emailItem);
                                            },
                                            tooltip: 'Delete Email',
                                          ),
                                        ],
                                      ),
Full code Implementation
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:provider/provider.dart';
import 'package:wizbrand/Screen/Influencer/createemail.dart';
import 'package:wizbrand/model/email.dart';
import 'package:wizbrand/view_modal/organization_view_model.dart';
import 'package:wizbrand/Screen/layout/rolemixins.dart';
import 'package:wizbrand/Screen/layout/drawer.dart';
class EmailScreen extends StatefulWidget {
  final String orgSlug;
  EmailScreen({required this.orgSlug});
  @override
  _EmailScreenState createState() => _EmailScreenState();
}
class _EmailScreenState extends State<EmailScreen> with DrawerMixin, RoleMixin {
  String _userRole = '';
  String? _email;
  TextEditingController _searchController = TextEditingController();
List<EmailModel> _filteredEmails = []; // List to hold filtered emails
  final TextEditingController _emailController = TextEditingController();
  @override
  void initState() {
    super.initState();
    _fetchData();
  }
  Future<void> _fetchData() async {
    final organizationViewModel = Provider.of<OrganizationViewModel>(context, listen: false);
    final credentials = await _getCredentials();
    final email = credentials['email'];
    final orgSlug = widget.orgSlug;
    final secureStorage = FlutterSecureStorage();
    final orgRoleId = await secureStorage.read(key: 'orgRoleId');
    final orgUserId = await secureStorage.read(key: 'orgUserId');
    final orgUserorgId = await secureStorage.read(key: 'orgUserorgId');
    setState(() {
        print(orgRoleId);
      _userRole = determineUserRole(orgRoleId); // Determine the user role
         print("emailscreen role id coming");
       print(_userRole);
    });
    if (email != null && orgSlug.isNotEmpty) {
      await organizationViewModel.getEmailassets(email, orgSlug, orgRoleId.toString(), orgUserId.toString(), orgUserorgId.toString()); // Fetch email assets
   _filteredEmails = organizationViewModel.my_emails; // Initialize with full data
    }
  }
void _filterEmails(String query) {
    final organizationViewModel = Provider.of<OrganizationViewModel>(context, listen: false);
    final allEmails = organizationViewModel.my_emails;
    setState(() {
        _filteredEmails = allEmails.where((emailItem) {
            final emailLower = emailItem.email?.toLowerCase() ?? '';
            final phoneLower = emailItem.phoneNumber?.toLowerCase() ?? '';
            final queryLower = query.toLowerCase();
            return emailLower.contains(queryLower) || phoneLower.contains(queryLower);
        }).toList();
    });
}
  Future<Map<String, String?>> _getCredentials() async {
    final secureStorage = FlutterSecureStorage();
    String? email = await secureStorage.read(key: 'email');
    String? password = await secureStorage.read(key: 'password');
    return {'email': email, 'password': password};
  }
  Future<void> _saveEmail() async {
    final secureStorage = FlutterSecureStorage();
    await secureStorage.write(key: 'email', value: _emailController.text);
    setState(() {
      _email = _emailController.text; // Update displayed email
    });
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('Email saved successfully')),
    );
  }
  @override
  Widget build(BuildContext context) {
    final organizationViewModel = Provider.of<OrganizationViewModel>(context);
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: true,
        backgroundColor: Colors.blue,
        centerTitle: true,
        title: Text(
          'Email - $_userRole', // Display role dynamically in the AppBar
          style: TextStyle(color: Colors.white),
        ),
      ),
      drawer: buildDrawer(context, orgSlug: widget.orgSlug),
      body: buildBaseScreen(
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              SizedBox(height: 20),
              // Mail button at the top
              if (_userRole != 'User') 
              ElevatedButton(
                onPressed: () {                 
                  _showSendMailDialog(context);
                },
                child: Text('Add Email'),
              ),
                    SizedBox(height: 20),
                                Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: TextField(
                          controller: _searchController,
                          decoration: InputDecoration(
                              labelText: 'Search by Email or Phone Number',
                              border: OutlineInputBorder(),
                              prefixIcon: Icon(Icons.search),
                          ),
                          onChanged: (value) {
                              _filterEmails(value); // Call filter method on text change
                          },
                      ),
                    ),
                                // ListView for displaying fetched emails
              Expanded(
                child: organizationViewModel.isLoading
                    ? Center(child: CircularProgressIndicator())
                    : _filteredEmails.isEmpty
                        ? Center(child: Text('No emails found for this organization.'))
                        : ListView.builder(
                            itemCount: _filteredEmails.length,
                              itemBuilder: (context, index) {
                                  final emailItem = _filteredEmails[index];
                              return Card(
                                margin: const EdgeInsets.symmetric(vertical: 8.0),
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10),
                                  side: BorderSide(color: Colors.grey[300]!),
                                ),
                                child: Padding(
                                  padding: const EdgeInsets.all(16.0),
                                  child: Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: [
                                      SizedBox(height: 8),
                                       RichText(
                                      text: TextSpan(
                                        children: [
                                          TextSpan(
                                            text: 'Email: ', // The static part
                                            style: TextStyle(
                                              fontSize: 16,color: Colors.black,
                                              fontWeight: FontWeight.bold, // Bold style for 'Email:'
                                            ),
                                          ),
                                          TextSpan(
                                            text: '${emailItem.email ?? 'No Email Address'}', // The dynamic part
                                            style: TextStyle(
                                              fontSize: 14,color: Colors.black, // Regular size for the email
                                              fontWeight: FontWeight.normal, // Regular font weight for the email
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                      SizedBox(height: 8),
                                          RichText(
                                      text: TextSpan(
                                        children: [
                                          TextSpan(
                                            text: 'Mobile: ', // The static part
                                            style: TextStyle(
                                              fontSize: 16,color: Colors.black,
                                              fontWeight: FontWeight.bold, // Bold style for 'Email:'
                                            ),
                                          ),
                                          TextSpan(
                                            text: '${emailItem.phoneNumber ?? 'No Mobile'}', // The dynamic part
                                            style: TextStyle(
                                              fontSize: 14,color: Colors.black, // Regular size for the email
                                              fontWeight: FontWeight.normal, // Regular font weight for the email
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                      SizedBox(height: 8),
                                          RichText(
                                      text: TextSpan(
                                        children: [
                                          TextSpan(
                                            text: 'Password Hint: ', // The static part
                                            style: TextStyle(
                                              fontSize: 16,color: Colors.black,
                                              fontWeight: FontWeight.bold, // Bold style for 'Email:'
                                            ),
                                          ),
                                          TextSpan(
                                            text: '${emailItem.passwordHint ?? 'No Password Hint'}', // The dynamic part
                                            style: TextStyle(
                                              fontSize: 14,color: Colors.black, // Regular size for the email
                                              fontWeight: FontWeight.normal, // Regular font weight for the email
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                    SizedBox(height: 8),
                                      RichText(
                                      text: TextSpan(
                                        children: [
                                          TextSpan(
                                            text: 'Account Recovery: ', // The static part
                                            style: TextStyle(
                                              fontSize: 16,color: Colors.black,
                                              fontWeight: FontWeight.bold, // Bold style for 'Email:'
                                            ),
                                          ),
                                          TextSpan(
                                            text: '${emailItem.accountRecoveryDetails ?? 'No Account Recovery'}', // The dynamic part
                                            style: TextStyle(
                                              fontSize: 14,color: Colors.black, // Regular size for the email
                                              fontWeight: FontWeight.normal, // Regular font weight for the email
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                      SizedBox(height: 8),// Row for action icons
                                      Row(
                                        mainAxisAlignment: MainAxisAlignment.end,
                                        children: [
                                           if (_userRole != 'User') 
                                          IconButton(
                                            icon: Icon(Icons.edit, color: Colors.blue),
                                            onPressed: () {
                                              _showEditEmailDialog(emailItem); // Implement your edit logic
                                            },
                                            tooltip: 'Edit Email',
                                          ),
                                           if (_userRole != 'Manager' && _userRole != 'User') 
                                          IconButton(
                                            icon: Icon(Icons.delete, color: Colors.red),
                                            onPressed: () {
                                              _showDeleteEmailDialog(context, emailItem);
                                            },
                                            tooltip: 'Delete Email',
                                          ),
                                        ],
                                      ),
                                    ],
                                  ),
                                ),
                              );
                            },
                          ),
              ),
            ],
          ),
        ),
      ),
    );
  }
void _showSendMailDialog(BuildContext context) async {
  // Fetch the parameters from secure storage
  final secureStorage = FlutterSecureStorage();
  final orgRoleId = await secureStorage.read(key: 'orgRoleId');
  final orgUserId = await secureStorage.read(key: 'orgUserId');
  final orgUserorgId = await secureStorage.read(key: 'orgUserorgId');
  await showDialog(
    context: context,
    builder: (BuildContext context) {
      return CreateEmailDialog(
        orgSlug: widget.orgSlug, // Pass the existing parameter
        orgRoleId: orgRoleId!,   // Pass the new parameter
        orgUserId: orgUserId!,   // Pass the new parameter
        orgUserorgId: orgUserorgId!, // Pass the new parameter
      );
    },
  );
}
void _showEditEmailDialog(emailItem) async{
   final secureStorage = FlutterSecureStorage();
  final orgRoleId = await secureStorage.read(key: 'orgRoleId');
  final orgUserId = await secureStorage.read(key: 'orgUserId');
  final orgUserorgId = await secureStorage.read(key: 'orgUserorgId');
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return CreateEmailDialog(   
        orgSlug: widget.orgSlug, // Pass the existing parameter
        orgRoleId: orgRoleId!,   // Pass the new parameter
        orgUserId: orgUserId!,   // Pass the new parameter
        orgUserorgId: orgUserorgId!, 
        email: emailItem.email, // Existing email
        phoneNumber: emailItem.phoneNumber, // Existing phone number
        password: emailItem.password, // Existing password
        passwordHint: emailItem.passwordHint, // Existing password hint
        accountRecoveryDetails: emailItem.accountRecoveryDetails, // Existing recovery details
        id: emailItem.id, // Pass the ID of the email
      );
    },
  );
}
   void _showDeleteEmailDialog(BuildContext context, emailItem) async {
  // Show confirmation dialog
  final confirmed = await showDialog(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text('Delete Email'),
        content: Text('Are you sure you want to delete this Email?'),
        actions: [
          TextButton(
            onPressed: () {
              Navigator.of(context).pop(false); // Cancel action
            },
            child: Text('Cancel'),
          ),
          ElevatedButton(
            onPressed: () {
              Navigator.of(context).pop(true); // Confirm action
            },
            style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
            child: Text('Delete'),
          ),
        ],
      );
    },
  );
  // If confirmed, call the API to delete the project
  if (confirmed == true) {
    final organizationViewModel = Provider.of<OrganizationViewModel>(context, listen: false);
    try {
      // Make API call to delete the project
      await organizationViewModel.deleteEmail(
        emailItem.id, // Pass the project ID for deletion
        widget.orgSlug, // Pass the organization slug if necessary
      );    
      _fetchData(); // Refresh the project list
    } catch (error) {
      print("Error while deleting project: $error");
    }
  }
}
  Widget buildBaseScreen({required Widget body}) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
      ),
      child: body,
    );
  }
  // Helper method to determine user role
}
Reuse App bar action
mixin dart file
import 'package:flutter/material.dart';
import 'package:wizbrand/Screen/Auth/loginscreen.dart';
import 'package:wizbrand/Screen/Influencer/createorg.dart';
import 'package:wizbrand/Screen/Influencer/dashboard.dart';
import 'package:wizbrand/Screen/Influencer/organizationScreen.dart';
import 'package:wizbrand/Screen/layout/basescreen.dart';
mixin NavigationMixin<T extends StatefulWidget> on State<T> {
  Widget buildBaseScreen({required Widget body, required int currentIndex, required String title}) {
    return BaseScreen(
      currentIndex: currentIndex,
      title: title,
      body: body,
    );
  }
  List<Widget> buildAppBarActions(BuildContext context) {
    return [
      IconButton(
        icon: Icon(Icons.home, color: Colors.white),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => HomeScreen()), // Replace HomeScreen with your actual screen
          );
        },
      ),
      IconButton(
        icon: Icon(Icons.business, color: Colors.white),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => OrganizationScreen()), // Replace OrganizationScreen with your actual screen
          );
        },
      ),
    ];
  }
}
Apply reusability in dart file
Include NavigationMixin
class _ProjectScreenState extends State<ProjectScreen> with DrawerMixin, RoleMixin, NavigationMixin {
Include buildAppBarActions
appBar: AppBar(
  automaticallyImplyLeading: true,
  backgroundColor: Colors.blue,
  centerTitle: true,
  title: Text(
    'Projects - $_userRole', // Display role dynamically in the AppBar
    style: TextStyle(color: Colors.white),
  ),
 actions: buildAppBarActions(context),
),
Add parameter currentIndex,title in buildBaseScreen
buildBaseScreen(
            body: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // Your existing body content...
                ],
              ),
            ),
            currentIndex: 0, // Set an appropriate index
            title: 'Projects', // Set the title as needed
          ),
Update Widget buildBaseScreen Your Method:
Widget buildBaseScreen({required Widget body, required int currentIndex, required String title}) {
  return Container(
    decoration: BoxDecoration(
      color: Colors.white,
    ),
    child: Column(
      children: [
        // Optionally, add a title if needed
        Padding(
          padding: const EdgeInsets.all(16.0),
          child: Text(
            title,
            style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
        ),
        Expanded(child: body),
      ],
    ),
  );
}
Top comments (0)