feat: diskon page

This commit is contained in:
efrilm 2025-08-01 15:41:02 +07:00
parent 8c946ce3d9
commit 8e4a289625
4 changed files with 107 additions and 110 deletions

View File

@ -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:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/components/custom_text_field.dart'; import 'package:enaklo_pos/core/components/custom_text_field.dart';
@ -23,19 +24,10 @@ class _FormDiscountDialogState extends State<FormDiscountDialog> {
final discountController = TextEditingController(); final discountController = TextEditingController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return CustomModalDialog(
title: Row( title: widget.data == null ? 'Tambah Diskon' : 'Edit Diskon',
mainAxisAlignment: MainAxisAlignment.spaceBetween, contentPadding: const EdgeInsets.all(16.0),
children: [ child: SingleChildScrollView(
IconButton(
onPressed: () => context.pop(),
icon: const Icon(Icons.close),
),
const Text('Tambah Diskon'),
const Spacer(),
],
),
content: SingleChildScrollView(
child: SizedBox( child: SizedBox(
width: context.deviceWidth / 3, width: context.deviceWidth / 3,
child: Column( child: Column(

View File

@ -1,3 +1,5 @@
import 'package:enaklo_pos/core/components/buttons.dart';
import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/presentation/setting/bloc/discount/discount_bloc.dart'; import 'package:enaklo_pos/presentation/setting/bloc/discount/discount_bloc.dart';
@ -5,7 +7,6 @@ import 'package:enaklo_pos/presentation/setting/bloc/discount/discount_bloc.dart
import '../../home/widgets/custom_tab_bar.dart'; import '../../home/widgets/custom_tab_bar.dart';
import '../dialogs/form_discount_dialog.dart'; import '../dialogs/form_discount_dialog.dart';
import '../models/discount_model.dart'; import '../models/discount_model.dart';
import '../widgets/add_data.dart';
import '../widgets/manage_discount_card.dart'; import '../widgets/manage_discount_card.dart';
import '../widgets/settings_title.dart'; import '../widgets/settings_title.dart';
@ -49,83 +50,94 @@ class _DiscountPageState extends State<DiscountPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SingleChildScrollView( return Column(
child: Column( children: [
mainAxisAlignment: MainAxisAlignment.start, SettingsTitle(
children: [ 'Kelola Diskon',
const SettingsTitle('Kelola Diskon'), subtitle: 'Kelola diskon untuk produk Anda',
const SizedBox(height: 24), actionWidget: [
CustomTabBar( Button.outlined(
tabTitles: const ['Semua'], onPressed: onAddDataTap,
initialTabIndex: 0, label: "Tambah Diskon",
tabViews: [ icon: Icon(Icons.add, color: AppColors.primary),
// SEMUA TAB )
SizedBox( ],
child: BlocBuilder<DiscountBloc, DiscountState>( ),
builder: (context, state) { Expanded(
return state.maybeWhen(orElse: () { child: SingleChildScrollView(
return const Center( child: Column(
child: CircularProgressIndicator(), mainAxisAlignment: MainAxisAlignment.start,
); children: [
}, loaded: (discounts) { CustomTabBar(
return GridView.builder( tabTitles: const ['Semua'],
shrinkWrap: true, initialTabIndex: 0,
itemCount: discounts.length + 1, tabViews: [
physics: const NeverScrollableScrollPhysics(), // SEMUA TAB
gridDelegate: SizedBox(
const SliverGridDelegateWithFixedCrossAxisCount( child: BlocBuilder<DiscountBloc, DiscountState>(
childAspectRatio: 0.85, builder: (context, state) {
crossAxisCount: 3, return state.maybeWhen(orElse: () {
crossAxisSpacing: 30.0, return const Center(
mainAxisSpacing: 30.0, child: CircularProgressIndicator(),
),
itemBuilder: (context, index) {
if (index == 0) {
return AddData(
title: 'Tambah Diskon Baru',
onPressed: onAddDataTap,
); );
} }, loaded: (discounts) {
final item = discounts[index - 1]; return GridView.builder(
return ManageDiscountCard( shrinkWrap: true,
data: item, itemCount: discounts.length,
onEditTap: (){}, physics: const NeverScrollableScrollPhysics(),
); padding:
const EdgeInsets.symmetric(horizontal: 16.0),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) {
final item = discounts[index];
return ManageDiscountCard(
data: item,
onEditTap: () {},
);
},
);
});
// return GridView.builder(
// shrinkWrap: true,
// itemCount: discounts.length + 1,
// physics: const NeverScrollableScrollPhysics(),
// gridDelegate:
// const SliverGridDelegateWithFixedCrossAxisCount(
// childAspectRatio: 0.85,
// crossAxisCount: 3,
// crossAxisSpacing: 30.0,
// mainAxisSpacing: 30.0,
// ),
// itemBuilder: (context, index) {
// if (index == 0) {
// return AddData(
// title: 'Tambah Diskon Baru',
// onPressed: onAddDataTap,
// );
// }
// final item = discounts[index - 1];
// return ManageDiscountCard(
// data: item,
// onEditTap: () => onEditTap(item),
// );
// },
// );
}, },
); ),
}); ),
// return GridView.builder( ],
// shrinkWrap: true,
// itemCount: discounts.length + 1,
// physics: const NeverScrollableScrollPhysics(),
// gridDelegate:
// const SliverGridDelegateWithFixedCrossAxisCount(
// childAspectRatio: 0.85,
// crossAxisCount: 3,
// crossAxisSpacing: 30.0,
// mainAxisSpacing: 30.0,
// ),
// itemBuilder: (context, index) {
// if (index == 0) {
// return AddData(
// title: 'Tambah Diskon Baru',
// onPressed: onAddDataTap,
// );
// }
// final item = discounts[index - 1];
// return ManageDiscountCard(
// data: item,
// onEditTap: () => onEditTap(item),
// );
// },
// );
},
), ),
), ],
], ),
), ),
], ),
), ],
); );
} }
} }

View File

@ -18,11 +18,9 @@ class ManageDiscountCard 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 ManageDiscountCard 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!.replaceAll('.00', '')}%', '${data.value!.replaceAll('.00', '')}%',
@ -48,23 +46,12 @@ class ManageDiscountCard extends StatelessWidget {
), ),
const Spacer(), const Spacer(),
Center( Center(
child: RichText( child: Text(
text: TextSpan( data.name ?? "-",
text: 'Nama Promo : ', style: const TextStyle(
children: [ fontSize: 16,
TextSpan( fontWeight: FontWeight.w600,
text: data.name, color: AppColors.black,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
],
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: AppColors.black,
),
), ),
), ),
), ),

View File

@ -27,6 +27,12 @@ class SettingsTitle extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColors.white, color: AppColors.white,
border: Border(
bottom: BorderSide(
color: AppColors.background,
width: 1.0,
),
),
), ),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,