213 lines
7.8 KiB
Dart
213 lines
7.8 KiB
Dart
/// Invoice Section Widget
|
|
///
|
|
/// Optional invoice information section with address selection.
|
|
library;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:worker/core/constants/ui_constants.dart';
|
|
import 'package:worker/features/account/presentation/providers/address_provider.dart';
|
|
|
|
/// Invoice Section
|
|
///
|
|
/// Shows invoice toggle and default address when enabled.
|
|
/// Matches HTML design from checkout.html.
|
|
class InvoiceSection extends HookConsumerWidget {
|
|
const InvoiceSection({super.key, required this.needsInvoice});
|
|
|
|
final ValueNotifier<bool> needsInvoice;
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final colorScheme = Theme.of(context).colorScheme;
|
|
|
|
// Watch the default address
|
|
final defaultAddr = ref.watch(defaultAddressProvider);
|
|
|
|
return Container(
|
|
margin: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
|
padding: const EdgeInsets.all(AppSpacing.md),
|
|
decoration: BoxDecoration(
|
|
color: colorScheme.surface,
|
|
borderRadius: BorderRadius.circular(AppRadius.card),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withValues(alpha: 0.05),
|
|
blurRadius: 8,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Header with Toggle
|
|
Row(
|
|
children: [
|
|
FaIcon(
|
|
FontAwesomeIcons.fileInvoice,
|
|
color: colorScheme.primary,
|
|
size: 16,
|
|
),
|
|
const SizedBox(width: AppSpacing.sm),
|
|
Expanded(
|
|
child: Text(
|
|
'Phát hành hóa đơn',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w600,
|
|
color: colorScheme.onSurface,
|
|
),
|
|
),
|
|
),
|
|
// Toggle Switch
|
|
Switch(
|
|
value: needsInvoice.value,
|
|
onChanged: (value) {
|
|
needsInvoice.value = value;
|
|
},
|
|
activeTrackColor: colorScheme.primary,
|
|
),
|
|
],
|
|
),
|
|
|
|
// Invoice Information (visible when toggle is ON)
|
|
if (needsInvoice.value) ...[
|
|
const SizedBox(height: AppSpacing.md),
|
|
Divider(color: colorScheme.outlineVariant),
|
|
const SizedBox(height: AppSpacing.md),
|
|
|
|
// Address Card
|
|
if (defaultAddr != null)
|
|
InkWell(
|
|
onTap: () {
|
|
// Navigate to addresses page for selection
|
|
context.push('/account/addresses');
|
|
},
|
|
borderRadius: BorderRadius.circular(AppRadius.sm),
|
|
child: Container(
|
|
padding: const EdgeInsets.all(AppSpacing.sm),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: colorScheme.outlineVariant),
|
|
borderRadius: BorderRadius.circular(AppRadius.sm),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Company/Address Title
|
|
Text(
|
|
defaultAddr.addressTitle,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
color: colorScheme.onSurface,
|
|
),
|
|
),
|
|
const SizedBox(height: 4),
|
|
|
|
// Tax Code (if available)
|
|
if (defaultAddr.taxCode != null &&
|
|
defaultAddr.taxCode!.isNotEmpty) ...[
|
|
Text(
|
|
'Mã số thuế: ${defaultAddr.taxCode}',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
],
|
|
|
|
// Phone
|
|
Text(
|
|
'Số điện thoại: ${defaultAddr.phone}',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
|
|
// Email (if available)
|
|
if (defaultAddr.email != null &&
|
|
defaultAddr.email!.isNotEmpty) ...[
|
|
Text(
|
|
'Email: ${defaultAddr.email}',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
],
|
|
|
|
// Address
|
|
Text(
|
|
'Địa chỉ: ${defaultAddr.fullAddress}',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: AppSpacing.sm),
|
|
FaIcon(
|
|
FontAwesomeIcons.chevronRight,
|
|
size: 14,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
)
|
|
else
|
|
// No default address - show button to add
|
|
InkWell(
|
|
onTap: () {
|
|
context.push('/account/addresses');
|
|
},
|
|
borderRadius: BorderRadius.circular(AppRadius.sm),
|
|
child: Container(
|
|
padding: const EdgeInsets.all(AppSpacing.md),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color: colorScheme.primary,
|
|
style: BorderStyle.solid,
|
|
),
|
|
borderRadius: BorderRadius.circular(AppRadius.sm),
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
FaIcon(
|
|
FontAwesomeIcons.plus,
|
|
size: 14,
|
|
color: colorScheme.primary,
|
|
),
|
|
const SizedBox(width: AppSpacing.sm),
|
|
Text(
|
|
'Thêm địa chỉ xuất hóa đơn',
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
color: colorScheme.primary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|