step 3 : hapus ai_barcode_scanner, ai barcode, update permission_handler, flutter_map,latlong2

This commit is contained in:
sindhu
2025-04-11 13:39:17 +07:00
parent aa05bb5d51
commit 25fdce45f9
141 changed files with 19594 additions and 165 deletions

126
lib/widget/chip_type.dart Normal file
View File

@@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import '../../app/constant.dart';
class ChipType extends StatelessWidget {
ChipType(
{super.key,
required this.tipe,
required this.name,
required this.isDetailHistory});
final int tipe;
final String name;
bool isDetailHistory = false;
@override
Widget build(BuildContext context) {
switch (tipe) {
case 5:
return Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
decoration: BoxDecoration(
color: Constant.backgroundBlue,
borderRadius: BorderRadius.circular(6)),
child: Text(
name,
overflow: TextOverflow.ellipsis,
style: isDetailHistory
? Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryBlue)
: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryBlue),
),
);
case 1:
return Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
decoration: BoxDecoration(
color: Constant.backgroundOrange,
borderRadius: BorderRadius.circular(6)),
child: Text(
name,
overflow: TextOverflow.ellipsis,
style: isDetailHistory
? Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryOrange)
: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryOrange),
),
);
case 3:
return Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
decoration: BoxDecoration(
color: Constant.backgroundGreen,
borderRadius: BorderRadius.circular(6)),
child: Text(
name,
overflow: TextOverflow.ellipsis,
style: isDetailHistory
? Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryGreen)
: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryGreen),
),
);
case 2:
return Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
decoration: BoxDecoration(
color: Constant.backgroundPurple,
borderRadius: BorderRadius.circular(6)),
child: Text(
name,
overflow: TextOverflow.ellipsis,
style: isDetailHistory
? Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryPurple)
: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryPurple),
),
);
case 4:
return Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
decoration: BoxDecoration(
color: Constant.primaryRed.withOpacity(0.25),
borderRadius: BorderRadius.circular(6)),
child: Text(
name,
overflow: TextOverflow.ellipsis,
style: isDetailHistory
? Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryRed)
: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryRed),
),
);
default:
return Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
decoration: BoxDecoration(
color: Constant.backgroundBlue,
borderRadius: BorderRadius.circular(6)),
child: Text(
name,
overflow: TextOverflow.ellipsis,
style: isDetailHistory
? Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryBlue)
: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.primaryBlue),
),
);
}
}
}

View File

@@ -0,0 +1,248 @@
import 'package:flutter/material.dart';
import '../../app/constant.dart';
// login
class CustomTextFieldLogin extends StatelessWidget {
final String hintText;
final String labelText;
final bool isPassword;
final bool obscureText;
final bool isMaxLine;
final void Function()? onToggle;
final TextEditingController? ctrl;
final void Function(String)? onChange;
final void Function(String)? onSubmitted;
final void Function()? onTap;
final void Function()? onEditingComplete;
final FocusNode? focusNode;
final bool isPrefix;
final bool isError;
final bool isTextArea;
final bool isReadOnly;
final bool hasFocus;
const CustomTextFieldLogin(
{Key? key,
required this.hintText,
required this.labelText,
this.isPassword = false,
this.isMaxLine = false,
this.onToggle,
this.obscureText = false,
this.ctrl,
this.onChange,
this.onSubmitted,
this.focusNode,
this.isPrefix = false,
this.isTextArea = false,
this.isError = false,
this.isReadOnly = false,
this.hasFocus = false,
this.onTap,
this.onEditingComplete})
: super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
autofocus: false,
showCursor: (hasFocus) ? true : false,
readOnly: isReadOnly,
controller: ctrl,
enableInteractiveSelection: false,
style:
Constant.body1(context: context).copyWith(color: Constant.textBlack),
obscureText: obscureText,
onChanged: onChange,
onSubmitted: onSubmitted,
onTap: onTap,
onEditingComplete: onEditingComplete,
focusNode: focusNode,
maxLines: (isTextArea) ? 4 : 1,
cursorColor: Constant.primaryBlue,
decoration: InputDecoration(
// fillColor: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
filled: true,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
width: 2),
borderRadius: BorderRadius.circular(8),
),
enabledBorder: (hasFocus)
? OutlineInputBorder(
// ignore: prefer_const_constructors
borderRadius: BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(
color: Constant.primaryMain,
width: 1,
),
)
: OutlineInputBorder(
// ignore: prefer_const_constructors
borderRadius: BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(
color: Constant.textGrey,
width: 2,
),
),
// hintStyle: Constant.body1_400(context: context)
// .copyWith(color: Constant.textBlack),
// labelStyle: Constant.body3_400(context: context),
hintStyle: Constant.body1(context: context).copyWith(
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey),
// mainkan focus
labelStyle: Constant.body1(context: context).copyWith(
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey),
labelText: labelText,
hintText: hintText,
alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
),
prefixIcon: isPrefix ? const Icon(Icons.search) : null,
prefixStyle: isPrefix ? Constant.body1(context: context) : null,
suffixIcon: isPassword
? IconButton(
alignment: Alignment.centerRight,
onPressed: onToggle,
icon: Icon(
Icons.remove_red_eye,
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
),
iconSize: Constant.getActualY(context: context, y: 24),
)
: null,
),
);
}
}
// selain inputan login
class CustomTextFieldInputan extends StatelessWidget {
final String hintText;
final String labelText;
final bool isPassword;
final bool obscureText;
final bool isMaxLine;
final void Function()? onToggle;
final TextEditingController? ctrl;
final void Function(String)? onChange;
final void Function(String)? onSubmitted;
final void Function()? onTap;
final void Function()? onEditingComplete;
final FocusNode? focusNode;
final bool isPrefix;
final bool isError;
final bool isTextArea;
final bool isReadOnly;
final bool hasFocus;
const CustomTextFieldInputan(
{Key? key,
required this.hintText,
required this.labelText,
this.isPassword = false,
this.isMaxLine = false,
this.onToggle,
this.obscureText = false,
this.ctrl,
this.onChange,
this.onSubmitted,
this.focusNode,
this.isPrefix = false,
this.isTextArea = false,
this.isError = false,
this.isReadOnly = false,
this.hasFocus = true,
this.onTap,
this.onEditingComplete})
: super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
enabled: (isReadOnly == true) ? false : true,
autofocus: false,
showCursor: (hasFocus) ? true : false,
readOnly: (isReadOnly == true) ? true : false,
controller: ctrl,
enableInteractiveSelection: false,
style:
Constant.body1(context: context).copyWith(color: Constant.textBlack),
obscureText: obscureText,
onChanged: onChange,
onSubmitted: onSubmitted,
onTap: (isReadOnly == true) ? null : onTap,
onEditingComplete: onEditingComplete,
focusNode: focusNode,
maxLines: (isTextArea) ? 4 : 1,
cursorColor: Constant.primaryBlue,
decoration: InputDecoration(
// fillColor: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
// filled: true,
disabledBorder: OutlineInputBorder(
// ignore: prefer_const_constructors
borderRadius: BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(
color: Constant.textGrey,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryMain, width: 2),
borderRadius: BorderRadius.circular(8),
),
enabledBorder: (hasFocus)
? OutlineInputBorder(
// ignore: prefer_const_constructors
borderRadius: BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(
color: Constant.primaryMain,
width: 1,
),
)
: OutlineInputBorder(
// ignore: prefer_const_constructors
borderRadius: BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(
color: Constant.textGrey,
width: 1,
),
),
// hintStyle: Constant.body1_400(context: context)
// .copyWith(color: Constant.textBlack),
// labelStyle: Constant.body3_400(context: context),
hintStyle: Constant.body1(context: context).copyWith(
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey),
// mainkan focus
labelStyle: Constant.body1(context: context).copyWith(
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey),
labelText: labelText,
hintText: hintText,
alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
),
prefixIcon: isPrefix ? const Icon(Icons.document_scanner) : null,
prefixStyle: isPrefix ? Constant.body1(context: context) : null,
suffixIcon: isPassword
? IconButton(
alignment: Alignment.centerRight,
onPressed: onToggle,
icon: Icon(
Icons.remove_red_eye,
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
),
iconSize: Constant.getActualY(context: context, y: 24),
)
: null,
),
);
}
}

