342 lines
11 KiB
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,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|