feat: tax page
This commit is contained in:
parent
1384253e8a
commit
8c946ce3d9
@ -12,6 +12,7 @@ class CustomModalDialog extends StatelessWidget {
|
|||||||
final double? maxWidth;
|
final double? maxWidth;
|
||||||
final double? minHeight;
|
final double? minHeight;
|
||||||
final double? maxHeight;
|
final double? maxHeight;
|
||||||
|
final EdgeInsets? contentPadding;
|
||||||
|
|
||||||
const CustomModalDialog({
|
const CustomModalDialog({
|
||||||
super.key,
|
super.key,
|
||||||
@ -23,6 +24,7 @@ class CustomModalDialog extends StatelessWidget {
|
|||||||
this.maxWidth,
|
this.maxWidth,
|
||||||
this.minHeight,
|
this.minHeight,
|
||||||
this.maxHeight,
|
this.maxHeight,
|
||||||
|
this.contentPadding,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -100,7 +102,10 @@ class CustomModalDialog extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child,
|
Padding(
|
||||||
|
padding: contentPadding ?? EdgeInsets.zero,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:enaklo_pos/core/components/custom_modal_dialog.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
|
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
|
||||||
|
|
||||||
@ -28,7 +29,8 @@ class _FormTaxDialogState extends State<FormTaxDialog> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
serviceFeeController = TextEditingController(text: widget.serviceChargeValue.toString());
|
serviceFeeController =
|
||||||
|
TextEditingController(text: widget.serviceChargeValue.toString());
|
||||||
taxFeeController = TextEditingController(text: widget.taxValue.toString());
|
taxFeeController = TextEditingController(text: widget.taxValue.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,19 +43,10 @@ class _FormTaxDialogState extends State<FormTaxDialog> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AlertDialog(
|
return CustomModalDialog(
|
||||||
title: Row(
|
title: 'Edit Perhitungan Biaya',
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
contentPadding: const EdgeInsets.all(16.0),
|
||||||
children: [
|
child: SingleChildScrollView(
|
||||||
IconButton(
|
|
||||||
onPressed: () => context.pop(),
|
|
||||||
icon: const Icon(Icons.close),
|
|
||||||
),
|
|
||||||
const Text('Edit Perhitungan Biaya'),
|
|
||||||
const Spacer(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
content: SingleChildScrollView(
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: context.deviceWidth / 3,
|
width: context.deviceWidth / 3,
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -78,12 +71,13 @@ class _FormTaxDialogState extends State<FormTaxDialog> {
|
|||||||
Button.filled(
|
Button.filled(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final taxValue = int.tryParse(taxFeeController.text) ?? 0;
|
final taxValue = int.tryParse(taxFeeController.text) ?? 0;
|
||||||
final serviceChargeValue = int.tryParse(serviceFeeController.text) ?? 0;
|
final serviceChargeValue =
|
||||||
|
int.tryParse(serviceFeeController.text) ?? 0;
|
||||||
|
|
||||||
if (widget.onSave != null) {
|
if (widget.onSave != null) {
|
||||||
widget.onSave!(taxValue, serviceChargeValue);
|
widget.onSave!(taxValue, serviceChargeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.pop();
|
context.pop();
|
||||||
},
|
},
|
||||||
label: 'Simpan',
|
label: 'Simpan',
|
||||||
|
|||||||
@ -31,11 +31,11 @@ class _TaxPageState extends State<TaxPage> {
|
|||||||
serviceChargeValue: serviceChargeValue,
|
serviceChargeValue: serviceChargeValue,
|
||||||
onSave: (newTaxValue, newServiceChargeValue) {
|
onSave: (newTaxValue, newServiceChargeValue) {
|
||||||
context.read<TaxSettingsBloc>().add(
|
context.read<TaxSettingsBloc>().add(
|
||||||
TaxSettingsEvent.updateSettings(
|
TaxSettingsEvent.updateSettings(
|
||||||
taxValue: newTaxValue,
|
taxValue: newTaxValue,
|
||||||
serviceChargeValue: newServiceChargeValue,
|
serviceChargeValue: newServiceChargeValue,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -49,11 +49,11 @@ class _TaxPageState extends State<TaxPage> {
|
|||||||
serviceChargeValue: serviceChargeValue,
|
serviceChargeValue: serviceChargeValue,
|
||||||
onSave: (newTaxValue, newServiceChargeValue) {
|
onSave: (newTaxValue, newServiceChargeValue) {
|
||||||
context.read<TaxSettingsBloc>().add(
|
context.read<TaxSettingsBloc>().add(
|
||||||
TaxSettingsEvent.updateSettings(
|
TaxSettingsEvent.updateSettings(
|
||||||
taxValue: newTaxValue,
|
taxValue: newTaxValue,
|
||||||
serviceChargeValue: newServiceChargeValue,
|
serviceChargeValue: newServiceChargeValue,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -61,91 +61,110 @@ class _TaxPageState extends State<TaxPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SingleChildScrollView(
|
return Column(
|
||||||
child: Column(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
children: [
|
||||||
children: [
|
const SettingsTitle(
|
||||||
const SettingsTitle('Perhitungan Biaya'),
|
'Perhitungan Biaya',
|
||||||
const SizedBox(height: 24),
|
subtitle: 'Biaya Layanan dan Pajak',
|
||||||
BlocBuilder<TaxSettingsBloc, TaxSettingsState>(
|
),
|
||||||
builder: (context, state) {
|
Expanded(
|
||||||
return state.when(
|
child: SingleChildScrollView(
|
||||||
initial: () => const Center(child: CircularProgressIndicator()),
|
child: BlocBuilder<TaxSettingsBloc, TaxSettingsState>(
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
builder: (context, state) {
|
||||||
error: (message) => Center(child: Text('Error: $message')),
|
return state.when(
|
||||||
loaded: (taxModel, serviceChargeValue) {
|
initial: () =>
|
||||||
final items = [
|
const Center(child: CircularProgressIndicator()),
|
||||||
TaxModel(name: 'Biaya Layanan', type: TaxType.layanan, value: serviceChargeValue),
|
loading: () =>
|
||||||
taxModel,
|
const Center(child: CircularProgressIndicator()),
|
||||||
];
|
error: (message) => Center(child: Text('Error: $message')),
|
||||||
|
loaded: (taxModel, serviceChargeValue) {
|
||||||
|
final items = [
|
||||||
|
TaxModel(
|
||||||
|
name: 'Biaya Layanan',
|
||||||
|
type: TaxType.layanan,
|
||||||
|
value: serviceChargeValue),
|
||||||
|
taxModel,
|
||||||
|
];
|
||||||
|
|
||||||
return CustomTabBar(
|
return CustomTabBar(
|
||||||
tabTitles: const ['Layanan', 'Pajak'],
|
tabTitles: const ['Layanan', 'Pajak'],
|
||||||
initialTabIndex: 0,
|
initialTabIndex: 0,
|
||||||
tabViews: [
|
tabViews: [
|
||||||
// LAYANAN TAB
|
// LAYANAN TAB
|
||||||
SizedBox(
|
SizedBox(
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: 2, // Add button + 1 service charge item
|
itemCount: 2, // Add button + 1 service charge item
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
childAspectRatio: 0.85,
|
gridDelegate:
|
||||||
crossAxisCount: 3,
|
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisSpacing: 30.0,
|
childAspectRatio: 0.85,
|
||||||
mainAxisSpacing: 30.0,
|
crossAxisCount: 3,
|
||||||
),
|
crossAxisSpacing: 30.0,
|
||||||
itemBuilder: (context, index) {
|
mainAxisSpacing: 30.0,
|
||||||
if (index == 0) {
|
),
|
||||||
return AddData(
|
itemBuilder: (context, index) {
|
||||||
title: 'Edit Perhitungan',
|
if (index == 0) {
|
||||||
onPressed: () => onAddDataTap(serviceChargeValue, taxModel.value),
|
return AddData(
|
||||||
|
title: 'Edit Perhitungan',
|
||||||
|
onPressed: () => onAddDataTap(
|
||||||
|
serviceChargeValue, taxModel.value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final item = items.firstWhere(
|
||||||
|
(element) => element.type.isLayanan);
|
||||||
|
return ManageTaxCard(
|
||||||
|
data: item,
|
||||||
|
onEditTap: () => onEditTap(
|
||||||
|
item, serviceChargeValue, taxModel.value),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
final item = items.firstWhere((element) => element.type.isLayanan);
|
),
|
||||||
return ManageTaxCard(
|
|
||||||
data: item,
|
|
||||||
onEditTap: () => onEditTap(item, serviceChargeValue, taxModel.value),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
|
||||||
|
|
||||||
// PAJAK TAB
|
// PAJAK TAB
|
||||||
SizedBox(
|
SizedBox(
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: 2, // Add button + 1 tax item
|
itemCount: 2, // Add button + 1 tax item
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
childAspectRatio: 0.85,
|
gridDelegate:
|
||||||
crossAxisCount: 3,
|
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisSpacing: 30.0,
|
childAspectRatio: 0.85,
|
||||||
mainAxisSpacing: 30.0,
|
crossAxisCount: 3,
|
||||||
),
|
crossAxisSpacing: 30.0,
|
||||||
itemBuilder: (context, index) {
|
mainAxisSpacing: 30.0,
|
||||||
if (index == 0) {
|
),
|
||||||
return AddData(
|
itemBuilder: (context, index) {
|
||||||
title: 'Edit Perhitungan',
|
if (index == 0) {
|
||||||
onPressed: () => onAddDataTap(serviceChargeValue, taxModel.value),
|
return AddData(
|
||||||
|
title: 'Edit Perhitungan',
|
||||||
|
onPressed: () => onAddDataTap(
|
||||||
|
serviceChargeValue, taxModel.value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final item = items.firstWhere(
|
||||||
|
(element) => element.type.isPajak);
|
||||||
|
return ManageTaxCard(
|
||||||
|
data: item,
|
||||||
|
onEditTap: () => onEditTap(
|
||||||
|
item, serviceChargeValue, taxModel.value),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
final item = items.firstWhere((element) => element.type.isPajak);
|
),
|
||||||
return ManageTaxCard(
|
|
||||||
data: item,
|
|
||||||
onEditTap: () => onEditTap(item, serviceChargeValue, taxModel.value),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
);
|
||||||
);
|
},
|
||||||
},
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import 'package:flutter/material.dart';
|
|||||||
import '../../../core/components/spaces.dart';
|
import '../../../core/components/spaces.dart';
|
||||||
import '../../../core/constants/colors.dart';
|
import '../../../core/constants/colors.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AddData extends StatelessWidget {
|
class AddData extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final VoidCallback onPressed;
|
final VoidCallback onPressed;
|
||||||
@ -21,18 +19,25 @@ class AddData extends StatelessWidget {
|
|||||||
onTap: onPressed,
|
onTap: onPressed,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
decoration: ShapeDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: RoundedRectangleBorder(
|
color: AppColors.white,
|
||||||
side: const BorderSide(width: 1, color: AppColors.card),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
borderRadius: BorderRadius.circular(19),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Icon(
|
Container(
|
||||||
Icons.add,
|
width: 56.0,
|
||||||
color: AppColors.primary,
|
height: 56.0,
|
||||||
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.primary.withOpacity(0.1),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.add,
|
||||||
|
color: AppColors.primary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SpaceHeight(8.0),
|
const SpaceHeight(8.0),
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@ -18,11 +18,9 @@ class ManageTaxCard extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
decoration: ShapeDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: RoundedRectangleBorder(
|
color: AppColors.white,
|
||||||
side: const BorderSide(width: 1, color: AppColors.card),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
borderRadius: BorderRadius.circular(19),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
@ -36,7 +34,7 @@ class ManageTaxCard extends StatelessWidget {
|
|||||||
margin: const EdgeInsets.only(top: 30.0),
|
margin: const EdgeInsets.only(top: 30.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: AppColors.disabled.withOpacity(0.4),
|
color: AppColors.primary.withOpacity(0.1),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'${data.value}%',
|
'${data.value}%',
|
||||||
@ -48,23 +46,12 @@ class ManageTaxCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Center(
|
Center(
|
||||||
child: RichText(
|
child: Text(
|
||||||
text: TextSpan(
|
data.type.name,
|
||||||
text: 'Nama Promo : ',
|
style: const TextStyle(
|
||||||
children: [
|
fontSize: 16,
|
||||||
TextSpan(
|
fontWeight: FontWeight.w600,
|
||||||
text: data.type.name,
|
color: AppColors.black,
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color: AppColors.black,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user