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

340 lines
12 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/router/app_route.dart';
import 'package:niogu_ecommerce_v1/core/widgets/custom_empty_screen.dart';
import 'package:niogu_ecommerce_v1/features/account/domain/entities/account.dart';
import 'package:niogu_ecommerce_v1/features/account/presentation/providers/account_provider.dart';
import 'package:shimmer/shimmer.dart';
import 'package:sizer/sizer.dart';
import 'package:niogu_ecommerce_v1/core/constant/app_color.dart';
class AddressScreen extends ConsumerWidget {
const AddressScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return LayoutBuilder(
builder: (context, constraints) {
final customerAddressState = ref.watch(
customerAddressControllerProvider,
);
return SafeArea(
top: false,
bottom: true,
right: false,
left: false,
child: Scaffold(
backgroundColor: const Color(0xFFF8F9FA),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0.5,
leading: IconButton(
icon: Icon(
Icons.arrow_back,
size: 7.w,
color: AppColor.primaryColor,
),
onPressed: () => context.pop(),
),
title: Text(
"Alamat Saya",
style: TextStyle(
color: Colors.black,
fontSize: AppFontSize.medium.sp,
fontWeight: FontWeight.bold,
),
),
),
body: Column(
children: [
Expanded(
child: RefreshIndicator(
onRefresh: () async {
await ref
.read(customerAddressControllerProvider.notifier)
.refresh();
},
color: AppColor.primaryColor,
backgroundColor: Colors.white,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.symmetric(vertical: 2.h),
child: Column(
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: 4.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2.5.w),
border: Border.all(color: Colors.grey.shade200),
),
child: customerAddressState.when(
data: (addresses) {
if (addresses.isEmpty) {
return CustomEmptyScreen(
icon: Icons.search_off_outlined,
title: "Belum Ada Alamat",
subtitle: "Tambahkan alamat pertamamu",
height: 40.h,
);
}
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: addresses.length,
separatorBuilder: (context, index) => Divider(
height: 0,
thickness: 1,
color: Colors.grey.shade100,
indent: 4.w,
endIndent: 4.w,
),
itemBuilder: (context, index) {
final address = addresses[index];
return _buildAddressItem(
context,
ref,
address,
);
},
);
},
error: (error, stackTrace) => CustomEmptyScreen(
icon: Icons.cloud_off_outlined,
title: "Terjadi Kesalahan Koneksi",
subtitle: "Tarik ke bawah untuk mencoba lagi",
height: 40.h,
),
loading: () => _buildAddressLoading(),
),
),
if (!customerAddressState.isLoading)
_buildAddAddressButton(context),
],
),
),
),
),
],
),
),
);
},
);
}
Widget _buildAddressItem(
BuildContext context,
WidgetRef ref,
CustomerAddress address,
) {
return InkWell(
onTap: () {},
child: Padding(
padding: EdgeInsets.all(4.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(
address.label,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: AppFontSize.small.sp,
color: Colors.black87,
),
),
/**
if (item['is_utama']) ...[
SizedBox(width: 2.w),
Container(
padding: EdgeInsets.symmetric(
horizontal: 2.w,
vertical: 0.4.h,
),
decoration: BoxDecoration(
color: AppColor.primaryColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(1.w),
border: Border.all(
color: AppColor.primaryColor.withOpacity(0.5),
),
),
child: Text(
"Utama",
style: TextStyle(
color: AppColor.primaryColor,
fontSize: AppFontSize.small.sp,
fontWeight: FontWeight.bold,
),
),
),
],
*/
],
),
TextButton(
onPressed: () {
ref
.read(selectedAddressProvider.notifier)
.state = SelectedAddress(
id: address.uuid,
fullAddress: address.fullAddress,
latitude: address.latitude,
longitude: address.longitude,
);
context.pushNamed(
AppRoute.saveAddressScreen,
extra: address.label,
);
},
child: Text(
"Ubah",
style: TextStyle(
color: AppColor.primaryColor,
fontSize: AppFontSize.small.sp,
fontWeight: FontWeight.w600,
),
),
),
],
),
/**
SizedBox(height: 1.5.h),
Text(
"${item['penerima']} | ${item['telepon']}",
style: TextStyle(
fontSize: AppFontSize.small.sp,
color: Colors.black87,
fontWeight: FontWeight.w500,
),
),
*/
Text(
address.fullAddress,
style: TextStyle(
fontSize: AppFontSize.small.sp,
color: Colors.grey.shade600,
height: 1.4,
),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
],
),
),
);
}
Widget _buildAddAddressButton(BuildContext context) {
return Container(
padding: EdgeInsets.all(4.w),
child: SafeArea(
child: SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
onPressed: () => context.pushNamed(AppRoute.mapAddressScreen),
icon: Icon(
Icons.add_circle_outline,
size: 5.w,
color: AppColor.primaryColor,
),
label: Text(
"Tambah Alamat Baru",
style: TextStyle(
color: AppColor.primaryColor,
fontWeight: FontWeight.bold,
fontSize: AppFontSize.medium.sp,
),
),
style: OutlinedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 1.8.h),
side: const BorderSide(color: AppColor.primaryColor),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(2.5.w),
),
),
),
),
),
);
}
Widget _buildAddressLoading() {
return Shimmer.fromColors(
baseColor: Colors.grey.shade300,
highlightColor: Colors.grey.shade100,
child: ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 5,
separatorBuilder: (context, index) => Divider(
height: 0,
thickness: 1,
color: Colors.grey.shade100,
indent: 4.w,
endIndent: 4.w,
),
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(4.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Skeleton Header (Label & Tombol Ubah)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 20.w,
height: 2.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(1.w),
),
),
Container(
width: 12.w,
height: 2.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(1.w),
),
),
],
),
SizedBox(height: 2.h),
// Skeleton Baris Alamat 1
Container(
width: double.infinity,
height: 1.5.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(1.w),
),
),
SizedBox(height: 1.h),
// Skeleton Baris Alamat 2
Container(
width: 70.w,
height: 1.5.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(1.w),
),
),
],
),
);
},
),
);
}
}