218 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'package:base_project/data/response/status.dart';
 | 
						|
import 'package:base_project/resources/app_colors.dart';
 | 
						|
import 'package:base_project/routes/route_names.dart';
 | 
						|
import 'package:base_project/utils/image_constant.dart';
 | 
						|
import 'package:base_project/utils/managers/user_manager.dart';
 | 
						|
import 'package:base_project/view/dashboard/profile/edit_profile.dart';
 | 
						|
import 'package:base_project/view_model/profile/profile_view_model.dart';
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:flutter_svg/flutter_svg.dart';
 | 
						|
import 'package:provider/provider.dart';
 | 
						|
 | 
						|
class ProfileView extends StatefulWidget {
 | 
						|
  const ProfileView({super.key});
 | 
						|
 | 
						|
  @override
 | 
						|
  State<ProfileView> createState() => _ProfileViewState();
 | 
						|
}
 | 
						|
 | 
						|
class _ProfileViewState extends State<ProfileView> {
 | 
						|
  late final ProfileViewModel provider;
 | 
						|
 | 
						|
  @override
 | 
						|
  void initState() {
 | 
						|
    super.initState();
 | 
						|
    WidgetsBinding.instance.addPostFrameCallback((_) {
 | 
						|
      provider = Provider.of<ProfileViewModel>(context, listen: false);
 | 
						|
      provider.getProfile();
 | 
						|
      provider.getProfileImg();
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    final textTheme = Theme.of(context).textTheme;
 | 
						|
    final size = MediaQuery.of(context).size;
 | 
						|
    return Scaffold(
 | 
						|
      appBar: AppBar(
 | 
						|
        leading: IconButton(
 | 
						|
          onPressed: () {
 | 
						|
            Navigator.pop(context);
 | 
						|
          },
 | 
						|
          icon: Icon(Icons.adaptive.arrow_back),
 | 
						|
        ),
 | 
						|
        title: const Text("Profile"),
 | 
						|
      ),
 | 
						|
      body: Padding(
 | 
						|
        padding: const EdgeInsets.all(16.0),
 | 
						|
        child: Column(
 | 
						|
          crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
						|
          children: [
 | 
						|
            const SizedBox(height: 20),
 | 
						|
            Consumer<ProfileViewModel>(
 | 
						|
              builder: (context, value, child) {
 | 
						|
                switch (provider.userProfile.status) {
 | 
						|
                  case null:
 | 
						|
                  // TODO: Handle this case.
 | 
						|
                  case Status.LOADING:
 | 
						|
                    return SizedBox(
 | 
						|
                      height: size.height * 0.2,
 | 
						|
                      child: const Center(
 | 
						|
                        child: CircularProgressIndicator.adaptive(
 | 
						|
                          valueColor: AlwaysStoppedAnimation(AppColors.primary),
 | 
						|
                        ),
 | 
						|
                      ),
 | 
						|
                    );
 | 
						|
                  case Status.SUCCESS:
 | 
						|
                    return Column(
 | 
						|
                      children: [
 | 
						|
                        CircleAvatar(
 | 
						|
                          radius: 60,
 | 
						|
                          backgroundColor: AppColors.primary.withOpacity(0.3),
 | 
						|
                          backgroundImage: provider.profileImageBytes != null
 | 
						|
                              ? MemoryImage(provider.profileImageBytes!)
 | 
						|
                              : null,
 | 
						|
                          child: provider.profileImageBytes != null
 | 
						|
                              ? null // Use backgroundImage for the actual image, so child should be null
 | 
						|
                              : SvgPicture.asset(
 | 
						|
                                  ImageConstant
 | 
						|
                                      .userProfileImg, // Placeholder SVG asset
 | 
						|
                                  width: 60, // Adjust to fit the CircleAvatar
 | 
						|
                                  height: 60,
 | 
						|
                                ),
 | 
						|
                        ),
 | 
						|
                        SizedBox(height: size.height * 0.03),
 | 
						|
                        Text(
 | 
						|
                          provider.userProfile.data?.fullName.toString() ??
 | 
						|
                              "N/A",
 | 
						|
                          style: textTheme.headlineSmall?.copyWith(
 | 
						|
                            fontWeight: FontWeight.bold,
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                        const SizedBox(height: 8),
 | 
						|
                        Text(
 | 
						|
                          provider.userProfile.data?.email.toString() ?? "N/A",
 | 
						|
                          style: textTheme.bodyMedium?.copyWith(
 | 
						|
                            color: AppColors.grey,
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                        const SizedBox(height: 8),
 | 
						|
                        Text(
 | 
						|
                          provider.userProfile.data?.mobNo.toString() ?? "N/A",
 | 
						|
                          style: textTheme.bodyMedium?.copyWith(
 | 
						|
                            color: AppColors.grey,
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                      ],
 | 
						|
                    );
 | 
						|
                  case Status.ERROR:
 | 
						|
                    return SizedBox(
 | 
						|
                      height: size.height * 0.2,
 | 
						|
                    );
 | 
						|
                }
 | 
						|
              },
 | 
						|
            ),
 | 
						|
            const SizedBox(height: 24),
 | 
						|
            Expanded(
 | 
						|
              child: ListView(
 | 
						|
                children: [
 | 
						|
                  _buildListTile(
 | 
						|
                    context,
 | 
						|
                    icon: Icons.edit,
 | 
						|
                    title: 'Edit Profile',
 | 
						|
                    trailingIcon: Icons.adaptive.arrow_forward,
 | 
						|
                    onTap: () {
 | 
						|
                      Navigator.push(
 | 
						|
                          context,
 | 
						|
                          MaterialPageRoute(
 | 
						|
                            builder: (context) => EditProfile(
 | 
						|
                              userProfile: provider.userProfile.data!,
 | 
						|
                            ),
 | 
						|
                          ));
 | 
						|
                    },
 | 
						|
                  ),
 | 
						|
                  const Divider(),
 | 
						|
                  _buildListTile(
 | 
						|
                    context,
 | 
						|
                    icon: Icons.lock,
 | 
						|
                    title: 'Change Password',
 | 
						|
                    trailingIcon: Icons.adaptive.arrow_forward,
 | 
						|
                    onTap: () {
 | 
						|
                      Navigator.pushNamed(
 | 
						|
                          context, RouteNames.changePasswordView);
 | 
						|
                    },
 | 
						|
                  ),
 | 
						|
                  const Divider(),
 | 
						|
                  _buildListTile(
 | 
						|
                    context,
 | 
						|
                    icon: Icons.logout,
 | 
						|
                    leadingIconColor: AppColors.error,
 | 
						|
                    title: 'Logout',
 | 
						|
                    //trailingIcon: Icons.adaptive.arrow_forward,
 | 
						|
                    onTap: () async {
 | 
						|
                      showDialog(
 | 
						|
                        context: context,
 | 
						|
                        builder: (BuildContext context) {
 | 
						|
                          return AlertDialog(
 | 
						|
                            title: const Text("Confirm Logout"),
 | 
						|
                            content:
 | 
						|
                                const Text("Are you sure you want to log out?"),
 | 
						|
                            actions: <Widget>[
 | 
						|
                              TextButton(
 | 
						|
                                child: const Text("Cancel"),
 | 
						|
                                onPressed: () {
 | 
						|
                                  Navigator.of(context)
 | 
						|
                                      .pop(); // Dismiss the dialog
 | 
						|
                                },
 | 
						|
                              ),
 | 
						|
                              TextButton(
 | 
						|
                                child: const Text("Log Out"),
 | 
						|
                                onPressed: () async {
 | 
						|
                                  await UserManager().clearUser();
 | 
						|
                                  Navigator.of(context)
 | 
						|
                                      .pop(); // Dismiss the dialog
 | 
						|
                                  Navigator.pushReplacementNamed(
 | 
						|
                                      context, RouteNames.loginView);
 | 
						|
                                },
 | 
						|
                              ),
 | 
						|
                            ],
 | 
						|
                          );
 | 
						|
                        },
 | 
						|
                      );
 | 
						|
                    },
 | 
						|
                  ),
 | 
						|
                ],
 | 
						|
              ),
 | 
						|
            ),
 | 
						|
          ],
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget _buildListTile(
 | 
						|
    BuildContext context, {
 | 
						|
    required IconData icon,
 | 
						|
    Color? leadingIconColor,
 | 
						|
    required String title,
 | 
						|
    IconData? trailingIcon,
 | 
						|
    required VoidCallback onTap,
 | 
						|
  }) {
 | 
						|
    return ListTile(
 | 
						|
      contentPadding: const EdgeInsets.symmetric(vertical: 8.0),
 | 
						|
      leading: Icon(
 | 
						|
        icon,
 | 
						|
        color: leadingIconColor ?? AppColors.primary,
 | 
						|
      ),
 | 
						|
      title: Text(
 | 
						|
        title,
 | 
						|
      ),
 | 
						|
      trailing: Icon(
 | 
						|
        trailingIcon,
 | 
						|
        color: AppColors.primary,
 | 
						|
      ),
 | 
						|
      onTap: onTap,
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |