first commit

This commit is contained in:
Sas Andy
2024-10-01 09:37:38 +07:00
commit e3073d9823
268 changed files with 26689 additions and 0 deletions

View File

@@ -0,0 +1,232 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/app/constant.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/screen/dashboard/chart_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../widgets/custom_snackbar_widget.dart';
class ChartScreen extends HookConsumerWidget {
const ChartScreen({super.key, required this.filter});
final ValueNotifier<String> filter;
@override
Widget build(BuildContext context, WidgetRef ref) {
// N = New, S= Send, P= Parsial, D=Done,
final auth = ref.watch(authProvider);
final chartLoading = useState(false);
final total = useState<List<String>>(List.empty());
final dikirim = useState<List<String>>(List.empty());
final dikonfirmasi = useState<List<String>>(List.empty());
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
var fltr = "month";
if (filter.value.toLowerCase() == "bulan") {
fltr = "month";
}
if (filter.value.toLowerCase() == "tahun") {
fltr = "year";
}
ref.read(ChartDataProvider.notifier).ChartData(
token: auth?.token ?? "",
filter: fltr,
company_id: auth?.mUserMCompanyID ?? "");
});
return () {};
}, [filter.value]);
ref.listen(ChartDataProvider, (prev, next) async {
if (next is ChartDataStateLoading) {
chartLoading.value = true;
} else if (next is ChartDataStateError) {
chartLoading.value = false;
SanckbarWidget(context, next.message ?? "", snackbarType.error);
Constant.autoLogout(context: context, msg: next.message ?? "");
} else if (next is ChartDataStateDone) {
total.value = next.model.t ?? [];
dikirim.value = next.model.s ?? [];
dikonfirmasi.value = next.model.y ?? [];
chartLoading.value = false;
}
});
return Scaffold(
body: chartLoading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40))
: Padding(
padding: const EdgeInsets.all(20),
child: LineChart(
LineChartData(
gridData: FlGridData(
show: true,
),
borderData: FlBorderData(
show: true,
border: Border(
top: BorderSide.none,
right: BorderSide.none,
left: BorderSide(color: Colors.grey.shade500),
bottom: BorderSide(color: Colors.grey.shade500))),
backgroundColor: Colors.white,
minX: 0,
minY: 0,
// maxX: 31,
titlesData: FlTitlesData(
rightTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false)),
leftTitles: AxisTitles(
axisNameSize: 30,
axisNameWidget: Text(
"Total",
style: Constant.caption1_400(context: context),
),
sideTitles: SideTitles(
showTitles: true,
reservedSize: 32,
interval: 10,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 10,
child: Text(
value.toInt().toString(),
style:
Constant.caption1_400(context: context),
),
);
},
)),
bottomTitles: AxisTitles(
axisNameSize: 30,
axisNameWidget: Container(
child: Text(
filter.value == "Bulan" ? "Hari" : "Bulan",
style: Constant.caption1_400(context: context),
),
),
sideTitles: SideTitles(
showTitles: true,
reservedSize: 32,
interval: 1,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 10,
child: Text(
style: Constant.caption1_400(
context: context),
value.toInt().toString(),
));
},
))),
lineBarsData: [
// LineChartBarData(
// isCurved: true,
// curveSmoothness: 0.20,
// color: Colors.red,
// barWidth: 4,
// isStrokeCapRound: true,
// dotData: FlDotData(
// checkToShowDot: (spot, barData) {
// if (pending.value.length == 1) {
// return true;
// } else {
// return false;
// }
// },
// ),
// belowBarData: BarAreaData(show: false),
// spots: pending.value.map((e) {
// var sp = e.split("|");
// return FlSpot(
// double.parse(sp[0]), double.parse(sp[1]));
// }).toList()),
LineChartBarData(
isCurved: true,
curveSmoothness: 0.2,
color: Colors.purple,
barWidth: 4,
isStrokeCapRound: true,
dotData: FlDotData(
checkToShowDot: (spot, barData) {
if (dikirim.value.length == 1) {
return true;
} else {
return false;
}
},
),
belowBarData: BarAreaData(show: false),
spots: dikirim.value.map((e) {
var sp = e.split("|");
return FlSpot(
double.parse(sp[0]), double.parse(sp[1]));
}).toList()),
LineChartBarData(
isCurved: true,
curveSmoothness: 0.1,
color: Colors.blue,
barWidth: 4,
isStrokeCapRound: true,
dotData: FlDotData(
checkToShowDot: (spot, barData) {
if (total.value.length == 1) {
return true;
} else {
return false;
}
},
),
belowBarData: BarAreaData(show: false),
spots: total.value.map((e) {
var sp = e.split("|");
return FlSpot(
double.parse(sp[0]), double.parse(sp[1]));
}).toList()),
LineChartBarData(
isCurved: true,
curveSmoothness: 0.20,
color: Colors.green,
barWidth: 4,
isStrokeCapRound: true,
dotData: FlDotData(
checkToShowDot: (spot, barData) {
if (dikonfirmasi.value.length == 1) {
return true;
} else {
return false;
}
},
),
belowBarData: BarAreaData(show: false),
spots: dikonfirmasi.value.map((e) {
var sp = e.split("|");
return FlSpot(
double.parse(sp[0]), double.parse(sp[1]));
}).toList()),
],
extraLinesData: ExtraLinesData(horizontalLines: [
HorizontalLine(
y: 0,
color: Colors.white,
strokeWidth: 1,
dashArray: [5])
])),
// swapAnimationDuration: Duration(milliseconds: 150),
// swapAnimationCurve: Curves.linear,
),
),
);
}
}