View File

@@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import '../../app/constant.dart';
class HeaderWidget extends StatelessWidget {
const HeaderWidget({super.key, required this.teks});
final String teks;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
height: Constant.getActualY(context: context, y: 60),
width: double.infinity,
alignment: Alignment.center,
child: Text(
teks,
style: Constant.heading3(context: context)
.copyWith(fontWeight: FontWeight.w600, color: Constant.primaryBlue),
),
);
}
}

View File

@@ -0,0 +1,143 @@
import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../models/work_total_model.dart';
class InformationCard extends StatelessWidget {
const InformationCard(
{super.key,
this.bgColor,
this.elevation = false,
required this.data,
required this.loading});
final Color? bgColor;
final bool? elevation;
final bool loading;
final WorkTotalModel data;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
color: bgColor ?? Colors.white,
// border: Border.all(width: 0),
boxShadow: [
if (elevation == true)
BoxShadow(
color: Colors.grey.shade200,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 2,
),
if (elevation == false)
BoxShadow(
color: Color(0XFF0000000F).withOpacity(0.06),
offset: Offset(0.0, 2), //(x,y)
blurRadius: 30,
),
],
),
height: Constant.getActualY(context: context, y: 112),
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 32),
vertical: Constant.getActualY(context: context, y: 12)),
child: SizedBox(
// color: Colors.blue,
height: Constant.getActualY(context: context, y: 88),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset(
width: Constant.getActualX(context: context, x: 24),
height: Constant.getActualX(context: context, x: 24),
"assets/icon_home_total_yellow.png"),
loading
? SizedBox(
height: Constant.getActualX(context: context, x: 20),
width: Constant.getActualX(context: context, x: 20),
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20))
: Text(
"${data.totalAll}",
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: Constant.body3(context: context)
.copyWith(fontWeight: FontWeight.w600),
),
Text(
"Total",
overflow: TextOverflow.ellipsis,
style: Constant.body3(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textSecondary),
)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Image.asset(
"assets/icon_home_diterima_yellow.png",
width: Constant.getActualX(context: context, x: 24),
height: Constant.getActualX(context: context, x: 24),
),
loading
? SizedBox(
height: Constant.getActualX(context: context, x: 20),
width: Constant.getActualX(context: context, x: 20),
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20))
: Text(
"${data.receive}",
overflow: TextOverflow.ellipsis,
style: Constant.body3(context: context).copyWith(
fontWeight: FontWeight.w600,
),
),
Text(
"Diterima",
overflow: TextOverflow.ellipsis,
style: Constant.body3(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textSecondary),
)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Image.asset(
width: Constant.getActualX(context: context, x: 24),
height: Constant.getActualX(context: context, x: 24),
"assets/icon_home_selesai_yellow.png"),
loading
? SizedBox(
height: Constant.getActualX(context: context, x: 20),
width: Constant.getActualX(context: context, x: 20),
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20))
: Text(
"${data.done}",
overflow: TextOverflow.ellipsis,
style: Constant.body3(context: context).copyWith(
fontWeight: FontWeight.w600,
),
),
Text(
"Selesai",
overflow: TextOverflow.ellipsis,
style: Constant.body3(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textSecondary),
)
],
)
],
),
),
);
}
}

View File

@@ -0,0 +1,89 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/app/constant.dart';
import '/widget/open_pdf_widget.dart';
import '/widget/rpt_date.dart';
import 'package:url_launcher/url_launcher.dart';
class InformationRptCard extends HookConsumerWidget {
final String courierID;
const InformationRptCard(this.courierID, {super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// final Uri url = Uri.parse("http://devone.aplikasi.web.id/");
// final Uri url = Uri.parse("https://www.google.com/");
final Uri url = Uri.parse(
"${Constant.baseBirtUrl}app-birt/run?__report=report/one/rekap/rpt_total_order_kurir.rptdesign&__format=pdf&courierID=40");
Future<void> _launchUrl() async {
print(url);
if (!await launchUrl(url)) {
throw Exception('Could not launch $url');
}
}
return Container(
// padding: EdgeInsets.fromLTRB(
// Constant.getActualY(context: context, y: 30),
// Constant.getActualX(context: context, x: 24),
// Constant.getActualX(context: context, x: 10),
// Constant.getActualY(context: context, y: 30)),
height: Constant.getActualY(context: context, y: 180),
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage("assets/kurir_bg_card.png")),
borderRadius: BorderRadius.circular(20)),
child: Row(
children: [
Expanded(
flex: 5,
child: Padding(
padding: EdgeInsets.fromLTRB(
Constant.getActualY(context: context, y: 30),
Constant.getActualX(context: context, x: 24),
0,
Constant.getActualY(context: context, y: 30)),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Status Total Pekerjaan",
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w700, color: Colors.white),
),
ElevatedButton(
onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
// PdfViewerPage(courierID: courierID),
// ));
// _launchUrl();
RptDate(context, ref, courierID);
},
child: Text(
"Lihat RPT",
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w700,
color: Color(0xff3366FF)),
),
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)),
elevation: 0,
backgroundColor: Colors.white)),
],
),
)),
Expanded(
flex: 7,
child: Container(
// color: Colors.red,
child: Image.asset("assets/kurir_icon_card.png")))
],
),
);
}
}

View File

@@ -0,0 +1,339 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import '/widget/chip_type.dart';
import '../app/constant.dart';
showConfirmCourierDialog(
{required BuildContext context,
required int tipeid,
required String tipe,
required String tipee,
required String tujuann,
required String penerimaa,
required TextEditingController noteKurir,
required VoidCallback okCallback}) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
insetPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 35),
),
title: const Text(
"Konfirmasi Pekerjaan",
style: TextStyle(fontWeight: FontWeight.bold),
),
content: tipe == "Tolak"
? TolakDialog(
tipeid: tipeid,
tipee: tipee,
tujuann: tujuann,
penerimaa: penerimaa,
noteKurir: noteKurir,
)
: TerimaDialog(
tipeid: tipeid,
tipee: tipee,
tujuann: tujuann,
penerimaa: penerimaa),
actions: [
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 15),
vertical: Constant.getActualY(context: context, y: 8)),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
OutlinedButton(
onPressed: () => Navigator.pop(context, 'Cancel'),
style: OutlinedButton.styleFrom(
side: BorderSide(
style: BorderStyle.solid,
color: Constant.textGrey),
shape: RoundedRectangleBorder(
side: BorderSide(
style: BorderStyle.solid,
color: Constant.textPrimary),
borderRadius: BorderRadius.circular(8),
),
),
child: const Text(
"Batal",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black),
)),
tipe == "Tolak"
? ElevatedButton(
onPressed: () {
okCallback();
Navigator.of(context).pop();
},
// onPressed: {} () => Navigator.pop(context, 'OK'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text(
"Tolak",
style: TextStyle(fontWeight: FontWeight.bold),
),
)
: ElevatedButton(
onPressed: () {
okCallback();
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text(
"Terima",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
]),
],
),
)
],
shape: RoundedRectangleBorder(
side: BorderSide(
color: Theme.of(context).colorScheme.outline,
),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
);
});
}
class TerimaDialog extends StatelessWidget {
const TerimaDialog({
super.key,
required this.tipeid,
required this.tipee,
required this.tujuann,
required this.penerimaa,
});
final int tipeid;
final String tipee;
final String tujuann;
final String penerimaa;
@override
Widget build(BuildContext context) {
return Container(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Anda menerima pekerjaan ini ?",
style: Constant.body2(context: context).copyWith(
fontWeight: FontWeight.w400, color: Constant.textPrimary),
),
Container(
margin: const EdgeInsets.fromLTRB(0, 16, 0, 0),
width: double.infinity,
child: Card(
elevation: 2,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Theme.of(context).colorScheme.outline,
),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: Container(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: Text("Tipe",
style: Constant.caption1(context: context))),
Expanded(
flex: 5,
child: ChipType(
tipe: tipeid,
name: tipee,
isDetailHistory: false,
),
)
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: Text("Tujuan",
style: Constant.caption1(context: context))),
Expanded(
flex: 5,
child: Text(tujuann,
style: TextStyle(
color: Constant.textGrey, fontSize: 12)))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: Text("Penerima",
style: Constant.caption1(context: context))),
Expanded(
flex: 5,
child: Text(penerimaa,
style: TextStyle(
color: Constant.textGrey, fontSize: 12)))
],
),
],
),
),
),
),
],
),
),
);
}
}
class TolakDialog extends StatelessWidget {
const TolakDialog({
super.key,
required this.tipeid,
required this.tipee,
required this.tujuann,
required this.penerimaa,
required this.noteKurir,
});
final int tipeid;
final String tipee;
final String tujuann;
final String penerimaa;
final TextEditingController noteKurir;
@override
Widget build(BuildContext context) {
return Container(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Anda menolak pekerjaan ini ?",
style: Constant.body2(context: context).copyWith(
fontWeight: FontWeight.w400, color: Constant.textPrimary),
),
Container(
margin: const EdgeInsets.fromLTRB(0, 16, 0, 25),
width: double.infinity,
child: Card(
elevation: 2,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Theme.of(context).colorScheme.outline,
),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: Container(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: Text("Tipe",
style: Constant.caption1(context: context))),
Expanded(
flex: 5,
child: ChipType(
tipe: tipeid,
name: tipee,
isDetailHistory: false,
),
)
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: Text("Tujuan",
style: Constant.caption1(context: context))),
Expanded(
flex: 5,
child: Text(tujuann,
style: TextStyle(
color: Constant.textGrey, fontSize: 12)))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: Text("Penerima",
style: Constant.caption1(context: context))),
Expanded(
flex: 5,
child: Text(penerimaa,
style: TextStyle(
color: Constant.textGrey, fontSize: 12)))
],
),
],
),
),
),
),
TextField(
controller: noteKurir,
maxLines: 1,
decoration: const InputDecoration(
labelStyle: TextStyle(color: Colors.grey),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
borderRadius: BorderRadius.all(Radius.circular(12))),
labelText: 'Alasan',
),
)
],
),
));
}
}

127
lib/widget/map_dialog.dart Normal file
View File

@@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import '../app/constant.dart';
typedef void MyFunction();
showMapDialog({
required BuildContext context,
required double lat,
required double long,
required MyFunction confirm,
required MyFunction notConfirm,
required String address,
}) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
"Konfirmasi lokasi",
style: Constant.body1(context: context),
),
content: SizedBox(
width: Constant.getActualX(context: context, x: 280),
height: Constant.getActualY(context: context, y: 200),
child: SizedBox(
width: Constant.getActualX(context: context, x: 200),
height: Constant.getActualY(context: context, y: 100),
// child: FlutterMap(
// options: MapOptions(
// center: LatLng(lat, long),
// zoom: 16,
// ),
// nonRotatedChildren: [
// Align(
// alignment: Alignment.bottomLeft,
// child: Text(
// address,
// style: Constant.body1(context: context).copyWith(
// backgroundColor: Colors.black.withOpacity(0.5),
// color: Colors.white),
// ),
// ),
// ],
// children: [
// TileLayer(
// urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
// userAgentPackageName: 'com.example.app',
// ),
// MarkerLayer(
// markers: [
// Marker(
// point: LatLng(lat, long),
// width: 100,
// height: 100,
// builder: (context) => const Icon(
// Icons.location_on,
// color: Colors.red,
// size: 50,
// )),
// ],
// ),
// ],
// ),
child: FlutterMap(
options: MapOptions(
initialCenter: LatLng(lat, long),
initialZoom: 16,
),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'com.example.app',
),
MarkerLayer(
markers: [
Marker(
point: LatLng(lat, long),
width: 100,
height: 100,
child: const Icon(
Icons.location_on,
color: Colors.red,
size: 50,
),
),
],
),
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
address,
style: Constant.body1(context: context).copyWith(
// backgroundColor: Colors.black.withOpacity(0.5),
backgroundColor: Colors.black.withAlpha(128),
color: Colors.white,
),
),
),
),
],
),
),
),
actions: [
OutlinedButton(
onPressed: () {
Navigator.pop(context);
notConfirm();
},
child: const Text("Ulangi"),
),
SizedBox(width: Constant.getActualX(context: context, x: 5)),
ElevatedButton(onPressed: confirm, child: Text("ya")),
SizedBox(width: Constant.getActualX(context: context, x: 10)),
],
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(24)),
),
);
},
);
}

View File

@@ -0,0 +1,81 @@
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import '/widget/snackbar_widget.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import '../app/constant.dart';
class PdfViewerPage extends StatefulWidget {
final String courierID;
final String date;
const PdfViewerPage({super.key, required this.courierID, required this.date});
@override
_PdfViewerPageState createState() => _PdfViewerPageState();
}
class _PdfViewerPageState extends State<PdfViewerPage> {
// final crr = widget.courierID;
late File Pfile;
bool isLoading = false;
Future<void> loadNetwork() async {
try {
setState(() {
isLoading = true;
});
// http: //10.9.9.3/birt/run?__report=report/one/rekap/rpt_total_order_kurir.rptdesign&__format=pdf&courierID=44&date=2023-09-07
var url =
"${Constant.baseBirtUrl}app-birt/run?__report=report/one/rekap/rpt_total_order_kurir.rptdesign&__format=pdf&courierID=${widget.courierID}&date=${widget.date}";
final response = await http.get(Uri.parse(url));
print(url);
final bytes = response.bodyBytes;
final filename = basename(url);
final dir = await getApplicationDocumentsDirectory();
var file = File('${dir.path}/$filename');
await file.writeAsBytes(bytes, flush: true);
setState(() {
Pfile = file;
});
print(Pfile);
setState(() {
isLoading = false;
});
} catch (e) {
print(e);
}
}
@override
void initState() {
loadNetwork();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"${widget.date}",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
body: isLoading
? Center(child: CircularProgressIndicator())
: Container(
child: Center(
child: PDFView(
filePath: Pfile.path,
),
),
),
);
}
}

View File

@@ -0,0 +1,130 @@
import 'package:flutter/material.dart';
import '../app/constant.dart';
typedef void MyFunction();
class PatientCard extends StatelessWidget {
const PatientCard({
super.key,
required this.name,
required this.noLab,
this.note,
this.onClick,
});
final String name;
final String noLab;
final String? note;
final MyFunction? onClick;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onClick,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 20)),
margin: EdgeInsets.symmetric(
vertical: Constant.getActualY(context: context, y: 4),
horizontal: Constant.getActualX(context: context, x: 1)),
// height: Constant.getActualY(context: context, y: 76),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey, width: 0.1),
boxShadow: [
BoxShadow(
color: Colors.grey.shade300,
offset: const Offset(0.0, 1), //(x,y)
blurRadius: 2,
),
],
borderRadius: BorderRadius.circular(12)),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Nomor lab",
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
noLab,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 4),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Nama",
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
name,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
if (note != null)
SizedBox(
height: Constant.getActualY(context: context, y: 4),
),
if (note != null)
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Catatan FO",
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
note ?? "",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
],
),
),
);
}
}

View File

@@ -0,0 +1,282 @@
import 'package:dotted_line/dotted_line.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../models/work_list_model.dart';
import '/screen/work_process_screen/work_process_screen.dart';
import '../../app/constant.dart';
import '../../app/route.dart';
import '../../models/pending_work_model.dart';
import '../provider/current_user_provider.dart';
import 'chip_type.dart';
class PendingCardWidget extends HookConsumerWidget {
const PendingCardWidget({super.key, required this.data});
final PendingWorkModel data;
@override
Widget build(BuildContext context, WidgetRef ref) {
Widget cardValue(String name, String value) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
name,
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400, color: Constant.textPrimary),
),
),
Text(
": ",
style: Constant.caption2(context: context).copyWith(
fontWeight: FontWeight.w400, color: Constant.textPrimary),
),
Expanded(
child: Text(
"${value}",
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400, color: Constant.textPrimary),
),
),
],
);
}
return Container(
margin: EdgeInsets.symmetric(
vertical: Constant.getActualY(context: context, y: 4)),
// color: Colors.blue,
// height: Constant.getActualY(context: context, y: 170),
width: double.infinity,
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey, width: 0.1),
boxShadow: [
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.12),
offset: Offset(0.0, 12), //(x,y)
blurRadius: 24,
spreadRadius: -4),
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.2),
offset: Offset(0.0, 0), //(x,y)
blurRadius: 2,
),
],
borderRadius: BorderRadius.circular(12)),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0.2,
shape: RoundedRectangleBorder(
side: BorderSide(width: 0.1, color: Colors.grey),
borderRadius: BorderRadius.circular(12),
),
backgroundColor: Colors.white,
foregroundColor: Colors.grey),
onPressed: () {
if (data.supervisor == "Dikonfirmasi") {
Navigator.pushNamed(
context,
workProcessRoute,
arguments: DetailWorkProp(
data.tipeid!,
ref.watch(currentUserProvider)?.model.user?.mCourierID ??
"0",
data.id.toString(),
data.noLab.toString(),
data.nama.toString(),
data.note.toString()),
);
}
},
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 18),
vertical: Constant.getActualY(context: context, y: 20)),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ChipType(
tipe: data.tipeid!,
name: data.tipe!,
isDetailHistory: false),
if (data.supervisor == "Dikonfirmasi")
Icon(
Icons.check_circle_outline_rounded,
color: Constant.primaryGreen,
size: 15,
),
if (data.supervisor == "Belum dikonfirmasi")
Icon(
Icons.help_outline_rounded,
color: Constant.primaryOrange,
size: 15,
),
if (data.supervisor == "Ditoalk")
Icon(
Icons.cancel_outlined,
color: Constant.primaryRed,
size: 15,
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
if (data.tipeid == 1)
Column(
children: [
cardValue("Nomot Lab", data.noLab ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Nama", data.nama ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Cabang Pengirim", data.branchname ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Alamat Pengantaran", data.alamat ?? ""),
],
),
if (data.tipeid == 2)
Column(
children: [
cardValue("Nomot Surat Jalan", data.noSuratJalan ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Nama", data.nama ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Cabang Pengirim", data.branchname ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Alamat Pengantaran", data.alamat ?? ""),
],
),
if (data.tipeid == 3)
Column(
children: [
cardValue("Nomot Surat Jalan", data.noSuratJalan ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Nama", data.nama ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Cabang Pengirim", data.branchname ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Alamat Pengantaran", data.alamat ?? ""),
],
),
if (data.tipeid == 4)
Column(
children: [
cardValue("Catatan", data.note ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Pengirim", data.branchaddress ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Penerima", data.alamat ?? ""),
],
),
if (data.tipeid == 5)
Column(
children: [
cardValue("Tujuan", data.nama ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Alamat", data.branchaddress ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Cabang penerima", data.branchname ?? ""),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 16),
),
Row(
children: [
Icon(
Icons.circle_outlined,
color: Colors.grey.shade300,
size: 15,
),
SizedBox(
width: Constant.getActualX(context: context, x: 12),
),
Expanded(
flex: 5,
child: DottedLine(
dashColor: Colors.grey.shade300,
)),
SizedBox(
width: Constant.getActualX(context: context, x: 12),
),
if (data.statusTransaksi == "Baru")
Icon(
Icons.circle_outlined,
color: Constant.primaryBlue,
size: 15,
),
if (data.statusTransaksi == "Proses")
Icon(
Icons.circle_outlined,
color: Constant.primaryYellow,
size: 15,
),
if (data.statusTransaksi == "Done" ||
data.statusTransaksi == "Selesai")
Icon(
Icons.circle_outlined,
color: Constant.primaryGreen,
size: 15,
),
SizedBox(
width: Constant.getActualX(context: context, x: 4),
),
Text(
"${data.statusTransaksi}",
style: Constant.caption2(context: context)
.copyWith(color: Constant.textPrimary),
),
],
)
],
),
),
),
),
),
);
}
}

117
lib/widget/rpt_date.dart Normal file
View File

