QueenFruits/Mobile Commerce/lib/features/account/presentation/screens/account_screen.dart

342 lines
11 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:niogu_ecommerce_v1/core/constant/app_font_size.dart';
import 'package:niogu_ecommerce_v1/core/errors/exceptions.dart';
import 'package:niogu_ecommerce_v1/core/providers/app_provider.dart';
import 'package:niogu_ecommerce_v1/core/router/app_route.dart';
import 'package:niogu_ecommerce_v1/core/system/system_secure.dart';
import 'package:niogu_ecommerce_v1/core/system/system_setting.dart';
import 'package:niogu_ecommerce_v1/core/utils/log_message.dart';
import 'package:niogu_ecommerce_v1/core/widgets/custom_snackbar.dart';
import 'package:niogu_ecommerce_v1/core/widgets/custom_text_form_field.dart';
import 'package:niogu_ecommerce_v1/features/account/presentation/providers/account_provider.dart';
import 'package:niogu_ecommerce_v1/features/account/presentation/screens/account_logout_screen.dart';
import 'package:sizer/sizer.dart';
import 'package:niogu_ecommerce_v1/core/constant/app_color.dart';
class AccountScreen extends ConsumerStatefulWidget {
const AccountScreen({super.key});
@override
ConsumerState<AccountScreen> createState() => _AccountScreenState();
}
class _AccountScreenState extends ConsumerState<AccountScreen> {
final _nameController = TextEditingController();
final _emailController = TextEditingController();
final _phoneNumberController = TextEditingController();
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_fetchCustomerInfo();
});
}
@override
void dispose() {
// TODO: implement dispose
_nameController.dispose();
_emailController.dispose();
_phoneNumberController.dispose();
super.dispose();
}
Future<void> _setCustomerInfo() async {
final customerId = await SystemSetting.getCurrentCustomerId();
final customerName = await SystemSetting.getCurrentCustomerName();
final customerEmail = await SystemSetting.getCurrentCustomerEmail();
final customerPhone = await SystemSetting.getCurrentCustomerPhone();
ref.read(currentCustomerIdProvider.notifier).state = customerId;
ref.read(currentCustomerNameProvider.notifier).state = customerName;
ref.read(currentCustomerEmailProvider.notifier).state = customerEmail;
ref.read(currentCustomerPhoneProvider.notifier).state = customerPhone;
ref.read(currentStatusLoginProvider.notifier).state = true;
}
Future<void> _fetchCustomerInfo() async {
final name = ref.read(currentCustomerNameProvider);
final email = ref.read(currentCustomerEmailProvider);
final phone = ref.read(currentCustomerPhoneProvider);
_nameController.text = name ?? '';
_emailController.text = email ?? '';
_phoneNumberController.text = phone ?? '';
}
Future<void> _updateCustomer() async {
try {
final name = _nameController.text.trim();
await ref.read(customerControllerProvider.notifier).updateCustomer(name);
if (!mounted) return;
await _setCustomerInfo();
await _fetchCustomerInfo();
CustomSnackbar.showSuccess(context, "Informasi akun berhasil diperbarui");
} on ServerException catch (e, st) {
LogMessage.log.e(e.toString(), error: e, stackTrace: st);
CustomSnackbar.showError(context, "Terjadi kesalahan");
}
}
Future<void> _logout() async {
await SystemSecure.deleteAccessToken();
await SystemSetting.clear();
ref.read(currentCustomerIdProvider.notifier).state = null;
ref.read(currentCustomerNameProvider.notifier).state = null;
ref.read(currentCustomerEmailProvider.notifier).state = null;
ref.read(currentCustomerPhoneProvider.notifier).state = null;
ref.read(currentStatusLoginProvider.notifier).state = false;
CustomSnackbar.showSuccess(context, "Berhasil keluar");
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
final isLoggedIn = ref.watch(currentStatusLoginProvider);
if (!isLoggedIn) return const AccountLogoutScreen();
final updateState = ref.watch(customerControllerProvider);
return SafeArea(
top: false,
bottom: true,
right: false,
left: false,
child: Scaffold(
backgroundColor: const Color(0xFFF8F9FA),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
centerTitle: true,
title: Text(
"Informasi Akun",
style: TextStyle(
color: Colors.black,
fontSize: AppFontSize.medium.sp,
fontWeight: FontWeight.bold,
),
),
),
body: RefreshIndicator(
onRefresh: _fetchCustomerInfo,
color: AppColor.primaryColor,
backgroundColor: Colors.white,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.all(5.w),
child: Column(
children: [
Center(
child: CircleAvatar(
radius: 12.w,
backgroundColor: Colors.grey.shade200,
child: Icon(
Icons.person,
size: 15.w,
color: Colors.grey.shade400,
),
),
),
SizedBox(height: 4.h),
CustomTextFormField(
label: "Nama",
hint: "John Doe",
controller: _nameController,
prefixIcon: Icons.person_outline,
),
SizedBox(height: 2.h),
CustomTextFormField(
label: "Email",
hint: ".@gmail.com",
controller: _emailController,
keyboardType: TextInputType.emailAddress,
prefixIcon: Icons.email_outlined,
readOnly: true,
),
SizedBox(height: 2.h),
CustomTextFormField(
label: "No. Whatsapp",
hint: "081234567890",
controller: _phoneNumberController,
prefixIcon: Icons.phone_android,
readOnly: true,
),
SizedBox(height: 2.h),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: updateState.isLoading
? null
: _updateCustomer,
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.primaryColor,
padding: EdgeInsets.symmetric(vertical: 1.8.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(2.5.w),
),
elevation: 0,
disabledBackgroundColor: Colors.grey.shade300,
),
child: Text(
"Simpan Perubahan",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: AppFontSize.medium.sp,
color: Colors.white,
),
),
),
),
SizedBox(height: 4.h),
_buildAccountMenu(
icon: Icons.lock_outline,
title: "Ubah Password",
subtitle: "Perbarui password untuk keamanan",
backgroundColor: Colors.blue.withOpacity(0.1),
iconColor: Colors.blue,
titleColor: Colors.black87,
onTap: () {
context.pushNamed(AppRoute.changePasswordScreen);
},
),
SizedBox(height: 1.5.h),
_buildAccountMenu(
icon: Icons.location_on_outlined,
title: "Alamat Saya",
subtitle: "Kelola alamat pengiriman",
backgroundColor: AppColor.primaryColor.withOpacity(0.1),
iconColor: AppColor.primaryColor,
titleColor: Colors.black87,
onTap: () => context.pushNamed(AppRoute.addressScreen),
),
SizedBox(height: 1.5.h),
_buildAccountMenu(
icon: Icons.logout,
title: "Keluar",
subtitle: "Akhiri sesi akun anda",
backgroundColor: Colors.red.shade50,
iconColor: Colors.red,
titleColor: Colors.red,
onTap: _logout,
),
SizedBox(height: 15.h),
],
),
),
),
),
);
},
);
}
Widget _buildAccountMenu({
required IconData icon,
required String title,
required String subtitle,
required Color backgroundColor,
required Color iconColor,
required Color titleColor,
required VoidCallback onTap,
}) {
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(2.5.w),
child: Container(
padding: EdgeInsets.all(4.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2.5.w),
border: Border.all(color: Colors.grey.shade100),
),
child: Row(
children: [
Container(
padding: EdgeInsets.all(2.w),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(2.w),
),
child: Icon(icon, color: iconColor, size: 5.w),
),
SizedBox(width: 4.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: AppFontSize.small.sp,
color: titleColor,
),
),
Text(
subtitle,
style: TextStyle(
fontSize: (AppFontSize.small - 1.25).sp,
color: Colors.grey.shade500,
),
),
],
),
),
Icon(
Icons.arrow_forward_ios,
size: 3.5.w,
color: Colors.grey.shade400,
),
],
),
),
);
}
}