View File

@@ -0,0 +1,69 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/chart_data_model.dart';
import 'package:mitra_corporate/repository/dashboard_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
// 3. state provider
final ChartDataProvider =
StateNotifierProvider<ChartDataNotifier, ChartDataState>(
(ref) => ChartDataNotifier(ref: ref));
// 2. notifier
class ChartDataNotifier extends StateNotifier<ChartDataState> {
final Ref ref;
ChartDataNotifier({required this.ref}) : super(ChartDataStateInit());
void ChartData(
{required String token,
required String filter,
required String company_id,
bool isRememberMe = false}) async {
try {
state = ChartDataStateLoading();
final resp = await DashboardRepository(dio: ref.read(dioProvider))
.getChartData(token: token, filter: filter, company_id: company_id);
state = ChartDataStateDone(model: resp);
// print(shared.getString(Constant.bearerName));
} catch (e) {
if (e is BaseRepositoryException) {
state = ChartDataStateError(message: e.message ?? "");
} else {
state = ChartDataStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class ChartDataState extends Equatable {
final DateTime date;
const ChartDataState(this.date);
@override
List<Object?> get props => [date];
}
class ChartDataStateInit extends ChartDataState {
ChartDataStateInit() : super(DateTime.now());
}
class ChartDataStateLoading extends ChartDataState {
ChartDataStateLoading() : super(DateTime.now());
}
class ChartDataStateError extends ChartDataState {
final String? message;
ChartDataStateError({
required this.message,
}) : super(DateTime.now());
}
class ChartDataStateDone extends ChartDataState {
final ChartDataModel model;
ChartDataStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,72 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:mitra_corporate/repository/dashboard_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
// 3. state provider
final DashboardDeliveryProvider =
StateNotifierProvider<DashboardDeliveryNotifier, DashboardDeliveryState>(
(ref) => DashboardDeliveryNotifier(ref: ref));
// 2. notifier
class DashboardDeliveryNotifier extends StateNotifier<DashboardDeliveryState> {
final Ref ref;
DashboardDeliveryNotifier({required this.ref})
: super(DashboardDeliveryStateInit());
void DashboardDelivery(
{required String token,
required String company_id,
bool isRememberMe = false}) async {
try {
state = DashboardDeliveryStateLoading();
final resp = await DashboardRepository(dio: ref.read(dioProvider))
.getOrder(token: token, companyID: company_id);
state = DashboardDeliveryStateDone(model: resp);
// print(shared.getString(Constant.bearerName));
} catch (e) {
if (e is BaseRepositoryException) {
state = DashboardDeliveryStateError(message: e.message ?? "");
} else {
state = DashboardDeliveryStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class DashboardDeliveryState extends Equatable {
final DateTime date;
const DashboardDeliveryState(this.date);
@override
List<Object?> get props => [date];
}
class DashboardDeliveryStateInit extends DashboardDeliveryState {
DashboardDeliveryStateInit() : super(DateTime.now());
}
class DashboardDeliveryStateLoading extends DashboardDeliveryState {
DashboardDeliveryStateLoading() : super(DateTime.now());
}
class DashboardDeliveryStateError extends DashboardDeliveryState {
final String? message;
DashboardDeliveryStateError({
required this.message,
}) : super(DateTime.now());
}
class DashboardDeliveryStateDone extends DashboardDeliveryState {
final List<SuratJalanModel> model;
DashboardDeliveryStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,213 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/screen/dashboard/chart.dart';
// import 'package:syncfusion_flutter_charts/charts.dart';
import '../../app/constant.dart';
import '../../provider/menu_provider.dart';
import '../../widgets/header.dart';
class DashboardScreen extends HookConsumerWidget {
const DashboardScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final isExpand = ref.watch(sideBarExpandProvider);
List<String> chartType = <String>['Tahun', 'Bulan'];
final selectedChartType = useState("Tahun");
return Scaffold(
body: Column(
children: [
Header(),
Padding(
padding: EdgeInsets.all(32.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
// color: Colors.red,
alignment: Alignment.centerLeft,
child: Text('Dashboard',
style: Constant.h3_400(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
//Statistik
Material(
// elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
color: Colors.white,
child: Container(
padding: EdgeInsets.all(20),
// width: Constant.getActualX(context: context, x: 1080),
height: Constant.getActualY(context: context, y: 720),
child: Column(
children: [
Row(
children: [
Text(
"Statistik",
style: Constant.h4_600(context: context),
),
const Spacer(),
// Text(
// "Bulan",
// style: Constant.caption1_400(context: context),
// ),
// Icon(EvaIcons.arrowIosDownward, size: 12),
DropdownButton<String>(
value: selectedChartType.value,
icon: Icon(EvaIcons.arrowIosDownward, size: 12),
elevation: 16,
style: Constant.caption1_400(context: context)
.copyWith(color: Colors.black),
underline: Container(
height: 0,
),
focusColor: Colors.white,
onChanged: (value) {
// This is called when the user selects an item.
selectedChartType.value = value!;
},
items: chartType.map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
],
),
SizedBox(
height:
Constant.getActualX(context: context, x: 4)),
// Row(
// children: [
// Text(
// "Last Update 1 Juli",
// style: Constant.caption1_400(context: context),
// ),
// ],
// ),
// Image.asset(
// 'images/grafik.png',
// width: Constant.getActualX(context: context, x: 1039),
// height: Constant.getActualY(context: context, y: 241),
// ),
SizedBox(
// width:
// Constant.getActualX(context: context, x: 1039),
height:
Constant.getActualY(context: context, y: 550),
child: Row(
children: [
Expanded(
flex: 9,
child: ChartScreen(
filter: selectedChartType,
)),
Expanded(flex: 1, child: Container()),
Expanded(
flex: 2,
child: Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius:
BorderRadius.circular(
5)),
margin:
EdgeInsets.only(right: 10),
),
Text(
"Total Order",
style: Constant.caption1_400(
context: context),
)
],
),
SizedBox(
height: Constant.getActualY(
context: context, y: 16),
),
Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: Colors.purple,
borderRadius:
BorderRadius.circular(
5)),
margin:
EdgeInsets.only(right: 10),
),
Text(
"Dikirim",
style: Constant.caption1_400(
context: context),
)
],
),
SizedBox(
height: Constant.getActualY(
context: context, y: 16),
),
Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: Colors.green,
borderRadius:
BorderRadius.circular(
5)),
margin:
EdgeInsets.only(right: 10),
),
Text(
"Dikonfirmasi",
style: Constant.caption1_400(
context: context),
)
],
),
],
),
)),
],
),
)
],
)),
),
// SizedBox(
// height: Constant.getActualY(context: context, y: 40),
// ),
// //Pengiriman terbaru
// DashboardTabel()
],
),
),
],
),
);
}
}