@@ -0,0 +1,117 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/intl.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../app/constant.dart';
import '../provider/current_user_provider.dart';
import '../screen/home_screen/pending_work_provider.dart';
import '../screen/work_list_screen/work_list_provider.dart';
import 'open_pdf_widget.dart';
Future<void> RptDate(BuildContext context, WidgetRef ref, String courierID) {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text(
'Pilih Tanggal',
style: Constant.heading4(context: context).copyWith(
color: Constant.primaryBlue, fontWeight: FontWeight.w600),
),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12))),
content: HookConsumer(builder: (context, WidgetRef ref, z) {
final dpKey = useState(1);
final dateInput = useTextEditingController(
text: DateFormat('yyyy-MM-dd').format(DateTime.now()));
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
var ky = dpKey.value;
dpKey.value = ky + 1;
});
return () {};
}, []);
return SingleChildScrollView(
child: Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// SizedBox(
// height: Constant.getActualY(context: context, y: 12),
// ),
TextField(
controller: dateInput,
decoration: InputDecoration(
suffixIcon: Icon(Icons.calendar_today),
border: OutlineInputBorder(),
labelText: "Pilih Tanggal" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: DateTime.parse(dateInput.text),
firstDate: DateTime(1950),
initialEntryMode:
DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('yyyy-MM-dd').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
dateInput.text =
formattedDate; //set output date to TextField value.
} else {}
},
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PdfViewerPage(
date: dateInput.text,
courierID: courierID),
));
// print(dateInput.text);
},
style: ElevatedButton.styleFrom(
backgroundColor: Constant.primaryBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
child: Text("Buka Rpt")),
],
),
],
)));
}),
);
},
);
}

View File

@@ -0,0 +1,442 @@
import 'package:flutter/material.dart';
import '../../app/constant.dart';
// define condition START
// ketika textfield terisi
InputBorder enabledBorderFillTextField = OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(
color: Constant.primaryMain,
width: 2,
),
);
// ketika focus
InputBorder enabledBorderFocusTextField = OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(
color: Constant.primaryMain,
width: 2,
),
);
// ketika no action
InputBorder enabledBorderNoAction = OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(
color: Constant.textGrey,
width: 2,
),
);
// color ketika focus
Color colorFocus = Constant.primaryMain;
// define condition END
// color no action
Color colorNoAction = Constant.textGrey;
// Textfield biasa atau common (widget biasa tanpa prefix dan suffix icon)
class SasTextField extends StatelessWidget {
final String hintText;
final String labelText;
final String errorText;
final void Function()? onToggle;
final TextEditingController? controller;
final void Function(String)? onChange;
final void Function(String)? onSubmitted;
final void Function()? onTap;
final void Function()? onEditingComplete;
final FocusNode? focusNode;
final bool isError;
final bool isReadOnly;
final bool hasFocus;
final TextStyle? style;
const SasTextField(
{Key? key,
required this.hintText,
required this.labelText,
this.onToggle,
required this.controller,
this.onChange,
this.onSubmitted,
this.focusNode,
this.isError = false,
this.isReadOnly = false,
this.hasFocus = false,
this.onTap,
this.onEditingComplete,
this.style,
this.errorText = ""})
: super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
autofocus: false,
showCursor: (hasFocus && isReadOnly == false) ? true : false,
readOnly: isReadOnly,
controller: controller,
enableInteractiveSelection: false,
style: style,
onChanged: onChange,
onSubmitted: onSubmitted,
onTap: onTap,
onEditingComplete: onEditingComplete,
focusNode: focusNode,
maxLines: 1,
cursorColor: Constant.primaryBlue,
decoration: InputDecoration(
errorText: (isError) ? errorText : null,
// filled: true,
fillColor: (hasFocus && isReadOnly == false)
? colorFocus
: ((controller?.text != "") && isReadOnly == false)
? colorFocus
: colorNoAction,
// filled: true,
focusedBorder:
(hasFocus && isReadOnly == false) ? enabledBorderFocusTextField : enabledBorderNoAction,
enabledBorder: (controller?.text != "" && isReadOnly == false)
? enabledBorderFillTextField
: (hasFocus && isReadOnly == false)
? enabledBorderFocusTextField
: enabledBorderNoAction,
hintStyle: Constant.body1(context: context).copyWith(
color: (hasFocus && isReadOnly == false)
? colorFocus
: ((controller?.text != "") && isReadOnly == false)
? colorFocus
: colorNoAction,
),
// mainkan focus
labelStyle: Constant.body1(context: context).copyWith(
color: (hasFocus && isReadOnly == false)
? colorFocus
: ((controller?.text != "") && isReadOnly == false)
? colorFocus
: colorNoAction,
),
labelText: labelText,
hintText: hintText,
alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
);
}
}
// Textfield password (widget dengan suffix icon eye)
class SasTextFieldPassword extends StatelessWidget {
final String hintText;
final String labelText;
final String errorText;
final bool obscureText;
final bool isMaxLine;
final void Function()? onToggle;
final TextEditingController? controller;
final void Function(String)? onChange;
final void Function(String)? onSubmitted;
final void Function()? onTap;
final void Function()? onEditingComplete;
final FocusNode? focusNode;
final bool isError;
final bool isReadOnly;
final bool hasFocus;
final TextStyle? style;
const SasTextFieldPassword(
{Key? key,
required this.hintText,
required this.labelText,
this.isMaxLine = false,
this.onToggle,
this.obscureText = false,
required this.controller,
this.onChange,
this.onSubmitted,
this.focusNode,
this.isError = false,
this.isReadOnly = false,
this.hasFocus = false,
this.onTap,
this.onEditingComplete,
this.style,
this.errorText = ""})
: super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
autofocus: false,
showCursor: (hasFocus) ? true : false,
readOnly: isReadOnly,
controller: controller,
// enableInteractiveSelection: false,
style: style,
obscureText: obscureText,
onChanged: onChange,
onSubmitted: onSubmitted,
onTap: onTap,
onEditingComplete: onEditingComplete,
focusNode: focusNode,
maxLines: 1,
cursorColor: Constant.primaryBlue,
decoration: InputDecoration(
// fillColor: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
errorText: (isError) ? errorText : null,
// filled: true,
fillColor: (hasFocus)
? colorFocus
: ((controller?.text != ""))
? colorFocus
: colorNoAction,
// filled: true,
focusedBorder:
(hasFocus) ? enabledBorderFocusTextField : enabledBorderNoAction,
enabledBorder: (controller?.text != "")
? enabledBorderFillTextField
: (hasFocus)
? enabledBorderFocusTextField
: enabledBorderNoAction,
hintStyle: Constant.body1(context: context).copyWith(
color: (hasFocus)
? colorFocus
: ((controller?.text != ""))
? colorFocus
: colorNoAction,
),
// mainkan focus
labelStyle: Constant.body1(context: context).copyWith(
color: (hasFocus)
? colorFocus
: ((controller?.text != ""))
? colorFocus
: colorNoAction,
),
labelText: labelText,
hintText: hintText,
alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
suffixIcon: IconButton(
alignment: Alignment.centerRight,
onPressed: onToggle,
icon: Icon(
Icons.remove_red_eye,
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
),
iconSize: Constant.getActualY(context: context, y: 24),
),
),
);
}
}
// Textfield area (widget seperti text area di html)
class SasTextFieldArea extends StatelessWidget {
final String hintText;
final String labelText;
final void Function()? onToggle;
final TextEditingController? controller;
final void Function(String)? onChange;
final void Function(String)? onSubmitted;
final void Function()? onTap;
final void Function()? onEditingComplete;
final FocusNode? focusNode;
final bool isError;
final bool isReadOnly;
final bool hasFocus;
final TextStyle? style;
const SasTextFieldArea(
{Key? key,
required this.hintText,
required this.labelText,
this.onToggle,
required this.controller,
this.onChange,
this.onSubmitted,
this.focusNode,
this.isError = false,
this.isReadOnly = false,
this.hasFocus = false,
this.onTap,
this.onEditingComplete,
this.style})
: super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
autofocus: false,
showCursor: (hasFocus && isReadOnly == false) ? true : false,
readOnly: isReadOnly,
controller: controller,
enableInteractiveSelection: false,
style: style,
onChanged: onChange,
onSubmitted: onSubmitted,
onTap: onTap,
onEditingComplete: onEditingComplete,
focusNode: focusNode,
maxLines: 4,
cursorColor: Constant.primaryBlue,
decoration: InputDecoration(
fillColor: (hasFocus && isReadOnly == false)
? colorFocus
: ((controller?.text != "") && isReadOnly == false)
? colorFocus
: colorNoAction,
// filled: true,
focusedBorder:
(hasFocus && isReadOnly == false) ? enabledBorderFocusTextField : enabledBorderNoAction,
enabledBorder: (controller?.text != "" && isReadOnly == false)
? enabledBorderFillTextField
: (hasFocus && isReadOnly == false)
? enabledBorderFocusTextField
: enabledBorderNoAction,
hintStyle: Constant.body1(context: context).copyWith(
color: (hasFocus && isReadOnly == false)
? colorFocus
: ((controller?.text != "") && isReadOnly == false)
? colorFocus
: colorNoAction,
),
// mainkan focus
labelStyle: Constant.body1(context: context).copyWith(
color: (hasFocus && isReadOnly == false)
? colorFocus
: ((controller?.text != "") && isReadOnly == false)
? colorFocus
: colorNoAction,
),
labelText: labelText,
hintText: hintText,
alignLabelWithHint: true,
),
);
}
}
// Textfield search (widget dengan suffix icon search)
class SasTextFieldSearch extends StatelessWidget {
final String hintText;
final String labelText;
final String errorText;
final bool obscureText;
final bool isMaxLine;
final void Function()? onPressed;
final TextEditingController? controller;
final void Function(String)? onChange;
final void Function(String)? onSubmitted;
final void Function()? onTap;
final void Function()? onEditingComplete;
final FocusNode? focusNode;
final bool isError;
final bool isReadOnly;
final bool hasFocus;
final TextStyle? style;
const SasTextFieldSearch(
{Key? key,
required this.hintText,
required this.labelText,
this.isMaxLine = false,
this.onPressed,
this.obscureText = false,
required this.controller,
this.onChange,
this.onSubmitted,
this.focusNode,
this.isError = false,
this.isReadOnly = false,
this.hasFocus = false,
this.onTap,
this.onEditingComplete,
this.style,
this.errorText = ""})
: super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
autofocus: false,
showCursor: (hasFocus) ? true : false,
readOnly: isReadOnly,
controller: controller,
// enableInteractiveSelection: false,
style: style,
// obscureText: obscureText,
onChanged: onChange,
onSubmitted: onSubmitted,
onTap: onTap,
onEditingComplete: onEditingComplete,
focusNode: focusNode,
maxLines: 1,
cursorColor: Constant.primaryBlue,
decoration: InputDecoration(
// fillColor: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
errorText: (isError) ? errorText : null,
// filled: true,
fillColor: (hasFocus)
? colorFocus
: ((controller?.text != ""))
? colorFocus
: colorNoAction,
// filled: true,
focusedBorder:
(hasFocus) ? enabledBorderFocusTextField : enabledBorderNoAction,
enabledBorder: (controller?.text != "")
? enabledBorderFillTextField
: (hasFocus)
? enabledBorderFocusTextField
: enabledBorderNoAction,
hintStyle: Constant.body1(context: context).copyWith(
color: (hasFocus)
? colorFocus
: ((controller?.text != ""))
? colorFocus
: colorNoAction,
),
// mainkan focus
labelStyle: Constant.body1(context: context).copyWith(
color: (hasFocus)
? colorFocus
: ((controller?.text != ""))
? colorFocus
: colorNoAction,
),
labelText: labelText,
hintText: hintText,
alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
suffixIcon: IconButton(
alignment: Alignment.centerRight,
onPressed: onPressed,
icon: Icon(
Icons.search_rounded,
color: (hasFocus) ? Constant.primaryMain : Constant.textGrey,
),
iconSize: Constant.getActualY(context: context, y: 24),
),
),
);
}
}

View File