View File

@@ -0,0 +1,283 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../provider/menu_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import 'dashboard_delivery_provider.dart';
class DashboardTabel extends HookConsumerWidget {
const DashboardTabel({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.read(authProvider);
final dataList = useState<List<SuratJalanModel>>(List.empty());
final loading = useState(false);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
ref.read(DashboardDeliveryProvider.notifier).DashboardDelivery(
token: auth?.token ?? "", company_id: auth?.mUserMCompanyID ?? "");
});
return () {};
}, []);
ref.listen(DashboardDeliveryProvider, (prev, next) async {
if (next is DashboardDeliveryStateLoading) {
loading.value = true;
} else if (next is DashboardDeliveryStateError) {
loading.value = false;
SanckbarWidget(context, next.message ?? "", snackbarType.error);
Constant.autoLogout(context: context, msg: next.message ?? "");
} else if (next is DashboardDeliveryStateDone) {
dataList.value = next.model;
loading.value = false;
}
});
return Material(
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
color: Colors.white,
child: SizedBox(
height: Constant.getActualY(context: context, y: 370),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text('Pengiriman Terbaru',
style: Constant.h4_600(context: context)
.copyWith(color: Constant.textBlack)),
),
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
child: Column(
children: [
Container(
decoration: BoxDecoration(
color: Constant.grey_200,
borderRadius: BorderRadius.circular(8)),
height: Constant.getActualY(context: context, y: 56),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Tanggal",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Nomor Surat Jalan",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Staff PIC",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Tipe Pengiriman",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Tujuan",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Status",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
],
),
)
],
),
),
Container(
height: Constant.getActualY(context: context, y: 160),
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
child: loading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40))
: ListView(
children: dataList.value
.map((e) => Container(
margin: EdgeInsets.symmetric(
vertical: Constant.getActualY(
context: context, y: 10)),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(e.date ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(
e.orderNumber ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(e.pic ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(e.type ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(
e.destination ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.bottomLeft,
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Chip(
backgroundColor:
Constant.yellow_016,
label: SelectableText(
"Proses",
style: Constant.caption1_600(
context: context)
.copyWith(
color: Constant
.textYellow),
),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(8)),
)
// Text("Status",
// style: Constant.body3_600(context: context)),
)),
],
),
))
.toList(),
),
),
Divider(),
Container(
padding: EdgeInsets.only(right: 10),
height: Constant.getActualY(context: context, y: 60),
child: Row(
children: [
Spacer(),
TextButton(
onPressed: () {
ref.read(currentMenuProvider.notifier).state = 3;
},
child: Row(
children: [
Text(
"View All",
style: Constant.body3_600(context: context)
.copyWith(color: Colors.black),
),
Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.black,
size: 17,
)
],
))
],
),
)
],
),
),
);
}
}