@@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import 'package:top_snackbar_flutter/custom_snack_bar.dart';
import 'package:top_snackbar_flutter/top_snack_bar.dart';
enum snackbarType { error, info, success, warning }
SanckbarWidget(BuildContext context, String msg, snackbarType tipe) {
switch (tipe) {
case snackbarType.error:
return showTopSnackBar(
Overlay.of(context),
CustomSnackBar.error(
message: msg,
),
);
break;
case snackbarType.success:
return showTopSnackBar(
Overlay.of(context),
CustomSnackBar.success(
message: msg,
),
);
break;
case snackbarType.info:
return showTopSnackBar(
Overlay.of(context),
CustomSnackBar.info(
message: msg,
),
);
break;
case snackbarType.warning:
return showTopSnackBar(
Overlay.of(context),
CustomSnackBar.info(
backgroundColor: Colors.orangeAccent,
message: msg,
),
);
break;
default:
return showTopSnackBar(
Overlay.of(context),
CustomSnackBar.info(
message: msg,
),
);
}
}

282
lib/widget/work_card.dart Normal file
View File

@@ -0,0 +1,282 @@
import 'package:dotted_line/dotted_line.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../models/work_list_model.dart';
import '/screen/work_process_screen/work_process_screen.dart';
import '../../app/constant.dart';
import '../../app/route.dart';
import '../../models/pending_work_model.dart';
import '../provider/current_user_provider.dart';
import 'chip_type.dart';
class WorkCardWidget extends HookConsumerWidget {
const WorkCardWidget({super.key, required this.data});
final WorkListModel data;
@override
Widget build(BuildContext context, WidgetRef ref) {
Widget cardValue(String name, String value) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
name,
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400, color: Constant.textPrimary),
),
),
Text(
": ",
style: Constant.caption2(context: context).copyWith(
fontWeight: FontWeight.w400, color: Constant.textPrimary),
),
Expanded(
child: Text(
"${value}",
style: Constant.caption1(context: context).copyWith(
fontWeight: FontWeight.w400, color: Constant.textPrimary),
),
),
],
);
}
return Container(
margin: EdgeInsets.symmetric(
vertical: Constant.getActualY(context: context, y: 4)),
// color: Colors.blue,
// height: Constant.getActualY(context: context, y: 170),
width: double.infinity,
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey, width: 0.1),
boxShadow: [
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.12),
offset: Offset(0.0, 12), //(x,y)
blurRadius: 24,
spreadRadius: -4),
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.2),
offset: Offset(0.0, 0), //(x,y)
blurRadius: 2,
),
],
borderRadius: BorderRadius.circular(12)),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0.2,
shape: RoundedRectangleBorder(
side: BorderSide(width: 0.1, color: Colors.grey),
borderRadius: BorderRadius.circular(12),
),
backgroundColor: Colors.white,
foregroundColor: Colors.grey),
onPressed: () {
if (data.supervisor == "Dikonfirmasi") {
Navigator.pushNamed(
context,
workProcessRoute,
arguments: DetailWorkProp(
data.tipeid!,
ref.watch(currentUserProvider)?.model.user?.mCourierID ??
"0",
data.id.toString(),
data.noLab.toString(),
data.nama.toString(),
data.note.toString()),
);
}
},
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 18),
vertical: Constant.getActualY(context: context, y: 20)),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ChipType(
tipe: data.tipeid!,
name: data.tipe!,
isDetailHistory: false),
if (data.supervisor == "Dikonfirmasi")
Icon(
Icons.check_circle_outline_rounded,
color: Constant.primaryGreen,
size: 15,
),
if (data.supervisor == "Belum dikonfirmasi")
Icon(
Icons.help_outline_rounded,
color: Constant.primaryOrange,
size: 15,
),
if (data.supervisor == "Ditoalk")
Icon(
Icons.cancel_outlined,
color: Constant.primaryRed,
size: 15,
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
if (data.tipeid == 1)
Column(
children: [
cardValue("Nomot Lab", data.noLab ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Nama", data.nama ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Cabang Pengirim", data.branchname ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Alamat Pengantaran", data.alamat ?? ""),
],
),
if (data.tipeid == 2)
Column(
children: [
cardValue("Nomot Surat Jalan", data.noSuratJalan ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Nama", data.nama ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Cabang Pengirim", data.branchname ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Alamat Pengantaran", data.alamat ?? ""),
],
),
if (data.tipeid == 3)
Column(
children: [
cardValue("Nomot Surat Jalan", data.noSuratJalan ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Nama", data.nama ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Cabang Pengirim", data.branchname ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Alamat Pengantaran", data.alamat ?? ""),
],
),
if (data.tipeid == 4)
Column(
children: [
cardValue("Catatan", data.note ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Pengirim", data.branchaddress ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Penerima", data.alamat ?? ""),
],
),
if (data.tipeid == 5)
Column(
children: [
cardValue("Tujuan", data.nama ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Alamat", data.branchaddress ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 5),
),
cardValue("Cabang penerima", data.branchname ?? ""),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 16),
),
Row(
children: [
Icon(
Icons.circle_outlined,
color: Colors.grey.shade300,
size: 15,
),
SizedBox(
width: Constant.getActualX(context: context, x: 12),
),
Expanded(
flex: 5,
child: DottedLine(
dashColor: Colors.grey.shade300,
)),
SizedBox(
width: Constant.getActualX(context: context, x: 12),
),
if (data.statusTransaksi == "Baru")
Icon(
Icons.circle_outlined,
color: Constant.primaryBlue,
size: 15,
),
if (data.statusTransaksi == "Proses")
Icon(
Icons.circle_outlined,
color: Constant.primaryYellow,
size: 15,
),
if (data.statusTransaksi == "Done" ||
data.statusTransaksi == "Selesai")
Icon(
Icons.circle_outlined,
color: Constant.primaryGreen,
size: 15,
),
SizedBox(
width: Constant.getActualX(context: context, x: 4),
),
Text(
"${data.statusTransaksi}",
style: Constant.caption2(context: context)
.copyWith(color: Constant.textPrimary),
),
],
)
],
),
),
),
),
),
);
}
}