first commit

This commit is contained in:
Sas Andy
2025-02-04 19:39:14 +07:00
commit 541d84755c
179 changed files with 9390 additions and 0 deletions

125
lib/app/constant.dart Normal file
View File

@@ -0,0 +1,125 @@
import 'package:flutter/material.dart';
class Constant {
static double designHeight = 1080;
static double designWidth = 1920;
// url
// static String baseUrl = "http://devone.aplikasi.web.id/one-api/";
static String baseUrl = 'a';
static String baseSocket = 'a';
static Color textBlack = const Color(0xff212B36);
static Color red1 = const Color(0xff0C00AC);
static Color red2 = const Color(0xff004AAC);
static Color textRed = const Color(0xff0C00AC);
// checkbox color
static Color checkboxActive = const Color(0xff0C00AC);
static Color checkboxCheck = Colors.white;
static Color checkboxSelected = Colors.red.shade100;
static TextStyle h1({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 68),
fontWeight: FontWeight.w700,
);
}
static TextStyle S75({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 80),
fontWeight: FontWeight.w700,
);
}
static TextStyle h2({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 30),
fontWeight: FontWeight.w700,
);
}
static TextStyle h2LayananDokter({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 40),
fontWeight: FontWeight.w700,
);
}
static TextStyle S50({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 50),
fontWeight: FontWeight.w700,
);
}
static TextStyle body_1({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 44),
fontWeight: FontWeight.w700,
);
}
static TextStyle body_big({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 70),
fontWeight: FontWeight.w700,
);
}
static TextStyle body_2({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 40),
fontWeight: FontWeight.w700,
);
}
static TextStyle body_3({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 32),
fontWeight: FontWeight.w700,
);
}
static TextStyle subTitle({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 22),
fontWeight: FontWeight.w600,
);
}
static TextStyle label({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 16),
fontStyle: FontStyle.italic);
}
static TextStyle normal({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 16),
);
}
//size convertion
static double getActualX({
required BuildContext context,
required double x,
}) {
return x / designWidth * MediaQuery.of(context).size.width;
}
static double getActualY({
required BuildContext context,
required double y,
}) {
return y / designHeight * MediaQuery.of(context).size.height;
}
static setBaseUrl(String text) {
// baseUrl = "http://devone.aplikasi.web.id/one-api/";
text = "devcpone.aplikasi.web.id";
baseUrl = "https://$text/one-api/";
baseSocket = text;
}
}

38
lib/app/route.dart Normal file
View File

@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:queuedisplay/screen/customer_service_dedicatedv2.dart';
import 'package:queuedisplay/screen/settings/setting_screen_counter_dedicated.dart';
const customerServiceDedicatedRoute = '/customerServiceDedicatedRoute';
const layananDokterRoute = '/layananDokterScreenRoute';
const pengambilanDarahRoute = '/pengambilanDarahScreenRoute';
const rontgenUsgRoute = '/rontgenUsgScreenRoute';
const settingRoute = '/settingRoute';
class AppRoute {
static Route<dynamic>? generateRoute(RouteSettings settings) {
if (settings.name == settingRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
padding: const EdgeInsets.all(0),
),
child: const SettingScreenCounterDedicated());
});
}
if (settings.name == customerServiceDedicatedRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
padding: const EdgeInsets.all(0),
),
child: CustomerServiceDedicatedV2());
});
}
return null;
}
}

31
lib/main.dart Normal file
View File

@@ -0,0 +1,31 @@
import 'dart:html';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:queuedisplay/app/route.dart';
import 'app/constant.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
Constant.setBaseUrl(window.location.host);
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Display Counter',
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.red, fontFamily: "Poppins"),
// initialRoute: layananDokterRoute,
// initialRoute: customerServiceRoute,
initialRoute: settingRoute,
// initialRoute: customerServiceDedicatedRoute,
onGenerateRoute: AppRoute.generateRoute);
}
}

View File

@@ -0,0 +1,60 @@
class BranchModel {
String? mBranchID;
String? mBranchCode;
String? mBranchCodeLab;
String? mBranchName;
String? mBranchAddress;
String? mBranchIsActive;
String? mBranchCreated;
String? mBranchCreatedUserID;
String? mBranchLastUpdated;
String? mBranchLastUpdatedUserID;
String? mBranchDeleted;
String? mBranchDeletedUserID;
BranchModel(
{this.mBranchID,
this.mBranchCode,
this.mBranchCodeLab,
this.mBranchName,
this.mBranchAddress,
this.mBranchIsActive,
this.mBranchCreated,
this.mBranchCreatedUserID,
this.mBranchLastUpdated,
this.mBranchLastUpdatedUserID,
this.mBranchDeleted,
this.mBranchDeletedUserID});
BranchModel.fromJson(Map<String, dynamic> json) {
mBranchID = json['M_BranchID'];
mBranchCode = json['M_BranchCode'];
mBranchCodeLab = json['M_BranchCodeLab'];
mBranchName = json['M_BranchName'];
mBranchAddress = json['M_BranchAddress'];
mBranchIsActive = json['M_BranchIsActive'];
mBranchCreated = json['M_BranchCreated'];
mBranchCreatedUserID = json['M_BranchCreatedUserID'];
mBranchLastUpdated = json['M_BranchLastUpdated'];
mBranchLastUpdatedUserID = json['M_BranchLastUpdatedUserID'];
mBranchDeleted = json['M_BranchDeleted'];
mBranchDeletedUserID = json['M_BranchDeletedUserID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['M_BranchID'] = this.mBranchID;
data['M_BranchCode'] = this.mBranchCode;
data['M_BranchCodeLab'] = this.mBranchCodeLab;
data['M_BranchName'] = this.mBranchName;
data['M_BranchAddress'] = this.mBranchAddress;
data['M_BranchIsActive'] = this.mBranchIsActive;
data['M_BranchCreated'] = this.mBranchCreated;
data['M_BranchCreatedUserID'] = this.mBranchCreatedUserID;
data['M_BranchLastUpdated'] = this.mBranchLastUpdated;
data['M_BranchLastUpdatedUserID'] = this.mBranchLastUpdatedUserID;
data['M_BranchDeleted'] = this.mBranchDeleted;
data['M_BranchDeletedUserID'] = this.mBranchDeletedUserID;
return data;
}
}

View File

@@ -0,0 +1,70 @@
import 'package:equatable/equatable.dart';
class Counter extends Equatable {
// int id;
// String name;
// String code;
// bool value;
// int priority;
// String isConsultDoctor;
// String doctorName;
// String? img;
int counterID;
String? counterCode;
String? counterIP;
String? counterIsDedicated;
String? counterLocationID;
String? counterMaxQueue;
String? counterIsActive;
String? locationID;
String? locationName;
String? serviceID;
bool value;
Counter({
// required this.name,
// required this.id,
// required this.priority,
// required this.isConsultDoctor,
// this.doctorName = '',
// this.value = false,
// this.img,
// required this.code
required this.counterCode,
required this.counterID,
required this.counterIP,
required this.counterIsDedicated,
required this.counterMaxQueue,
required this.counterIsActive,
required this.locationID,
required this.locationName,
required this.serviceID,
this.value = false,
});
Counter.fromJson(Map<String, dynamic> json)
: counterID = int.parse(json['counterID']),
counterCode = json['counterCode'].toString(),
counterIP = json['counterIP'].toString(),
value = false,
counterIsDedicated = json['counterIsDedicated'].toString(),
counterMaxQueue = json['counterMaxQueue'].toString(),
locationID = json['locationID'].toString(),
locationName = json['locationName'].toString(),
serviceID = json['serviceID'].toString(),
counterIsActive = json['counterIsActive'].toString();
Map<String, dynamic> toJson() => {
'counterID': counterID,
'counterCode': counterCode,
'counterIP': counterIP,
'counterIsDedicated': counterIsDedicated,
'counterMaxQueue': counterMaxQueue,
'counterIsActive': counterIsActive,
'locationID': locationID,
'locationName': locationName,
'serviceID': serviceID,
'value': value
};
@override
List<Object?> get props => [counterID];
}

View File

@@ -0,0 +1,161 @@
import 'package:equatable/equatable.dart';
class DisplayCounterDedicatedModelV2 extends Equatable {
late List<NotServed> notServed;
late List<Served> served;
late List<Call> call;
DisplayCounterDedicatedModelV2(
{required this.notServed, required this.served, required this.call});
DisplayCounterDedicatedModelV2.fromJson(Map<String, dynamic> json) {
if (json['not_served'] != null) {
notServed = [];
json['not_served'].forEach((v) {
notServed.add(NotServed.fromJson(v));
});
}
if (json['served'] != null) {
served = [];
json['served'].forEach((v) {
served.add(Served.fromJson(v));
});
}
if (json['call'] != null) {
call = [];
json['call'].forEach((v) {
call.add(Call.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
if (this.notServed != null) {
data['not_served'] = this.notServed.map((v) => v.toJson()).toList();
}
if (this.served != null) {
data['served'] = this.served.map((v) => v.toJson()).toList();
}
return data;
}
@override
List<Object?> get props => [notServed, served];
}
class NotServed extends Equatable {
late String queueID;
late String statusID;
late String queueNumber;
late String orderStatus;
late String skipQueue;
NotServed(
{required this.queueID,
required this.statusID,
required this.queueNumber,
required this.orderStatus,
required this.skipQueue});
NotServed.fromJson(Map<String, dynamic> json) {
queueID = json['queueID'];
statusID = json['statusID'];
queueNumber = json['queueNumber'];
orderStatus = json['order_status'];
skipQueue = json['skipQueue'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['queueID'] = this.queueID;
data['statusID'] = this.statusID;
data['queueNumber'] = this.queueNumber;
data['order_status'] = this.orderStatus;
data['skipQueue'] = this.skipQueue;
return data;
}
@override
List<Object?> get props => [queueID, statusID, queueNumber, orderStatus];
}
class Served extends Equatable {
late String queueID;
late String statusID;
late String queueNumber;
late String queueCounterID;
late String counterCode;
late String orderStatus;
Served(
{required this.queueID,
required this.statusID,
required this.queueNumber,
required this.queueCounterID,
required this.counterCode,
required this.orderStatus});
Served.fromJson(Map<String, dynamic> json) {
queueID = json['queueID'];
statusID = json['statusID'];
queueNumber = json['queueNumber'];
queueCounterID = json['queueCounterID'];
counterCode = json['counterCode'];
orderStatus = json['order_status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['queueID'] = this.queueID;
data['statusID'] = this.statusID;
data['queueNumber'] = this.queueNumber;
data['queueCounterID'] = this.queueCounterID;
data['counterCode'] = this.counterCode;
data['order_status'] = this.orderStatus;
return data;
}
@override
List<Object?> get props => [queueID, statusID, queueNumber, orderStatus];
}
class Call extends Equatable {
late String queueID;
late String statusID;
late String queueNumber;
late String queueCounterID;
late String counterCode;
late String orderStatus;
Call(
{required this.queueID,
required this.statusID,
required this.queueNumber,
required this.queueCounterID,
required this.counterCode,
required this.orderStatus});
Call.fromJson(Map<String, dynamic> json) {
queueID = json['queueID'];
statusID = json['statusID'];
queueNumber = json['queueNumber'];
queueCounterID = json['queueCounterID'];
counterCode = json['counterCode'];
orderStatus = json['order_status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['queueID'] = this.queueID;
data['statusID'] = this.statusID;
data['queueNumber'] = this.queueNumber;
data['queueCounterID'] = this.queueCounterID;
data['counterCode'] = this.counterCode;
data['order_status'] = this.orderStatus;
return data;
}
@override
List<Object?> get props => [queueID, statusID, queueNumber, orderStatus];
}

View File

@@ -0,0 +1,111 @@
class DisplayModel {
late List<BelumDilayani> belumDilayani;
late List<SedangDilayani> sedangDilayani;
DisplayModel({
required this.belumDilayani,
required this.sedangDilayani
});
DisplayModel.fromJson(Map<String, dynamic> json) {
if (json['belumDilayani'] != null) {
belumDilayani = [];
json['belumDilayani'].forEach((v) {
belumDilayani.add(BelumDilayani.fromJson(v));
});
}
if (json['sedangDilayani'] != null) {
sedangDilayani = [];
json['sedangDilayani'].forEach((v) {
sedangDilayani.add(SedangDilayani.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
if (this.belumDilayani != null) {
data['belumDilayani'] =
this.belumDilayani.map((v) => v.toJson()).toList();
}
if (this.sedangDilayani != null) {
data['sedangDilayani'] =
this.sedangDilayani.map((v) => v.toJson()).toList();
}
return data;
}
}
class BelumDilayani {
late String queueID;
late String statusID;
late String queueNumber;
late String serviceDoctorName;
late String antrianSelanjutnya;
late String orderStatus;
BelumDilayani(
{
required this.queueID,
required this.statusID,
required this.queueNumber,
required this.serviceDoctorName,
required this.antrianSelanjutnya,
required this.orderStatus
});
BelumDilayani.fromJson(Map<String, dynamic> json) {
queueID = json['queueID'];
statusID = json['statusID'];
queueNumber = json['queueNumber'];
serviceDoctorName = json['serviceDoctorName'];
antrianSelanjutnya = json['antrian_selanjutnya'];
orderStatus = json['order_status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['queueID'] = this.queueID;
data['statusID'] = this.statusID;
data['queueNumber'] = this.queueNumber;
data['serviceDoctorName'] = this.serviceDoctorName;
data['antrian_selanjutnya'] = this.antrianSelanjutnya;
data['order_status'] = this.orderStatus;
return data;
}
}
class SedangDilayani {
late String queueID;
late String queueNumber;
late String serviceDoctorName;
late String antrianSelanjutnya;
late String orderStatus;
SedangDilayani(
{
required this.queueID,
required this.queueNumber,
required this.serviceDoctorName,
required this.antrianSelanjutnya,
required this.orderStatus
});
SedangDilayani.fromJson(Map<String, dynamic> json) {
queueID = json['queueID'];
queueNumber = json['queueNumber'];
serviceDoctorName = json['serviceDoctorName'];
antrianSelanjutnya = json['antrian_selanjutnya'];
orderStatus = json['order_status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['queueID'] = this.queueID;
data['queueNumber'] = this.queueNumber;
data['serviceDoctorName'] = this.serviceDoctorName;
data['antrian_selanjutnya'] = this.antrianSelanjutnya;
data['order_status'] = this.orderStatus;
return data;
}
}

View File

@@ -0,0 +1,18 @@
class ErrorMsgModel {
String? title;
String? msg;
ErrorMsgModel({this.title, this.msg});
ErrorMsgModel.fromJson(Map<String, dynamic> json) {
title = json['title'];
msg = json['msg'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['title'] = this.title;
data['msg'] = this.msg;
return data;
}
}

View File

@@ -0,0 +1,40 @@
import 'package:equatable/equatable.dart';
class LayananDokter extends Equatable {
int id;
String name;
String code;
bool value;
int priority;
String isConsultDoctor;
String doctorName;
String? img;
LayananDokter(
{required this.name,
required this.id,
required this.priority,
required this.isConsultDoctor,
this.doctorName = '',
this.value = false,
this.img,
required this.code});
LayananDokter.fromJson(Map<String, dynamic> json)
: name = (json['serviceName'] as String).replaceAll("</br>", "\n"),
code = json['serviceCode'].toString(),
priority = int.parse(json['servicePriority']),
value = false,
isConsultDoctor = json['serviceIsConsultDoctor'].toString(),
doctorName = json['serviceDoctorName'].toString(),
id = int.parse(json['serviceID']);
Map<String, dynamic> toJson() => {
'serviceName': name,
'serviceID': id,
'serviceCode': code,
'servicePriority': priority,
'value': value
};
@override
List<Object?> get props => [id];
}

View File

@@ -0,0 +1,50 @@
import 'package:equatable/equatable.dart';
class SamplingLocation extends Equatable {
String mLocationID;
String mLocationTSampleStationID;
String mLocationName;
String mLocationPriority;
String mLocationIsActive;
String mLocationCreated;
String mLocationLastUpdated;
String tSampleStationName;
bool value;
SamplingLocation(
{required this.mLocationID,
required this.mLocationTSampleStationID,
required this.mLocationName,
required this.mLocationPriority,
required this.mLocationIsActive,
required this.mLocationCreated,
required this.mLocationLastUpdated,
required this.tSampleStationName,
this.value = false});
SamplingLocation.fromJson(Map<String, dynamic> json)
: mLocationID = json['M_LocationID'],
mLocationTSampleStationID = json['M_LocationT_SampleStationID'],
mLocationName = json['M_LocationName'],
mLocationPriority = json['M_LocationPriority'],
mLocationIsActive = json['M_LocationIsActive'],
mLocationCreated = json['M_LocationCreated'],
mLocationLastUpdated = json['M_LocationLastUpdated'],
tSampleStationName = json['T_SampleStationName'],
value = false;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['M_LocationID'] = this.mLocationID;
data['M_LocationT_SampleStationID'] = this.mLocationTSampleStationID;
data['M_LocationName'] = this.mLocationName;
data['M_LocationPriority'] = this.mLocationPriority;
data['M_LocationIsActive'] = this.mLocationIsActive;
data['M_LocationCreated'] = this.mLocationCreated;
data['M_LocationLastUpdated'] = this.mLocationLastUpdated;
return data;
}
@override
List<Object?> get props => [mLocationID];
}

View File

@@ -0,0 +1,75 @@
import 'package:equatable/equatable.dart';
class Layanan extends Equatable {
// int id;
// String name;
// String code;
// bool value;
// int priority;
// String isConsultDoctor;
// String doctorName;
// String? img;
int counterID;
String? counterCode;
String? counterIP;
String? counterIsDedicated;
String? counterLocationID;
String? counterMaxQueue;
String? counterIsActive;
String? locationID;
String? locationName;
String? serviceID;
bool value;
bool sound;
Layanan({
// required this.name,
// required this.id,
// required this.priority,
// required this.isConsultDoctor,
// this.doctorName = '',
// this.value = false,
// this.img,
// required this.code
required this.counterCode,
required this.counterID,
required this.counterIP,
required this.counterIsDedicated,
required this.counterMaxQueue,
required this.counterIsActive,
required this.locationID,
required this.locationName,
required this.serviceID,
this.value = false,
this.sound = false,
});
Layanan.fromJson(Map<String, dynamic> json)
: counterID = int.parse(json['counterID']),
counterCode = json['counterCode'].toString(),
counterIP = json['counterIP'].toString(),
value = false,
sound = false,
counterIsDedicated = json['counterIsDedicated'].toString(),
counterMaxQueue = json['counterMaxQueue'].toString(),
locationID = json['locationID'].toString(),
locationName = json['locationName'].toString(),
serviceID = json['serviceID'].toString(),
counterIsActive = json['counterIsActive'].toString();
Map<String, dynamic> toJson() => {
'counterID': counterID,
'counterCode': counterCode,
'counterIP': counterIP,
'counterIsDedicated': counterIsDedicated,
'counterMaxQueue': counterMaxQueue,
'counterIsActive': counterIsActive,
'locationID':locationID,
'locationName': locationName,
'value': value,
'sound':sound
};
@override
List<Object?> get props => [counterID];
}

View File

@@ -0,0 +1,15 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:queuedisplay/model/error_msg_model.dart';
import 'package:queuedisplay/model/layanan_dokter.dart';
import '../model/service_model.dart';
final allServiceProvider = StateProvider<List<Layanan>>(
(ref) => List.empty(),
);
final allServiceDoctorProvider = StateProvider<List<LayananDokter>>(
(ref) => List.empty(),
);
final errorListMsgProvider = StateProvider<List<ErrorMsgModel>>(
(ref) => List.empty(growable: true),
);

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:queuedisplay/model/counter_model.dart';
import 'package:queuedisplay/repository/counter_repository.dart';
import '../repository/base_repository.dart';
import 'dio_provider.dart';
abstract class CounterListState extends Equatable {
final DateTime date;
const CounterListState(this.date);
@override
List<Object?> get props => [date];
}
class CounterListStateInit extends CounterListState {
CounterListStateInit() : super(DateTime.now());
}
class CounterListStateLoading extends CounterListState {
CounterListStateLoading() : super(DateTime.now());
}
class CounterListStateError extends CounterListState {
final String message;
CounterListStateError({
required this.message,
}) : super(DateTime.now());
}
class CounterListStateDone extends CounterListState {
final List<Counter> model;
CounterListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class CounterListNotifier extends StateNotifier<CounterListState> {
final Ref ref;
CounterListNotifier({
required this.ref,
}) : super(CounterListStateInit());
void list() async {
try {
state = CounterListStateLoading();
final dio = ref.read(dioProvider);
final resp = await CounterRepository(dio: dio).getData();
state = CounterListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = CounterListStateError(message: e.message);
} else {
state = CounterListStateError(message: e.toString());
}
}
}
}
//provider
final CounterProvider =
StateNotifierProvider<CounterListNotifier, CounterListState>(
(ref) => CounterListNotifier(ref: ref));

View File

@@ -0,0 +1,4 @@
import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final dioProvider = Provider<Dio>((ref) => Dio());

View File

@@ -0,0 +1,72 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../model/display_counter_dedicated_modelv2.dart';
import '../repository/base_repository.dart';
import '../repository/service_repository.dart';
import 'dio_provider.dart';
abstract class DisplayCounterDedicatedState extends Equatable {
final DateTime date;
const DisplayCounterDedicatedState(this.date);
@override
List<Object?> get props => [date];
}
class DisplayCounterDedicatedStateInit extends DisplayCounterDedicatedState {
DisplayCounterDedicatedStateInit() : super(DateTime.now());
}
class DisplayCounterDedicatedStateLoading extends DisplayCounterDedicatedState {
DisplayCounterDedicatedStateLoading() : super(DateTime.now());
}
class DisplayCounterDedicatedStateError extends DisplayCounterDedicatedState {
final String message;
DisplayCounterDedicatedStateError({
required this.message,
}) : super(DateTime.now());
}
class DisplayCounterDedicatedStateDone extends DisplayCounterDedicatedState {
// final List<DisplayCounterDedicatedModel> model;
final List<DisplayCounterDedicatedModelV2> model;
DisplayCounterDedicatedStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class DisplayLayananNotifier
extends StateNotifier<DisplayCounterDedicatedState> {
final Ref ref;
DisplayLayananNotifier({
required this.ref,
}) : super(DisplayCounterDedicatedStateInit());
void listDisplayByCounterID(List<int> counterID, String branchID) async {
try {
state = DisplayCounterDedicatedStateLoading();
final dio = ref.read(dioProvider);
final resp = await ServiceRepository(dio: dio)
.getDataByCounterID(counterID, branchID);
state = DisplayCounterDedicatedStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
if (e.message == "XMLHttpRequest error." ||
e.message == "XMLHttpRequest error.") {
state =
DisplayCounterDedicatedStateError(message: "Connection Error");
} else {
state = DisplayCounterDedicatedStateError(message: e.message);
}
} else {
state = DisplayCounterDedicatedStateError(message: e.toString());
}
}
}
}
//provider
final displayProvider =
StateNotifierProvider<DisplayLayananNotifier, DisplayCounterDedicatedState>(
(ref) => DisplayLayananNotifier(ref: ref));

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../model/layanan_dokter.dart';
import '../repository/base_repository.dart';
import '../repository/service_repository_layanan_dokter.dart';
import 'dio_provider.dart';
abstract class LayananListState extends Equatable {
final DateTime date;
const LayananListState(this.date);
@override
List<Object?> get props => [date];
}
class LayananListStateInit extends LayananListState {
LayananListStateInit() : super(DateTime.now());
}
class LayananListStateLoading extends LayananListState {
LayananListStateLoading() : super(DateTime.now());
}
class LayananListStateError extends LayananListState {
final String message;
LayananListStateError({
required this.message,
}) : super(DateTime.now());
}
class LayananListStateDone extends LayananListState {
final List<LayananDokter> model;
LayananListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class LayananListNotifier extends StateNotifier<LayananListState> {
final Ref ref;
LayananListNotifier({
required this.ref,
}) : super(LayananListStateInit());
void list() async {
try {
state = LayananListStateLoading();
final dio = ref.read(dioProvider);
final resp = await ServiceRepositoryLayananDokter(dio: dio).getData();
state = LayananListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = LayananListStateError(message: e.message);
} else {
state = LayananListStateError(message: e.toString());
}
}
}
}
//provider
final layananProvider =
StateNotifierProvider<LayananListNotifier, LayananListState>(
(ref) => LayananListNotifier(ref: ref));

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:queuedisplay/model/sampling_location_model.dart';
import 'package:queuedisplay/provider/dio_provider.dart';
import 'package:queuedisplay/repository/sampling_location_repository.dart';
import '../repository/base_repository.dart';
abstract class SamplingLocationList extends Equatable {
final DateTime date;
const SamplingLocationList(this.date);
@override
List<Object?> get props => [date];
}
class SamplingLocationListInit extends SamplingLocationList {
SamplingLocationListInit() : super(DateTime.now());
}
class SamplingLocationListLoading extends SamplingLocationList {
SamplingLocationListLoading() : super(DateTime.now());
}
class SamplingLocationListError extends SamplingLocationList {
final String message;
SamplingLocationListError({
required this.message,
}) : super(DateTime.now());
}
class SamplingLocationListDone extends SamplingLocationList {
final List<SamplingLocation> model;
SamplingLocationListDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SamplingLocationListNotifier extends StateNotifier<SamplingLocationList> {
final Ref ref;
SamplingLocationListNotifier({
required this.ref,
}) : super(SamplingLocationListInit());
void list() async {
try {
state = SamplingLocationListLoading();
final dio = ref.read(dioProvider);
final resp = await SamplingLocationRepository(dio: dio).getData();
state = SamplingLocationListDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SamplingLocationListError(message: e.message);
} else {
state = SamplingLocationListError(message: e.toString());
}
}
}
}
//provider
final SamplingLocationProvider =
StateNotifierProvider<SamplingLocationListNotifier, SamplingLocationList>(
(ref) => SamplingLocationListNotifier(ref: ref));

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../model/service_model.dart';
import '../repository/base_repository.dart';
import '../repository/service_repository.dart';
import 'dio_provider.dart';
abstract class ServiceListState extends Equatable {
final DateTime date;
const ServiceListState(this.date);
@override
List<Object?> get props => [date];
}
class ServiceListStateInit extends ServiceListState {
ServiceListStateInit() : super(DateTime.now());
}
class ServiceListStateLoading extends ServiceListState {
ServiceListStateLoading() : super(DateTime.now());
}
class ServiceListStateError extends ServiceListState {
final String message;
ServiceListStateError({
required this.message,
}) : super(DateTime.now());
}
class ServiceListStateDone extends ServiceListState {
final List<Layanan> model;
ServiceListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class ServiceListNotifier extends StateNotifier<ServiceListState> {
final Ref ref;
ServiceListNotifier({
required this.ref,
}) : super(ServiceListStateInit());
void list(String branchID) async {
try {
state = ServiceListStateLoading();
final dio = ref.read(dioProvider);
final resp = await ServiceRepository(dio: dio).getData(branchID);
state = ServiceListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ServiceListStateError(message: e.message);
} else {
state = ServiceListStateError(message: e.toString());
}
}
}
}
//provider
final serviceProvider =
StateNotifierProvider<ServiceListNotifier, ServiceListState>(
(ref) => ServiceListNotifier(ref: ref));

View File

@@ -0,0 +1,230 @@
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
abstract class BaseRepository {
final Dio dio;
BaseRepository({required this.dio});
Future<Map<String, dynamic>> post({
required Map<String, dynamic> param,
required String service,
String? token,
}) async {
try {
final response = await dio.post(
// Constant.baseUrl + service,
service,
data: jsonEncode(param),
options: Options(
headers: token != null
? {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.authorizationHeader: "Bearer $token",
}
: {
HttpHeaders.contentTypeHeader: "application/json",
},
contentType: "application/json",
),
);
if (response.statusCode != 200) {
throw BaseRepositoryException(
message: "Invalid Http Response ${response.statusCode}",
);
}
Map<String, dynamic> jsonData = jsonDecode(response.data);
if (jsonData["status"] != "OK") {
throw BaseRepositoryException(
message: jsonData["message"],
);
} else {
return jsonData;
}
} on DioError catch (e) {
if (e.type == DioErrorType.connectTimeout) {
print("Conection Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Conection Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.sendTimeout) {
print("Send Data Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Send Data Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.receiveTimeout) {
print("Get Data Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Get Data Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.response) {
print("Response Error, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Response Error, periksa koneksi anda");
} else {
print("else");
throw BaseRepositoryException(message: e.message);
}
// throw BaseRepositoryException(message: e.message);
} on SocketException catch (e) {
throw BaseRepositoryException(message: e.message);
} on BaseRepositoryException catch (e) {
throw BaseRepositoryException(message: e.message);
}
}
Future<Map<String, dynamic>> get({
required String service,
}) async {
try {
final response = await dio.get(
// Constant.baseUrl + service,
service,
);
if (response.statusCode != 200) {
throw BaseRepositoryException(
message: "Invalid Http Response ${response.statusCode}",
);
}
// print(jsonDecode(response.data));
Map<String, dynamic> jsonData = response.data;
if (jsonData["status"] != "OK") {
throw BaseRepositoryException(
message: jsonData["message"],
);
} else {
return jsonData;
}
} on DioError catch (e) {
if (e.type == DioErrorType.connectTimeout) {
print("Conection Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Conection Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.sendTimeout) {
print("Send Data Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Send Data Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.receiveTimeout) {
print("Get Data Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Get Data Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.response) {
print("Response Error, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Response Error, periksa koneksi anda");
} else {
print("else");
throw BaseRepositoryException(message: e.message);
}
} on SocketException catch (e) {
throw BaseRepositoryException(message: e.message);
} on BaseRepositoryException catch (e) {
throw BaseRepositoryException(message: e.message);
}
}
Future<Map<String, dynamic>> getBooth({
required String service,
}) async {
try {
final response = await dio.get(
// Constant.baseUrl + service,
service,
);
if (response.statusCode != 200) {
throw BaseRepositoryException(
message: "Invalid Http Response ${response.statusCode}",
);
}
// print(jsonDecode(response.data));
Map<String, dynamic> jsonData = jsonDecode(response.data);
if (jsonData["status"] != "OK") {
throw BaseRepositoryException(
message: jsonData["message"],
);
} else {
return jsonData;
}
} on DioError catch (e) {
if (e.type == DioErrorType.connectTimeout) {
print("Conection Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Conection Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.sendTimeout) {
print("Send Data Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Send Data Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.receiveTimeout) {
print("Get Data Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Get Data Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.response) {
print("Response Error, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Response Error, periksa koneksi anda");
} else {
print("else");
throw BaseRepositoryException(message: e.message);
}
} on SocketException catch (e) {
throw BaseRepositoryException(message: e.message);
} on BaseRepositoryException catch (e) {
throw BaseRepositoryException(message: e.message);
}
}
Future<Map<String, dynamic>> getService({
required String service,
}) async {
try {
final response = await dio.get(
// Constant.baseUrl + service,
service,
);
if (response.statusCode != 200) {
throw BaseRepositoryException(
message: "Invalid Http Response ${response.statusCode}",
);
}
// print(jsonDecode(response.data));
Map<String, dynamic> jsonData = jsonDecode(response.data);
if (jsonData["status"] != "OK") {
throw BaseRepositoryException(
message: jsonData["message"],
);
} else {
return jsonData;
}
} on DioError catch (e) {
if (e.type == DioErrorType.connectTimeout) {
print("Conection Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Conection Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.sendTimeout) {
print("Send Data Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Send Data Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.receiveTimeout) {
print("Get Data Timeout, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Get Data Timeout, periksa koneksi anda");
} else if (e.type == DioErrorType.response) {
print("Response Error, periksa koneksi anda");
throw BaseRepositoryException(
message: "${e.message} Response Error, periksa koneksi anda");
} else {
print("else");
throw BaseRepositoryException(message: e.message);
}
} on SocketException catch (e) {
throw BaseRepositoryException(message: e.message);
} on BaseRepositoryException catch (e) {
throw BaseRepositoryException(message: e.message);
}
}
}
class BaseRepositoryException implements Exception {
final String message;
BaseRepositoryException({
required this.message,
});
}

View File

@@ -0,0 +1,42 @@
import 'dart:convert';
import 'package:queuedisplay/model/branch_model.dart';
import 'package:queuedisplay/model/counter_model.dart';
import '../app/constant.dart';
import 'base_repository.dart';
class CounterRepository extends BaseRepository {
CounterRepository({required super.dio});
Future<List<Counter>> getData() async {
final url =
"${Constant.baseUrl}antrian/AntrianCounterDedicated/list_counter";
final resp = await getService(service: url);
// print(resp);
final List<Counter> listCounter = List.empty(growable: true);
resp['data']['records'].forEach((e) {
final model = Counter.fromJson(e);
listCounter.add(model);
});
return listCounter;
}
Future<List<BranchModel>> getBranch() async {
// https://devcpone.aplikasi.web.id/one-api/mockup/fo/antrian/AntrianByStationAndLocation/getbranch
final url =
"${Constant.baseUrl}mockup/fo/antrian/AntrianByStationAndLocation/getbranch";
print(url);
// final url = "$hostIP/one-api/training/ticketbooth/index";
final resp = await getBooth(service: url);
final List<BranchModel> listBooth = List.empty(growable: true);
resp['data']['records'].forEach((e) {
final model = BranchModel.fromJson(e);
listBooth.add(model);
});
return listBooth;
}
}

View File

@@ -0,0 +1,23 @@
import 'package:queuedisplay/model/sampling_location_model.dart';
import '../app/constant.dart';
import 'base_repository.dart';
class SamplingLocationRepository extends BaseRepository {
SamplingLocationRepository({required super.dio});
Future<List<SamplingLocation>> getData() async {
final url =
"${Constant.baseUrl}mockup/fo/antrian/AntrianByStationAndLocation/getLocationName";
final resp = await getService(service: url);
final List<SamplingLocation> listLocation = List.empty(growable: true);
// print(resp);
resp['data']['records'].forEach((e) {
final model = SamplingLocation.fromJson(e);
listLocation.add(model);
});
return listLocation;
}
}

View File

@@ -0,0 +1,44 @@
import 'package:queuedisplay/model/service_model.dart';
import '../app/constant.dart';
import '../model/display_counter_dedicated_modelv2.dart';
import 'base_repository.dart';
class ServiceRepository extends BaseRepository {
ServiceRepository({required super.dio});
Future<List<Layanan>> getData(String branchID) async {
final url =
"${Constant.baseUrl}antrian/AntrianCounterDedicated/list_counter/$branchID";
final resp = await getService(service: url);
final List<Layanan> listLayanan = List.empty(growable: true);
resp['data']['records'].forEach((e) {
final model = Layanan.fromJson(e);
listLayanan.add(model);
});
return listLayanan;
}
// get data by Counter ID
// Future<List<DisplayCounterDedicatedModel>> getDataByCounterID(List<int> arrCounterID) async {
Future<List<DisplayCounterDedicatedModelV2>> getDataByCounterID(
List<int> arrCounterID, String branchID) async {
final url =
"${Constant.baseUrl}antrian/AntrianCounterDedicated/get_antrian";
final param = {"arr_counter": arrCounterID, "branchID": branchID};
// print(param);
final resp = await post(service: url, param: param);
// print(resp);
final List<DisplayCounterDedicatedModelV2> listDisplay =
List.empty(growable: true);
resp['data'].forEach((e) {
final model = DisplayCounterDedicatedModelV2.fromJson(e);
listDisplay.add(model);
});
// DisplayCounterDedicatedModel.fromJson(resp['data']);
return listDisplay;
}
}

View File

@@ -0,0 +1,39 @@
import '../app/constant.dart';
import '../model/layanan_dokter.dart';
import 'base_repository.dart';
class ServiceRepositoryLayananDokter extends BaseRepository {
ServiceRepositoryLayananDokter({required super.dio});
Future<List<LayananDokter>> getData() async {
final url = "${Constant.baseUrl}antrian/layanandokter/list_service";
final resp = await getService(service: url);
final List<LayananDokter> listLayanan = List.empty(growable: true);
resp['data']['records'].forEach((e) {
final model = LayananDokter.fromJson(e);
listLayanan.add(model);
});
return listLayanan;
}
// get data by serviceID
// Future<List<DisplayModel>> getDataByServiceID(List<int> serviceID) async {
// Future<List<DisplayModelV2>> getDataByServiceID(List<int> serviceID) async {
// final url = "${Constant.baseUrl}antrian/layanandokter/list_layanan_dokter";
// final param = {"serviceId": serviceID};
// // print(param);
// final resp = await post(service: url, param: param);
// // print(resp);
// final List<DisplayModelV2> listDisplay = List.empty(growable: true);
// resp['data'].forEach((e) {
// final model = DisplayModelV2.fromJson(e);
// listDisplay.add(model);
// });
// return listDisplay;
// }
}

View File

@@ -0,0 +1,706 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:html';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_image_slideshow/flutter_image_slideshow.dart';
import 'package:intl/intl.dart';
import 'package:queuedisplay/model/branch_model.dart';
import 'package:queuedisplay/model/display_counter_dedicated_modelv2.dart';
import 'package:queuedisplay/model/service_model.dart';
import 'package:queuedisplay/provider/all_service_provider.dart';
import 'package:queuedisplay/screen/with_media_promo.dart';
import 'package:queuedisplay/widget/my_counter_customer_service_dedicated.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:flutter/material.dart';
import 'package:text_scroll/text_scroll.dart';
import '../app/constant.dart';
import '../app/route.dart';
import '../model/layanan_dokter.dart';
import '../provider/display_counter_dedicated_provider.dart';
import '../widget/clock.dart';
import '../widget/my_antrian_customer_service_dedicated.dart';
import '../widget/my_error_dialog.dart';
import 'no_media_promo.dart';
class CustomerServiceDedicatedV2 extends StatefulHookConsumerWidget {
const CustomerServiceDedicatedV2({super.key});
@override
ConsumerState<ConsumerStatefulWidget> createState() =>
_CustomerServiceDedicatedV2State();
}
class _CustomerServiceDedicatedV2State
extends ConsumerState<CustomerServiceDedicatedV2> {
late IO.Socket socket;
late String typeJson = "";
@override
void initState() {
initSocket();
super.initState();
}
initSocket() {
socket = IO.io('https://${Constant.baseSocket}:9099', <String, dynamic>{
'autoConnect': false,
'transports': ['websocket'],
});
socket.connect();
socket.onConnect((_) {
print('Connection established');
});
socket.onDisconnect((_) => print('Connection Disconnection'));
socket.onConnectError((err) => print(err));
socket.onError((err) => print(err));
}
@override
void dispose() {
socket.disconnect();
socket.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final isLoading = useState(false);
final errorMessage = useState("");
final ListErrorMessage = useState<List<String>>(List.empty());
final listService =
useState<List<DisplayCounterDedicatedModelV2>>(List.empty());
final listBelumDilayani = useState<List<NotServed>>(List.empty());
final listSedangDilayani = useState<List<Served>>(List.empty());
final listCall = useState<List<Call>>(List.empty());
final selectedBranch = useState(BranchModel(mBranchID: '0'));
final judul = useState("");
final dataLayanan = useState<List<int>>(List.empty());
final lastTimeCall =
useState<DateTime>(DateTime.now().subtract(Duration(minutes: 1)));
final locationIDCall = useState(0);
final serviceIDArr = useState<List>(List.empty());
final serviceIDArrSuara = useState<List>(List.empty());
final selectedCounter = useState<List<Layanan>>(List.empty());
final scrlCnt = useScrollController();
final activeSoundDoctor = useState<List<int>>(List.empty());
final activeSoundCounter = useState<List<int>>(List.empty());
final activeSoundSamplingLocation = useState<List<int>>(List.empty());
final listNotification = useState<List<String>>(List.empty());
final serviceIDCounterArr = useState<List<int>>(List.empty());
final notifState = useState<Map<String, DateTime>>({});
// media promo
final tanpaMediaPromo = useState(false);
void goFullScreen() {
document.documentElement?.requestFullscreen();
}
// mp3
wordToMp3(int number) {
var result = "";
print("number = $number");
int ribu = (number / 1000).floor();
// print("ribu = $ribu");
if (ribu > 0) {
if (ribu == 1) {
result += "seribu" + '${number % 1000 == 0 ? "" : ","}';
} else {
result += "$ribu,ribu" + '${number % 1000 == 0 ? "" : ","}';
}
}
int cur = number - ribu * 1000;
int ratus = (cur / 100).floor();
// print("ratus = $ratus");
if (ratus > 0) {
if (ratus == 1) {
result += "100";
} else {
result += "$ratus,ratus";
}
}
cur = cur - ratus * 100;
int puluh = (cur / 10).floor();
// print("puluh = $puluh");
if (puluh > 0) {
if (result != "") result += ",";
if (puluh == 1) {
if (cur - 10 == 1) {
result += "11";
return result;
}
// else if(cur - 10 == 0){
// result += "10";
// return result;
// }
else {
int hasil = cur - 10;
if (hasil == 0) {
result += "10";
} else {
result += "$hasil,belas";
}
}
} else {
result += "$puluh,puluh";
}
}
cur = cur - (puluh * 10);
// print("akhir = $cur");
if (cur > 0) {
if (puluh == 1) {
result += "";
} else {
if (result != "") result += ",";
result += "$cur";
}
}
return result;
}
void downloadMp3(String param) async {
try {
var url = "http://${Constant.baseSocket}/audio/?prm=$param";
final player = AudioPlayer();
player.setSource(UrlSource(url));
print(url);
player.resume();
} catch (e) {
print(e);
}
}
process_sound(String number, String Counter) {
String antrian = number.replaceAll(RegExp(r'[^0-9]'), '');
String code = number.replaceAll(RegExp(r'[^A-Z]'), '');
var splitedCode = code.split("");
String joinCode = splitedCode.join(",");
String counterNum = Counter.replaceAll(RegExp(r'[^0-9]'), '');
String counterCode = Counter.replaceAll(RegExp(r'[^A-Z]'), '');
var splitedCodeCounter = counterCode.split("");
String joinCodeCounter = splitedCodeCounter.join(",");
if (antrian.isNotEmpty && counterNum.isNotEmpty) {
String param = "antrian,$joinCode," +
"${wordToMp3(int.parse(antrian))}," +
"counter,$joinCodeCounter," +
wordToMp3(int.parse(counterNum));
downloadMp3(param);
}
}
process_sound_sampling(String number, String Counter) {
try {
String antrian = number.replaceAll(RegExp(r'[^0-9]'), '');
String code = number.replaceAll(RegExp(r'[^A-Z]'), '');
var splitedCode = code.split("");
String joinCode = splitedCode.join(",");
String counterNum = Counter.replaceAll(RegExp(r'[^0-9]'), '');
String counterCode = Counter.replaceAll(RegExp(r'[^A-Z]'), '');
var splitedCodeCounter = counterCode.split("");
String joinCodeCounter = splitedCodeCounter.join(",");
String param = "antrian,$joinCode," +
"${wordToMp3(int.parse(antrian))},ruangan,r$Counter";
print(param);
downloadMp3(param);
// }
} catch (e) {
print(e);
}
}
process_sound_doctor(String number, String Counter, String serviceID) {
try {
String antrian = number.replaceAll(RegExp(r'[^0-9]'), '');
String code = number.replaceAll(RegExp(r'[^A-Z]'), '');
var splitedCode = code.split("");
String joinCode = splitedCode.join(",");
var allLayanan = ref.read(allServiceDoctorProvider.notifier).state;
LayananDokter lyn = allLayanan.firstWhere(
(element) => element.id == int.parse(serviceID.toString()));
if (antrian.isNotEmpty && lyn.doctorName != '') {
String service = lyn.doctorName;
String processService = service
.replaceAll('.', '')
.replaceAll(' ', '_')
.replaceAll(',', '')
.toLowerCase();
String param = "antrian,$joinCode," +
"${wordToMp3(int.parse(antrian))}," +
processService;
downloadMp3(param);
}
} catch (e) {
print(e);
}
}
// mp3
// socket.off("notification", (data) {});
socket.on('notification', (data) {
String pesan = data['type'];
if (notifState.value.containsKey(pesan)) {
var lasDate = notifState.value[pesan];
if (DateTime.now()
.subtract(const Duration(seconds: 10))
.isBefore(lasDate!)) {
return;
}
var notifNew = notifState.value;
notifNew[pesan] = DateTime.now();
notifState.value = notifNew;
} else {
var notifNew = notifState.value;
notifNew[pesan] = DateTime.now();
notifState.value = notifNew;
}
print(data);
// typeJsonSocketIO.value = data['type'];
var splited_pesan = pesan.split(".");
// var splited_pesan = pesan.split(".");
// print(splited_pesan);
if (splited_pesan[0] == 'call') {
var xList = listNotification.value.toList();
List<String> msgList = xList;
if (splited_pesan[1] == 'fo') {
var serviceValidation = serviceIDArr.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[2].toString()));
var counterValidation = dataLayanan.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[5].toString()));
locationIDCall.value = int.parse(splited_pesan[2]);
if (serviceValidation.isNotEmpty && counterValidation.isNotEmpty) {
ref.read(displayProvider.notifier).listDisplayByCounterID(
dataLayanan.value, selectedBranch.value.mBranchID ?? "0");
}
}
if (xList.isEmpty) {
// if (activeSoundDoctor.value.isNotEmpty && splited_pesan[1] == 'kd') {
// var validation =
// activeSoundDoctor.value.contains(int.parse(splited_pesan[2]));
// if (validation) {
// msgList.add(pesan);
// }
// }
if (activeSoundCounter.value.isNotEmpty &&
splited_pesan[1] == 'fo' &&
splited_pesan[6] == selectedBranch.value.mBranchID) {
var serviceValidation = serviceIDArrSuara.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[2].toString()));
var counterValidation = activeSoundCounter.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[5].toString()));
locationIDCall.value = int.parse(splited_pesan[2]);
if (serviceValidation.isNotEmpty && counterValidation.isNotEmpty) {
msgList.add(pesan);
}
}
// if (activeSoundSamplingLocation.value.isNotEmpty &&
// splited_pesan[1] == 'sm') {
// var validation = activeSoundSamplingLocation.value
// .contains(int.parse(splited_pesan[2]));
// if (validation) {
// msgList.add(pesan);
// }
// }
}
// else {
// if (activeSoundDoctor.value.isNotEmpty && splited_pesan[1] == 'kd') {
// var validation =
// activeSoundDoctor.value.contains(int.parse(splited_pesan[2]));
// var msgValidation = msgList.contains(pesan.toString());
// if (validation && !msgValidation) {
// msgList.add(pesan);
// }
// }
// if (activeSoundCounter.value.isNotEmpty && splited_pesan[1] == 'fo') {
// var validation =
// activeSoundCounter.value.contains(int.parse(splited_pesan[5]));
// var counterValidation =
// serviceIDCounterArr.value.contains(int.parse(splited_pesan[2]));
// var msgValidation = msgList.contains(pesan.toString());
// if (validation && !msgValidation && counterValidation) {
// msgList.add(pesan);
// }
// }
// if (activeSoundSamplingLocation.value.isNotEmpty &&
// splited_pesan[1] == 'sm') {
// var validation = activeSoundSamplingLocation.value
// .contains(int.parse(splited_pesan[2]));
// var msgValidation = msgList.contains(pesan.toString());
// if (validation && !msgValidation) {
// msgList.add(pesan);
// }
// }
// }
listNotification.value = msgList;
print('List Notification : ${listNotification.value}');
} else if (splited_pesan[0] == 'skip') {
if (splited_pesan[1] == 'fo' &&
splited_pesan[4] == selectedBranch.value.mBranchID) {
var serviceValidation = serviceIDArr.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[2].toString()));
var counterValidation = dataLayanan.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[3].toString()));
if (serviceValidation.isNotEmpty && counterValidation.isNotEmpty) {
ref.read(displayProvider.notifier).listDisplayByCounterID(
dataLayanan.value, selectedBranch.value.mBranchID ?? "0");
}
}
} else if (splited_pesan[0] == 'serve') {
if (splited_pesan[1] == 'fo' &&
splited_pesan[4] == selectedBranch.value.mBranchID) {
var serviceValidation = serviceIDArr.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[2].toString()));
var counterValidation = dataLayanan.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[3].toString()));
if (serviceValidation.isNotEmpty && counterValidation.isNotEmpty) {
ref.read(displayProvider.notifier).listDisplayByCounterID(
dataLayanan.value, selectedBranch.value.mBranchID ?? "0");
}
}
} else if (splited_pesan[0] == 'done') {
if (splited_pesan[1] == 'fo' &&
splited_pesan[4] == selectedBranch.value.mBranchID) {
var serviceValidation = serviceIDArr.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[2].toString()));
var counterValidation = dataLayanan.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[3].toString()));
if (serviceValidation.isNotEmpty && counterValidation.isNotEmpty) {
ref.read(displayProvider.notifier).listDisplayByCounterID(
dataLayanan.value, selectedBranch.value.mBranchID ?? "0");
}
}
} else if (splited_pesan[0] == "printed") {
if (splited_pesan[1] == 'fo') {
var serviceValidation = serviceIDArr.value.where((element) =>
int.parse(element.toString()) ==
int.parse(splited_pesan[2].toString()));
if (serviceValidation.isNotEmpty &&
splited_pesan[3] == selectedBranch.value.mBranchID) {
ref.read(displayProvider.notifier).listDisplayByCounterID(
dataLayanan.value, selectedBranch.value.mBranchID ?? "0");
}
}
}
});
void autoScroll() {
if (scrlCnt.hasClients) {
if (scrlCnt.offset == 0) {
scrlCnt.animateTo(scrlCnt.position.maxScrollExtent,
duration: Duration(milliseconds: 100), curve: Curves.linear);
} else {
scrlCnt.animateTo(scrlCnt.position.minScrollExtent,
duration: Duration(milliseconds: 100), curve: Curves.linear);
}
}
}
Timer? tmr2;
Timer? tmr;
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
goFullScreen();
tmr = Timer.periodic(Duration(seconds: 5), (timer) {
autoScroll();
});
final prefs = await SharedPreferences.getInstance();
var rawData = prefs.getString('counter_dedicated') ?? 'a';
if (rawData != 'a') {
print(rawData);
var data = json.decode(rawData);
judul.value = data['judul'];
serviceIDArr.value = data['serviceID'];
// suara
serviceIDArrSuara.value = data['serviceIDSuara'];
// klu di check(true) maka tanpa media promo
tanpaMediaPromo.value = data['tanpaMediaPromo'];
//Selected branch
selectedBranch.value = BranchModel.fromJson(data['selectedBranch']);
List<int> listServiceID = List.empty(growable: true);
for (var x in data['activeLayanan']) {
listServiceID.add(int.parse(x.toString()));
}
dataLayanan.value = listServiceID;
List<int> listSoundDoctorID = List.empty(growable: true);
for (var x in data['activeSoundDoctor']) {
listSoundDoctorID.add(int.parse(x.toString()));
}
activeSoundDoctor.value = listSoundDoctorID;
List<int> listSoundSamplingID = List.empty(growable: true);
for (var x in data['activeSoundSamplingLocation']) {
listSoundSamplingID.add(int.parse(x.toString()));
}
activeSoundSamplingLocation.value = listSoundSamplingID;
List<int> listsoundCounter = List.empty(growable: true);
for (var x in data['activeSoundCounter']) {
listsoundCounter.add(int.parse(x.toString()));
}
activeSoundCounter.value = listsoundCounter;
List<int> listServiceCounterIDarr = List.empty(growable: true);
for (var x in data['serviceIDSuara']) {
listServiceCounterIDarr.add(int.parse(x.toString()));
}
serviceIDCounterArr.value = listServiceCounterIDarr;
var listCounter = ref.read(allServiceProvider.notifier).state;
List<Layanan> sc = List.empty(growable: true);
for (var i = 0; i < listCounter.length; i++) {
for (var j = 0; j < listServiceID.length; j++) {
if (int.parse(listCounter[i].counterID.toString()) ==
listServiceID[j]) {
sc.add(listCounter[i]);
}
}
}
selectedCounter.value = sc;
tmr2 = Timer.periodic(Duration(seconds: 10), (timer) {
if (listNotification.value.isNotEmpty) {
String pesan = listNotification.value[0];
print('Proses Sound : $pesan ');
var notif = listNotification.value.toList();
var splited_pesan = pesan.split(".");
if (splited_pesan[1] == 'kd') {
var serviceID = splited_pesan[2];
process_sound_doctor(
splited_pesan[3], splited_pesan[4], serviceID);
}
if (splited_pesan[1] == 'fo') {
process_sound(splited_pesan[3], splited_pesan[4]);
}
if (splited_pesan[1] == 'sm') {
print('masuk sampling');
process_sound_sampling(splited_pesan[3], splited_pesan[5]);
}
notif.removeAt(0);
listNotification.value = notif;
}
});
ref.read(displayProvider.notifier).listDisplayByCounterID(
listServiceID, selectedBranch.value.mBranchID ?? "0");
} else {
Navigator.of(context)
.pushNamedAndRemoveUntil(settingRoute, (route) => false);
return;
}
});
return () {
tmr!.cancel();
tmr2!.cancel();
};
}, []);
showDialogError(BuildContext context, String msg) {
var lstMsg = ListErrorMessage.value;
var validation = false;
for (var i = 0; i < lstMsg.length; i++) {
if (lstMsg[i] == msg) {
validation = true;
} else {
validation = false;
var newMsg = [...ListErrorMessage.value];
newMsg.add(msg);
ListErrorMessage.value = newMsg;
}
}
if (lstMsg.length == 0) {
validation = false;
List<String> newMsg = List.empty(growable: true);
newMsg.add(msg.toString());
ListErrorMessage.value = newMsg;
}
if (!validation) {
// print("modal cek ");
// print(_isThereCurrentDialogShowing(BuildContext context) =>
// ModalRoute.of(context)?.isCurrent != true);
var joinMsg = ListErrorMessage.value.join(",");
myErrorDialog(context, joinMsg, 'ERROR');
}
}
Timer? timer;
ref.listen(displayProvider, (prev, next) {
if (next is DisplayCounterDedicatedStateLoading) {
isLoading.value = true;
} else if (next is DisplayCounterDedicatedStateError) {
isLoading.value = false;
//kalau error msg connection mengaktifkan blink error
//update error counter
//if error counter lebih dari sama dengan 3 retry
// kalau done erro msg blink di nonaktifkan error counter di nolkan
if (errorMessage.value != next.message) {
myErrorDialog(context, next.message, 'ERROR');
}
errorMessage.value = next.message;
// showDialogError(context, next.message);
// print("error" + next.message);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is DisplayCounterDedicatedStateDone) {
isLoading.value = false;
listService.value = next.model;
next.model.forEach((element) {
listBelumDilayani.value = element.notServed;
listSedangDilayani.value = element.served;
listCall.value = element.call;
});
// print(jsonEncode(listBelumDilayani.value));
}
});
getNomorAntrian(String counterID) {
var rawCall = listCall.value;
// print(rawCall);
Call call = Call(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawCall.length; i++) {
if (rawCall[i].queueCounterID == counterID) {
call = rawCall[i];
}
}
var rawProcess = listSedangDilayani.value;
Served process = Served(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawProcess.length; i++) {
if (rawProcess[i].queueCounterID == counterID) {
process = rawProcess[i];
}
}
if (call.queueID != '0' && process.queueID == '0') {
return call.queueNumber;
} else if (call.queueID == '0' && process.queueID != '0') {
return process.queueNumber;
} else if (call.queueID == '0' && process.queueID == '0') {
return '-';
} else {
return call.queueNumber;
}
}
getBlinkAntrian(String counterID) {
var rawCall = listCall.value;
// print(rawCall);
Call call = Call(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawCall.length; i++) {
if (rawCall[i].queueCounterID == counterID) {
call = rawCall[i];
}
}
var rawProcess = listSedangDilayani.value;
Served process = Served(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawProcess.length; i++) {
if (rawProcess[i].queueCounterID == counterID) {
process = rawProcess[i];
}
}
if (call.queueID != '0' && process.queueID == '0') {
return true;
} else if (call.queueID == '0' && process.queueID != '0') {
return false;
} else if (call.queueID == '0' && process.queueID == '0') {
return false;
} else {
return true;
}
}
if (tanpaMediaPromo.value == true) {
return DisplayTanpaPromo(
isLoading: isLoading,
judul: judul,
scrlCnt: scrlCnt,
selectedCounter: selectedCounter,
listBelumDilayani: listBelumDilayani,
listCall: listCall,
listSedangDilayani: listSedangDilayani,
);
} else {
return WithMediaPromo(
listBelumDilayani: listBelumDilayani,
isLoading: isLoading,
judul: judul,
scrlCnt: scrlCnt,
selectedCounter: selectedCounter,
listCall: listCall,
listSedangDilayani: listSedangDilayani,
);
}
}
}

View File

@@ -0,0 +1,294 @@
import 'package:flutter/material.dart';
import 'package:text_scroll/text_scroll.dart';
import '../app/constant.dart';
import '../model/display_counter_dedicated_modelv2.dart';
import '../model/service_model.dart';
import '../widget/clock.dart';
import '../widget/my_antrian_customer_service_dedicated.dart';
import '../widget/my_counter_customer_service_dedicated.dart';
import 'customer_service_dedicatedv2.dart';
class DisplayTanpaPromo extends StatelessWidget {
const DisplayTanpaPromo(
{Key? key,
required this.isLoading,
required this.judul,
required this.scrlCnt,
required this.selectedCounter,
required this.listBelumDilayani,
required this.listCall,
required this.listSedangDilayani})
: super(key: key);
final ValueNotifier<bool> isLoading;
final ValueNotifier<String> judul;
final ScrollController scrlCnt;
final ValueNotifier<List<Layanan>> selectedCounter;
final ValueNotifier<List<NotServed>> listBelumDilayani;
final ValueNotifier<List<Call>> listCall;
final ValueNotifier<List<Served>> listSedangDilayani;
@override
Widget build(BuildContext context) {
getNomorAntrian(String counterID) {
var rawCall = listCall.value;
// print(rawCall);
Call call = Call(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawCall.length; i++) {
if (rawCall[i].queueCounterID == counterID) {
call = rawCall[i];
}
}
var rawProcess = listSedangDilayani.value;
Served process = Served(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawProcess.length; i++) {
if (rawProcess[i].queueCounterID == counterID) {
process = rawProcess[i];
}
}
if (call.queueID != '0' && process.queueID == '0') {
return call.queueNumber;
} else if (call.queueID == '0' && process.queueID != '0') {
return process.queueNumber;
} else if (call.queueID == '0' && process.queueID == '0') {
return '-';
} else {
return call.queueNumber;
}
}
getBlinkAntrian(String counterID) {
var rawCall = listCall.value;
// print(rawCall);
Call call = Call(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawCall.length; i++) {
if (rawCall[i].queueCounterID == counterID) {
call = rawCall[i];
}
}
var rawProcess = listSedangDilayani.value;
Served process = Served(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawProcess.length; i++) {
if (rawProcess[i].queueCounterID == counterID) {
process = rawProcess[i];
}
}
if (call.queueID != '0' && process.queueID == '0') {
return true;
} else if (call.queueID == '0' && process.queueID != '0') {
return false;
} else if (call.queueID == '0' && process.queueID == '0') {
return false;
} else {
return true;
}
}
return Material(
child: Container(
width: Constant.getActualX(context: context, x: 1920),
height: Constant.getActualY(context: context, y: 1080),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('images/background.png'), fit: BoxFit.fill),
),
child: Padding(
padding:
const EdgeInsets.only(left: 68, right: 68, top: 34, bottom: 32),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// judul start
Row(
children: [
Expanded(
flex: 3,
child: Container(
// color: Colors.green,
// width: Constant.getActualX(context: context, x: 900),
height: Constant.getActualY(context: context, y: 120),
child: Stack(
alignment: Alignment.centerLeft,
children: [
Container(
width:
Constant.getActualX(context: context, x: 1400),
height:
Constant.getActualY(context: context, y: 72),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.25),
blurRadius: 8)
],
borderRadius: BorderRadius.circular(20),
color: Colors.white),
child: Padding(
padding: const EdgeInsets.only(
top: 6,
left: 80,
),
child: Stack(
alignment: Alignment.centerLeft,
children: [
if (isLoading.value)
SizedBox(
width: Constant.getActualX(
context: context, x: 60),
height: Constant.getActualX(
context: context, x: 70),
child: const CircularProgressIndicator(),
),
Padding(
padding:
EdgeInsets.only(left: 40, right: 40),
child: TextScroll(
judul.value,
velocity: Velocity(
pixelsPerSecond: Offset(50, 0)),
style: Constant.body_3(context: context)
.copyWith(color: Constant.textRed),
),
),
],
),
),
),
Container(
width:
Constant.getActualX(context: context, x: 100),
height:
Constant.getActualY(context: context, y: 100),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient: LinearGradient(
colors: [Constant.red1, Constant.red2])),
),
Positioned(
top: 0,
child: Image.asset(
'images/cs.png',
fit: BoxFit.cover,
height: 100,
),
)
],
),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: Clock(),
),
),
],
),
// judul end
// counter list start
Expanded(
child: Container(
// color: Colors.blue,
width: Constant.getActualX(context: context, x: 1920),
height: Constant.getActualY(context: context, y: 400),
child: GridView.count(
scrollDirection: Axis.horizontal,
controller: scrlCnt,
crossAxisSpacing: 0.6,
// mainAxisSpacing: 30,
childAspectRatio: 1,
crossAxisCount: 1,
children: selectedCounter.value
.map(
(e) => MyCounterCustomerServiceDedicated(
// counter: 'DOKTER UMUM',
counter: 'Counter ${e.counterCode}',
nomorAntrian:
getNomorAntrian(e.counterID.toString()),
// nomorAntrian: 'LA 001',
borderDalam: const BorderRadius.only(
topLeft: Radius.circular(50),
topRight: Radius.circular(50),
bottomLeft: Radius.circular(50)),
borderLuar: const BorderRadius.only(
topLeft: Radius.circular(60),
topRight: Radius.circular(60),
bottomLeft: Radius.circular(60),
),
blink: getBlinkAntrian(e.counterID.toString()),
),
)
.toList()),
),
),
// counter list end
// antrian selanjutnya start
SizedBox(
width: Constant.getActualX(context: context, x: 882),
height: Constant.getActualY(context: context, y: 66),
child: Text('Antrian Selanjutnya',
style: Constant.S50(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
Container(
// color: Colors.yellowAccent,
width: Constant.getActualX(context: context, x: 1920),
height: Constant.getActualY(context: context, y: 360),
child: GridView.count(
crossAxisSpacing: 10,
mainAxisSpacing: 0,
crossAxisCount: 3,
childAspectRatio: 5,
children: listBelumDilayani.value
.map(
(e) => MyAntrianCustomerServiceDedicated(
antrian: e.queueNumber,
skip: e.skipQueue,
),
)
.toList(),
),
),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:queuedisplay/model/branch_model.dart';
import 'package:queuedisplay/provider/dio_provider.dart';
import 'package:queuedisplay/repository/base_repository.dart';
import 'package:queuedisplay/repository/counter_repository.dart';
abstract class BranchListState extends Equatable {
final DateTime date;
const BranchListState(this.date);
@override
List<Object?> get props => [date];
}
class BranchListStateInit extends BranchListState {
BranchListStateInit() : super(DateTime.now());
}
class BranchListStateLoading extends BranchListState {
BranchListStateLoading() : super(DateTime.now());
}
class BranchListStateError extends BranchListState {
final String message;
BranchListStateError({
required this.message,
}) : super(DateTime.now());
}
class BranchListStateDone extends BranchListState {
final List<BranchModel> model;
BranchListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class BranchListNotifier extends StateNotifier<BranchListState> {
final Ref ref;
BranchListNotifier({
required this.ref,
}) : super(BranchListStateInit());
void list() async {
try {
state = BranchListStateLoading();
final dio = ref.read(dioProvider);
final resp = await CounterRepository(dio: dio).getBranch();
state = BranchListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = BranchListStateError(message: e.message);
} else {
state = BranchListStateError(message: e.toString());
}
}
}
}
//provider
final BranchListProvider =
StateNotifierProvider<BranchListNotifier, BranchListState>(
(ref) => BranchListNotifier(ref: ref));

View File

@@ -0,0 +1,656 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:queuedisplay/app/route.dart';
import 'package:queuedisplay/model/branch_model.dart';
import 'package:queuedisplay/model/error_msg_model.dart';
import 'package:queuedisplay/model/layanan_dokter.dart';
import 'package:queuedisplay/model/service_model.dart';
import 'package:queuedisplay/provider/layanan_dokter_provider.dart';
import 'package:queuedisplay/provider/service_provider.dart';
import 'package:queuedisplay/screen/settings/branch_list_provider.dart';
import 'package:queuedisplay/widget/display_counter.dart';
import 'package:queuedisplay/widget/my_error_dialog_state.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../model/counter_model.dart';
import '../../model/sampling_location_model.dart';
import '../../provider/all_service_provider.dart';
import '../../provider/counter_provider.dart';
import '../../provider/sampling_location_provider.dart';
import '../../widget/SamplingSoundSetting.dart';
import '../../widget/counter_sound_setting.dart';
import '../../widget/display_dokter.dart';
import '../../widget/my_error_dialog.dart';
class SettingScreenCounterDedicated extends HookConsumerWidget {
const SettingScreenCounterDedicated({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final init = useState(true);
final ctrlJudul = useTextEditingController(text: "");
final ctrlJudulError = useState(false);
final isLoading = useState(false);
final errorMessage = useState("");
final listService = useState<List<Layanan>>(List.empty());
final activeLayanan = useState<List>(List.empty());
final activeSoundCounter = useState<List>(List.empty());
final serviceIDArr = useState<List>(List.empty());
final data = useState('N');
final isLoadingDoctor = useState(false);
final listServiceDoctor = useState<List<LayananDokter>>(List.empty());
final activeSoundDoctor = useState<List>(List.empty());
// Sampling
final isLoadingSamplingLocation = useState(false);
final listSamplingLocation = useState<List<SamplingLocation>>(List.empty());
final activeSoundSamplingLocation = useState<List>(List.empty());
// Media Promo
final tanpaMediaPromo = useState(false);
final errorMsgList = useState<List<ErrorMsgModel>>(List.empty());
//Branch
final branchList = useState<List<BranchModel>>([]);
final selectedBranch = useState<BranchModel?>(null);
_isThereCurrentDialogShowing(BuildContext context) =>
ModalRoute.of(context)?.isCurrent != true;
// function
Future delData() async {
// Obtain shared preferences.
try {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('counter_dedicated');
} catch (e) {
// print(e);
}
}
Future getData() async {
try {
final prefs = await SharedPreferences.getInstance();
var rawData = prefs.getString('counter_dedicated') ?? 'a';
data.value = rawData;
if (rawData != 'a') {
listService.value = ref.read(allServiceProvider);
var data = json.decode(rawData);
ctrlJudul.text = data['judul'];
activeLayanan.value = data['activeLayanan'] ?? List.empty();
activeSoundCounter.value = data['activeSoundCounter'] ?? List.empty();
activeSoundDoctor.value = data['activeSoundDoctor'] ?? List.empty();
activeSoundSamplingLocation.value =
data['activeSoundSamplingLocation'] ?? List.empty();
selectedBranch.value = BranchModel.fromJson(data['selectedBranch']);
// media promo
tanpaMediaPromo.value = data['tanpaMediaPromo'] ?? List.empty();
if (activeLayanan.value.isNotEmpty) {
activeLayanan.value.forEach((e) {
listService.value.forEach((f) {
if (e == f.counterID) {
f.value = true;
}
});
});
}
// suara counter
if (activeSoundCounter.value.isNotEmpty) {
activeSoundCounter.value.forEach((e) {
listService.value.forEach((f) {
if (e == f.counterID) {
f.sound = true;
}
});
});
}
// suara sampling
if (activeSoundSamplingLocation.value.isNotEmpty) {
activeSoundSamplingLocation.value.forEach((e) {
listSamplingLocation.value.forEach((f) {
if (e == f.mLocationID) {
f.value = true;
// print(e);
}
});
});
}
// suara dokter
if (activeSoundDoctor.value.isNotEmpty) {
activeSoundDoctor.value.forEach((e) {
listServiceDoctor.value.forEach((f) {
if (e == f.id) {
f.value = true;
// print(e);
}
});
});
}
}
} catch (e) {
// print(e);
myErrorDialog(
context, e.toString(), 'ERROR: Get data shared preference');
}
}
Future<bool> saveData() async {
try {
final prefs = await SharedPreferences.getInstance();
var distinctList = activeLayanan.value.toSet().toList();
// suara counter
var distinctListCounterSnd = activeSoundCounter.value.toSet().toList();
// suara doctor
var distinctListDoctorSnd = activeSoundDoctor.value.toSet().toList();
// suara sampling
var distinctListSamplingSnd =
activeSoundSamplingLocation.value.toSet().toList();
// media promo
var distinctMediaPromoSnd = tanpaMediaPromo.value;
var serviceIDTemp = List.empty(growable: true);
var serviceIDTempSuara = List.empty(growable: true);
listService.value.forEach((i) {
distinctList.forEach((j) {
if (i.counterID == int.parse(j.toString())) {
if (i.serviceID != null) {
List listServiceIDx = i.serviceID!.split(',');
serviceIDTemp.addAll(listServiceIDx);
}
}
});
});
// suara counter
listService.value.forEach((i) {
distinctListCounterSnd.forEach((j) {
if (i.counterID == int.parse(j.toString())) {
if (i.serviceID != null) {
List listServiceIDx = i.serviceID!.split(',');
serviceIDTempSuara.addAll(listServiceIDx);
}
}
});
});
final Map<String, dynamic> data = {
"judul": ctrlJudul.text,
"activeLayanan": distinctList,
"activeSoundDoctor": distinctListDoctorSnd,
"activeSoundCounter": distinctListCounterSnd,
"activeSoundSamplingLocation": distinctListSamplingSnd,
"tanpaMediaPromo": distinctMediaPromoSnd,
"serviceID": serviceIDTemp,
"selectedBranch": selectedBranch.value,
"serviceIDSuara": serviceIDTempSuara,
};
await prefs.setString('counter_dedicated', json.encode(data));
// print(data);
return true;
} catch (e) {
myErrorDialog(
context, e.toString(), 'ERROR: Save data sahred preference');
// print(e);
return false;
}
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
ref.read(BranchListProvider.notifier).list();
// ref.read(layananProvider.notifier).list();
// ref.read(SamplingLocationProvider.notifier).list();
await getData();
});
return () {};
}, []);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
if (selectedBranch.value != null) {
if (!init.value) {
activeLayanan.value = [];
listService.value = [];
activeSoundCounter.value = [];
}
init.value = false;
ref
.read(serviceProvider.notifier)
.list(selectedBranch.value?.mBranchID ?? ')');
}
});
return () {};
}, [selectedBranch.value]);
// counter
ref.listen(serviceProvider, (prev, next) {
if (next is ServiceListStateLoading) {
isLoading.value = true;
} else if (next is ServiceListStateError) {
isLoading.value = false;
errorMessage.value = next.message;
List<ErrorMsgModel> msg = ref.read(errorListMsgProvider);
msg.add(ErrorMsgModel(
title: "ERROR: Get data list counter", msg: next.message));
ref.read(errorListMsgProvider.notifier).state = msg;
if (!_isThereCurrentDialogShowing(context)) {
myErrorDialogState(context, 'ERROR: Get data list counter');
}
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is ServiceListStateDone) {
isLoading.value = false;
listService.value = next.model;
if (activeLayanan.value.isNotEmpty) {
activeLayanan.value.forEach((e) {
listService.value.forEach((f) {
if (e == f.counterID) {
f.value = true;
}
});
});
}
// suara aktif?
if (activeSoundCounter.value.isNotEmpty) {
activeSoundCounter.value.forEach((e) {
listService.value.forEach((f) {
if (e == f.counterID) {
f.sound = true;
}
});
});
}
}
});
// sampling location
ref.listen(SamplingLocationProvider, (prev, next) {
if (next is SamplingLocationListLoading) {
isLoadingSamplingLocation.value = true;
} else if (next is SamplingLocationListError) {
isLoadingSamplingLocation.value = false;
errorMessage.value = next.message;
List<ErrorMsgModel> msg = ref.read(errorListMsgProvider);
msg.add(ErrorMsgModel(
title: "ERROR: Get data list sampling sound", msg: next.message));
ref.read(errorListMsgProvider.notifier).state = msg;
if (!_isThereCurrentDialogShowing(context)) {
myErrorDialogState(context, 'ERROR: Get data list sampling sound');
}
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is SamplingLocationListDone) {
isLoadingSamplingLocation.value = false;
listSamplingLocation.value = next.model;
if (activeSoundSamplingLocation.value.isNotEmpty) {
activeSoundSamplingLocation.value.forEach((e) {
listSamplingLocation.value.forEach((f) {
if (e == f.mLocationID) {
f.value = true;
// print(e);
}
});
});
}
// print(jsonEncode(next.model));
}
});
// layanan dokter
ref.listen(layananProvider, (prev, next) {
if (next is LayananListStateLoading) {
isLoadingDoctor.value = true;
} else if (next is LayananListStateError) {
isLoadingDoctor.value = false;
errorMessage.value = next.message;
List<ErrorMsgModel> msg = ref.read(errorListMsgProvider);
msg.add(ErrorMsgModel(
title: "ERROR: Get data list sound doctor", msg: next.message));
ref.read(errorListMsgProvider.notifier).state = msg;
if (!_isThereCurrentDialogShowing(context)) {
myErrorDialogState(context, 'ERROR: Get data list sound doctor');
}
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is LayananListStateDone) {
isLoadingDoctor.value = false;
listServiceDoctor.value = next.model;
if (activeSoundDoctor.value.isNotEmpty) {
activeSoundDoctor.value.forEach((e) {
listServiceDoctor.value.forEach((f) {
if (e == f.id) {
f.value = true;
}
});
});
}
}
});
ref.listen(BranchListProvider, (previous, next) {
if (next is BranchListStateLoading) {
isLoading.value = true;
} else if (next is BranchListStateError) {
myErrorDialog(context, next.message, 'ERROR');
isLoading.value = false;
} else if (next is BranchListStateDone) {
// ref.read(allServiceProvider.notifier).state = next.model;
// print(ref.read(allServiceProvider));
branchList.value = next.model;
isLoading.value = false;
}
});
return Material(
child: Container(
height: Constant.getActualY(context: context, y: 982),
width: Constant.getActualX(context: context, x: 1512),
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage('images/background.png'),
),
),
child: Center(
child: Card(
color: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
elevation: 5,
child: SizedBox(
height: Constant.getActualY(context: context, y: 880),
width: Constant.getActualX(context: context, x: 1360),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 30),
vertical: Constant.getActualY(context: context, y: 30),
),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
// TextButton(
// onPressed: () {
// Navigator.of(context)
// .popAndPushNamed(displayRoute);
// // print(pm.currentStatusUSB);
// // print(pm.currentStatusUSB);
// },
// child: const Text('back')),
Text(
'Setting',
style: Constant.subTitle(context: context),
),
// TextButton(
// onPressed: () {
// delData();
// },
// child: const Text('Delete All')),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 30),
),
Text(
'Cabang*',
style: Constant.label(context: context),
),
SizedBox(
height: Constant.getActualY(context: context, y: 60),
child: DropdownButtonFormField<BranchModel>(
style: Constant.normal(context: context)
.copyWith(color: Colors.black),
decoration: const InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
),
),
menuMaxHeight:
Constant.getActualY(context: context, y: 500),
hint: Text(selectedBranch.value?.mBranchName ?? ''),
items: branchList.value
.map((e) => DropdownMenuItem<BranchModel>(
value: e, child: Text(e.mBranchName ?? '')))
.toList(),
onChanged: (BranchModel? e) {
// print(e);
selectedBranch.value = e!;
},
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Text(
'Judul Header*',
style: Constant.label(context: context),
),
SizedBox(
width: Constant.getActualX(context: context, x: 1300),
child: TextField(
controller: ctrlJudul,
onChanged: (value) {
if (value.trim() == "") {
ctrlJudulError.value = true;
}
if (value.trim() != "") {
ctrlJudulError.value = false;
}
},
decoration: InputDecoration(
errorText: ctrlJudulError.value
? "Tidak boleh kosong"
: null,
border: const OutlineInputBorder(),
focusedBorder: const OutlineInputBorder(
borderSide:
BorderSide(color: Colors.blue, width: 2)),
hintText: "example Customer Service",
hintStyle: Constant.label(context: context)),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Text(
'Display Counter*',
style: Constant.label(context: context),
),
// widget counter
DisplayCounter(
isloading: isLoading,
listService: listService,
activeLayanan: activeLayanan,
),
//SOUND COUNTER
SizedBox(
height: Constant.getActualY(context: context, y: 50),
),
Text(
'Proses Suara Counter/FO',
style: Constant.label(context: context),
),
// suara
CounterSoundSetting(
isLoading: isLoading,
listService: listService,
activeSoundCounter: activeSoundCounter),
//END SOUND COUNTER
SizedBox(
height: Constant.getActualY(context: context, y: 50),
),
// Text(
// 'Proses Suara Sampling',
// style: Constant.label(context: context),
// ),
// SamplingSoundSetting(
// isloading: isLoadingSamplingLocation,
// listSamplingLocation: listSamplingLocation,
// activeSoundSampling: activeSoundSamplingLocation,
// ),
// SizedBox(
// height: Constant.getActualY(context: context, y: 50),
// ),
// Text(
// 'Proses Suara Layanan Dokter ',
// style: Constant.label(context: context),
// ),
// // DISPLAY LAYANAN DOKTER
// DisplayDoctor(
// isLoadingDoctor: isLoadingDoctor,
// listServiceDoctor: listServiceDoctor,
// activeSoundDoctor: activeSoundDoctor,
// ),
// // // END DISPLAY LAYANAN DOKTER
// Checkbox banner media promo start
// SizedBox(
// height: Constant.getActualY(context: context, y: 50),
// ),
Text(
'Media Promo',
style: Constant.label(context: context),
),
SizedBox(
// width: Constant.getActualX(
// context: context, x: 500),
height: Constant.getActualY(context: context, y: 200),
child: GridView.count(
childAspectRatio:
Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15),
crossAxisCount: 2,
children: [
Row(
children: [
FractionallySizedBox(
child: CupertinoSwitch(
value: tanpaMediaPromo.value,
onChanged: (val) {
if (val) {
var rwData =
json.encode(tanpaMediaPromo.value);
bool data = json.decode(rwData);
bool actlyn = data;
actlyn = !val;
tanpaMediaPromo.value = actlyn;
}
if (!val) {
var rwData =
json.encode(tanpaMediaPromo.value);
bool data = json.decode(rwData);
bool actlyn = data;
actlyn = !val;
tanpaMediaPromo.value = actlyn;
}
tanpaMediaPromo.value = val;
},
),
),
Expanded(
child: Text(
"Tanpa Media Promo",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.normal(context: context),
),
)
],
),
]),
),
// Checkbox banner media promo end
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Center(
child: SizedBox(
height: Constant.getActualY(context: context, y: 60),
width: Constant.getActualX(context: context, x: 200),
child: TextButton(
onPressed: () {
if (ctrlJudul.text.isNotEmpty &&
activeLayanan.value.isNotEmpty &&
selectedBranch.value != null) {
saveData();
ref.read(allServiceProvider.notifier).state =
listService.value;
ref
.read(allServiceDoctorProvider.notifier)
.state = listServiceDoctor.value;
Navigator.of(context).pushNamedAndRemoveUntil(
customerServiceDedicatedRoute,
(route) => false);
return;
} else {
if (ctrlJudul.text.isEmpty) {
myErrorDialog(
context,
'Input bertanda * tidak boleh kosong',
'PERINGATAN');
} else if (activeLayanan.value.isEmpty) {
myErrorDialog(
context,
'Layanan belum ada yang aktif',
'PERINGATAN');
}
}
},
style: TextButton.styleFrom(
elevation: 5, backgroundColor: Colors.blue),
child: Text(
'Save',
style: Constant.subTitle(context: context)
.copyWith(color: Colors.white),
),
)),
)
],
),
),
),
),
),
),
));
}
}

View File

@@ -0,0 +1,425 @@
import 'package:flutter/material.dart';
import 'package:flutter_image_slideshow/flutter_image_slideshow.dart';
import 'package:text_scroll/text_scroll.dart';
import '../app/constant.dart';
import '../model/display_counter_dedicated_modelv2.dart';
import '../model/service_model.dart';
import '../widget/clock.dart';
import '../widget/my_antrian_customer_service_dedicated.dart';
import '../widget/my_counter_customer_service_dedicated.dart';
class WithMediaPromo extends StatelessWidget {
const WithMediaPromo({
Key? key,
required this.listBelumDilayani,
required this.isLoading,
required this.judul,
required this.scrlCnt,
required this.selectedCounter,
required this.listCall,
required this.listSedangDilayani,
}) : super(key: key);
final ValueNotifier<List<NotServed>> listBelumDilayani;
final ValueNotifier<bool> isLoading;
final ValueNotifier<String> judul;
final ScrollController scrlCnt;
final ValueNotifier<List<Layanan>> selectedCounter;
final ValueNotifier<List<Call>> listCall;
final ValueNotifier<List<Served>> listSedangDilayani;
@override
Widget build(BuildContext context) {
getNomorAntrian(String counterID) {
var rawCall = listCall.value;
// print(rawCall);
Call call = Call(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawCall.length; i++) {
if (rawCall[i].queueCounterID == counterID) {
call = rawCall[i];
}
}
var rawProcess = listSedangDilayani.value;
Served process = Served(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawProcess.length; i++) {
if (rawProcess[i].queueCounterID == counterID) {
process = rawProcess[i];
}
}
if (call.queueID != '0' && process.queueID == '0') {
return call.queueNumber;
} else if (call.queueID == '0' && process.queueID != '0') {
return process.queueNumber;
} else if (call.queueID == '0' && process.queueID == '0') {
return '-';
} else {
return call.queueNumber;
}
}
getBlinkAntrian(String counterID) {
var rawCall = listCall.value;
// print(rawCall);
Call call = Call(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawCall.length; i++) {
if (rawCall[i].queueCounterID == counterID) {
call = rawCall[i];
}
}
var rawProcess = listSedangDilayani.value;
Served process = Served(
queueID: '0',
statusID: '0',
queueNumber: '0',
queueCounterID: '0',
counterCode: '0',
orderStatus: '0');
for (var i = 0; i < rawProcess.length; i++) {
if (rawProcess[i].queueCounterID == counterID) {
process = rawProcess[i];
}
}
if (call.queueID != '0' && process.queueID == '0') {
return true;
} else if (call.queueID == '0' && process.queueID != '0') {
return false;
} else if (call.queueID == '0' && process.queueID == '0') {
return false;
} else {
return true;
}
}
return Material(
child: Container(
width: Constant.getActualX(context: context, x: 1920),
height: Constant.getActualY(context: context, y: 1080),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('images/background.png'), fit: BoxFit.fill)),
child: Padding(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 68),
right: Constant.getActualX(context: context, x: 68),
top: Constant.getActualY(context: context, y: 34),
bottom: Constant.getActualY(context: context, y: 32)),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Column(
// mainAxisAlignment: MainAxisAlignment.end,
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
//TV
SizedBox(
width: Constant.getActualX(context: context, x: 882),
height: Constant.getActualY(context: context, y: 508),
child: ImageSlideshow(
indicatorColor: Colors.transparent,
indicatorBackgroundColor: Colors.transparent,
autoPlayInterval: 5000,
isLoop: true,
children: [
// Container(
// child:
// ),
Image.network(
'https://${Constant.baseSocket}/one-media/one-queue/slide-counter/1.jpg',
errorBuilder: (context, error, stackTrace) {
return Image.asset(
'images/1.jpg',
fit: BoxFit.fitWidth,
);
},
headers: {
'Access-Control-Allow-Origin': '*',
},
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
Image.network(
'https://${Constant.baseSocket}/one-media/one-queue/slide-counter/2.jpg',
errorBuilder: (context, error, stackTrace) {
return Image.asset(
'images/2.jpg',
fit: BoxFit.fitWidth,
);
},
headers: {
'Access-Control-Allow-Origin': '*',
},
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
Image.network(
'https://${Constant.baseSocket}/one-media/one-queue/slide-counter/3.jpg',
errorBuilder: (context, error, stackTrace) {
return Image.asset(
'images/3.jpg',
fit: BoxFit.fitWidth,
);
},
headers: {
'Access-Control-Allow-Origin': '*',
},
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
Image.network(
'https://${Constant.baseSocket}/one-media/one-queue/slide-counter/4.jpg',
errorBuilder: (context, error, stackTrace) {
return Image.asset(
'images/4.jpg',
fit: BoxFit.fitWidth,
);
},
headers: {
'Access-Control-Allow-Origin': '*',
},
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
Image.network(
'https://${Constant.baseSocket}/one-media/one-queue/slide-counter/5.jpg',
errorBuilder: (context, error, stackTrace) {
return Image.asset(
'images/5.jpg',
fit: BoxFit.fitWidth,
);
},
headers: {
'Access-Control-Allow-Origin': '*',
},
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
],
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 10),
),
// waktu yg direvisi
Clock(),
//Antrian Selanjutnya
SizedBox(
width: Constant.getActualX(context: context, x: 882),
height: Constant.getActualY(context: context, y: 66),
child: Text('Antrian Selanjutnya',
style: Constant.S50(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 882),
height: Constant.getActualY(context: context, y: 300),
child: GridView.count(
crossAxisSpacing: 10,
mainAxisSpacing: 0,
crossAxisCount: 2,
childAspectRatio: 4,
children: listBelumDilayani.value
.map(
(e) => GestureDetector(
onTap: () {
// process_sound(
// e['waiting'].queueNumber, "r117");
},
child: MyAntrianCustomerServiceDedicated(
skip: e.skipQueue,
antrian: e.queueNumber,
),
),
)
.toList(),
),
),
],
),
// const Spacer(),
SizedBox(
width: Constant.getActualX(context: context, x: 40),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 808),
height: Constant.getActualY(context: context, y: 160),
child: Stack(
alignment: Alignment.centerLeft,
children: [
Container(
width:
Constant.getActualX(context: context, x: 808),
height:
Constant.getActualY(context: context, y: 72),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.25),
blurRadius: 8)
],
borderRadius: BorderRadius.circular(20),
color: Colors.white),
child: Padding(
padding: EdgeInsets.only(
top: 6,
left: Constant.getActualX(
context: context, x: 120),
),
child: Stack(
alignment: Alignment.centerLeft,
children: [
if (isLoading.value)
SizedBox(
width: Constant.getActualX(
context: context, x: 60),
height: Constant.getActualX(
context: context, x: 70),
child:
const CircularProgressIndicator(),
),
TextScroll(judul.value,
velocity: Velocity(
pixelsPerSecond: Offset(50, 0)),
style: Constant.body_3(context: context)
.copyWith(color: Constant.textRed)),
],
),
),
),
Container(
width:
Constant.getActualX(context: context, x: 100),
height:
Constant.getActualY(context: context, y: 100),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient: LinearGradient(
colors: [Constant.red1, Constant.red2])),
),
Positioned(
top: 0,
child: Image.asset(
'images/cs.png',
fit: BoxFit.cover,
height: 100,
),
)
],
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 20),
),
],
),
SizedBox(
width: Constant.getActualX(context: context, x: 808),
height: Constant.getActualY(context: context, y: 820),
child: GridView.count(
scrollDirection: Axis.horizontal,
controller: scrlCnt,
crossAxisSpacing: 90,
mainAxisSpacing: 60,
crossAxisCount: 2,
children: selectedCounter.value
.map(
(e) => MyCounterCustomerServiceDedicated(
// counter: 'DOKTER UMUM',
counter: 'Counter ${e.counterCode}',
nomorAntrian:
getNomorAntrian(e.counterID.toString()),
// nomorAntrian: 'LA 001',
borderDalam: const BorderRadius.only(
topLeft: Radius.circular(50),
topRight: Radius.circular(50),
bottomLeft: Radius.circular(50)),
borderLuar: const BorderRadius.only(
topLeft: Radius.circular(60),
topRight: Radius.circular(60),
bottomLeft: Radius.circular(60),
),
blink: getBlinkAntrian(e.counterID.toString()),
),
)
.toList()),
),
],
),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,96 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:queuedisplay/model/sampling_location_model.dart';
import '../app/constant.dart';
import '../model/counter_model.dart';
class SamplingSoundSetting extends StatelessWidget {
const SamplingSoundSetting({
Key? key,
required this.isloading,
required this.listSamplingLocation,
required this.activeSoundSampling,
}) : super(key: key);
final ValueNotifier<bool> isloading;
final ValueNotifier<List<SamplingLocation>> listSamplingLocation;
final ValueNotifier<List> activeSoundSampling;
@override
Widget build(BuildContext context) {
return Padding(
padding:
EdgeInsets.only(right: Constant.getActualX(context: context, x: 50)),
child: SizedBox(
height: listSamplingLocation.value.length != 1
? (Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15)) *
(listSamplingLocation.value.length * 3.1)
: Constant.getActualY(context: context, y: 70),
child: (isloading.value)
? Column(
children: [
Expanded(
child: Center(
child: SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 90),
child: const CircularProgressIndicator(),
),
),
),
],
)
: GridView.count(
childAspectRatio:
Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15),
crossAxisCount: 2,
children: listSamplingLocation.value
.map(
(e) => Row(
children: [
FractionallySizedBox(
child: CupertinoSwitch(
value: e.value,
onChanged: (val) {
if (val) {
var rwData =
json.encode(activeSoundSampling.value);
List data = json.decode(rwData);
List actSnd = data;
actSnd.add(e.mLocationID);
activeSoundSampling.value = actSnd;
}
if (!val) {
var rwData =
json.encode(activeSoundSampling.value);
List data = json.decode(rwData);
List actSnd = data;
actSnd.remove(e.mLocationID);
activeSoundSampling.value = actSnd;
}
e.value = val;
},
),
),
Expanded(
child: Text(
"${e.mLocationName}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.normal(context: context),
))
],
),
)
.toList(),
),
),
);
}
}

60
lib/widget/clock.dart Normal file
View File

@@ -0,0 +1,60 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/intl.dart';
import '../app/constant.dart';
class Clock extends HookConsumerWidget {
const Clock({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final strHour = useState("");
final strMinute = useState("");
final strDate = useState("");
final strMonth = useState("");
final strYear = useState("");
useEffect(() {
final tmr = Timer.periodic(const Duration(seconds: 1), (timer) {
final dt = DateFormat('yyyy-MMMM-dd-HH-mm-ss').format(DateTime.now());
final splited = dt.split('-');
final date = splited[2].toString();
final month = splited[1].toString();
final year = splited[0].toString();
final hour = splited[3].toString();
final minute = splited[4].toString();
if (hour != strHour.value) strHour.value = hour;
if (minute != strMinute.value) strMinute.value = minute;
if (date != strDate.value) strDate.value = date;
if (month != strMonth.value) strMonth.value = month;
if (year != strYear.value) strYear.value = year;
});
return () {
tmr.cancel();
};
}, []);
return SizedBox(
width: Constant.getActualX(context: context, x: 882),
height: Constant.getActualY(context: context, y: 50),
child: Container(
width: Constant.getActualX(context: context, x: 882),
height: Constant.getActualY(context: context, y: 50),
// decoration: BoxDecoration(boxShadow: [
// BoxShadow(color: Colors.black.withOpacity(0.25), blurRadius: 8)
// ], borderRadius: BorderRadius.circular(20), color: Colors.white),
child: Text(
'${strDate.value} ${strMonth.value} ${strYear.value} ${strHour.value} : ${strMinute.value}',
textAlign: TextAlign.left,
style: Constant.body_3(context: context)
.copyWith(color: Constant.textRed)),
),
);
}
}

View File

@@ -0,0 +1,96 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../app/constant.dart';
import '../model/service_model.dart';
class CounterSoundSetting extends StatelessWidget {
const CounterSoundSetting({
Key? key,
required this.isLoading,
required this.listService,
required this.activeSoundCounter,
}) : super(key: key);
final ValueNotifier<bool> isLoading;
final ValueNotifier<List<Layanan>> listService;
final ValueNotifier<List> activeSoundCounter;
@override
Widget build(BuildContext context) {
return Padding(
padding:
EdgeInsets.only(right: Constant.getActualX(context: context, x: 50)),
child: SizedBox(
height: listService.value.length != 1
? (Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15)) *
(listService.value.length * 3.5)
: Constant.getActualY(context: context, y: 70),
child: (isLoading.value)
? Column(
children: [
Expanded(
child: Center(
child: SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 90),
child: const CircularProgressIndicator(),
),
),
),
],
)
: GridView.count(
childAspectRatio:
Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15),
crossAxisCount: 2,
children: listService.value
.map(
(e) => Row(
children: [
FractionallySizedBox(
child: CupertinoSwitch(
value: e.sound,
onChanged: (val) {
if (val) {
var rwData =
json.encode(activeSoundCounter.value);
List data = json.decode(rwData);
List actlyn = data;
actlyn.add(e.counterID);
activeSoundCounter.value = actlyn;
}
if (!val) {
var rwData =
json.encode(activeSoundCounter.value);
List data = json.decode(rwData);
List actlyn = data;
actlyn.remove(e.counterID);
activeSoundCounter.value = actlyn;
}
e.sound = val;
},
),
),
Expanded(
child: Text(
"${e.counterCode} - ${e.locationName}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.normal(context: context),
),
)
],
),
)
.toList(),
),
),
);
}
}

View File

@@ -0,0 +1,98 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:queuedisplay/model/service_model.dart';
import '../app/constant.dart';
class DisplayCounter extends StatelessWidget {
const DisplayCounter(
{Key? key,
required this.isloading,
required this.listService,
required this.activeLayanan})
: super(key: key);
final ValueNotifier<bool> isloading;
final ValueNotifier<List<Layanan>> listService;
// final ValueNotifier<List> activeLayanan;
final ValueNotifier<List> activeLayanan;
@override
Widget build(BuildContext context) {
return Padding(
padding:
EdgeInsets.only(right: Constant.getActualX(context: context, x: 50)),
child: Container(
// width: Constant.getActualX(
// context: context, x: 500),
height: listService.value.length != 1
? (Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15)) *
(listService.value.length * 3.5)
: Constant.getActualY(context: context, y: 70),
// color: Colors.red,
child: (isloading.value)
? Column(
children: [
Expanded(
child: Center(
child: SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 90),
child: const CircularProgressIndicator(),
),
),
),
],
)
: GridView.count(
childAspectRatio:
Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15),
crossAxisCount: 2,
children: listService.value
.map(
(e) => Row(
children: [
FractionallySizedBox(
child: CupertinoSwitch(
value: e.value,
onChanged: (val) {
if (val) {
var rwData = json.encode(activeLayanan.value);
List data = json.decode(rwData);
List actlyn = data;
actlyn.add(e.counterID);
activeLayanan.value = actlyn;
}
if (!val) {
var rwData = json.encode(activeLayanan.value);
List data = json.decode(rwData);
List actlyn = data;
actlyn.remove(e.counterID);
activeLayanan.value = actlyn;
}
e.value = val;
},
),
),
Expanded(
child: Text(
"${e.counterCode} - ${e.locationName}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.normal(context: context),
),
)
],
),
)
.toList(),
),
),
);
}
}

View File

@@ -0,0 +1,106 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../app/constant.dart';
import '../model/layanan_dokter.dart';
class DisplayDoctor extends StatelessWidget {
const DisplayDoctor({
Key? key,
required this.isLoadingDoctor,
required this.listServiceDoctor,
required this.activeSoundDoctor,
}) : super(key: key);
final ValueNotifier<bool> isLoadingDoctor;
final ValueNotifier<List<LayananDokter>> listServiceDoctor;
final ValueNotifier<List> activeSoundDoctor;
@override
Widget build(BuildContext context) {
return Padding(
padding:
EdgeInsets.only(right: Constant.getActualX(context: context, x: 50)),
child: SizedBox(
// color: Colors.red,
// width: Constant.getActualX(
// context: context, x: 500),
height: listServiceDoctor.value.length != 1
? (Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15)) *
(listServiceDoctor.value.length * 3.1)
: Constant.getActualY(context: context, y: 70),
child: (isLoadingDoctor.value)
? Column(
children: [
Expanded(
child: Center(
child: SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 90),
child: const CircularProgressIndicator(),
),
),
),
],
)
: GridView.count(
childAspectRatio:
Constant.getActualY(context: context, y: 150) /
Constant.getActualX(context: context, x: 15),
crossAxisCount: 2,
children: listServiceDoctor.value
.map(
(e) => Row(
children: [
FractionallySizedBox(
child: CupertinoSwitch(
value: e.value,
onChanged: (val) {
if (val) {
var rwData =
json.encode(activeSoundDoctor.value);
List data = json.decode(rwData);
List actlyn = data;
actlyn.add(e.id);
activeSoundDoctor.value = actlyn;
}
if (!val) {
var rwData =
json.encode(activeSoundDoctor.value);
List data = json.decode(rwData);
List actlyn = data;
actlyn.remove(e.id);
activeSoundDoctor.value = actlyn;
}
e.value = val;
},
),
),
Expanded(
child: e.isConsultDoctor == 'N'
? Text(
e.name,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.normal(context: context),
)
: Text(
"${e.name} ${e.doctorName}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.normal(context: context),
),
)
],
),
)
.toList(),
),
),
);
}
}

View File

@@ -0,0 +1,115 @@
import 'package:flutter/material.dart';
import '../app/constant.dart';
class MyAntrianCustomerServiceDedicated extends StatelessWidget {
final String antrian;
final String skip;
const MyAntrianCustomerServiceDedicated(
{Key? key, required this.antrian, required this.skip})
: super(key: key);
@override
Widget build(BuildContext context) {
// return SizedBox(
// width: Constant.getActualX(context: context, x: 420),
// height: Constant.getActualY(context: context, y: 100),
// child: Stack(
// alignment: Alignment.centerLeft,
// children: [
// Container(
// width: Constant.getActualX(context: context, x: 420),
// height: Constant.getActualY(context: context, y: 80),
// decoration: BoxDecoration(boxShadow: [
// BoxShadow(color: Colors.black.withOpacity(0.25), blurRadius: 8)
// ], borderRadius: BorderRadius.circular(20), color: Colors.white),
// child: Padding(
// padding: const EdgeInsets.only(
// left: 80,
// ),
// child: Text(antrian,
// textAlign: TextAlign.center,
// style: Constant.h2(context: context)
// .copyWith(color: Constant.textRed)),
// ),
// ),
// Padding(
// padding: const EdgeInsets.all(15),
// child: Container(
// width: Constant.getActualX(context: context, x: 100),
// height: Constant.getActualY(context: context, y: 100),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(20),
// gradient:
// LinearGradient(colors: [Constant.red1, Constant.red2])),
// child: const Icon(
// Icons.arrow_forward_ios_rounded,
// size: 40,
// color: Colors.white,
// ),
// ),
// ),
// ],
// ),
// );
return SingleChildScrollView(
child: SizedBox(
width: Constant.getActualX(context: context, x: 890),
height: Constant.getActualY(context: context, y: 100),
child: Stack(
alignment: Alignment.centerLeft,
children: [
Container(
width: Constant.getActualX(context: context, x: 890),
height: Constant.getActualY(context: context, y: 80),
decoration: BoxDecoration(boxShadow: [
BoxShadow(color: Colors.black.withOpacity(0.25), blurRadius: 8)
], borderRadius: BorderRadius.circular(20), color: Colors.white),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 80),
),
Expanded(
child: Text(
antrian,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: Constant.S50(context: context)
.copyWith(color: Constant.textRed),
),
),
skip != 'NEW'
? SizedBox(
width: Constant.getActualX(context: context, x: 100),
child: Text('Skipped'))
: SizedBox()
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 10,
),
child: Container(
width: Constant.getActualX(context: context, x: 50),
height: Constant.getActualY(context: context, y: 50),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient:
LinearGradient(colors: [Constant.red1, Constant.red2])),
child: const Icon(
Icons.arrow_forward_ios_rounded,
size: 30,
color: Colors.white,
),
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,105 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import '../app/constant.dart';
class MyCounterCustomerServiceDedicated extends HookWidget {
final String counter;
final String nomorAntrian;
final BorderRadiusGeometry borderLuar;
final BorderRadiusGeometry borderDalam;
final bool blink;
const MyCounterCustomerServiceDedicated(
{Key? key,
required this.counter,
required this.nomorAntrian,
required this.borderLuar,
required this.borderDalam,
required this.blink})
: super(key: key);
@override
Widget build(BuildContext context) {
AnimationController _ac =
useAnimationController(duration: Duration(seconds: 2), initialValue: 1);
_ac.repeat();
return Stack(
alignment: Alignment.center,
children: [
Container(
width: Constant.getActualX(context: context, x: 355),
height: Constant.getActualY(context: context, y: 355),
decoration: BoxDecoration(
borderRadius: borderLuar,
gradient: LinearGradient(colors: [Constant.red1, Constant.red2]),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.25),
blurRadius: 8,
offset: const Offset(-2, 6))
],
),
),
Container(
width: Constant.getActualX(context: context, x: 297),
height: Constant.getActualY(context: context, y: 297),
decoration: BoxDecoration(
borderRadius: borderDalam,
border: Border.all(
color: Colors.white,
strokeAlign: BorderSide.strokeAlignInside,
width: 3),
color: Colors.transparent,
),
child: blink
? FadeTransition(
opacity: _ac,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(counter,
textAlign: TextAlign.center,
style: Constant.body_1(context: context)
.copyWith(color: Colors.white)),
// blink
// ? FadeTransition(
// opacity: _ac,
// child: Text(nomorAntrian,
// style: Constant.body_1(context: context)
// .copyWith(color: Colors.white)),
// )
// :
Text(nomorAntrian,
style: Constant.h1(context: context)
.copyWith(color: Colors.white)),
],
),
)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(counter,
textAlign: TextAlign.center,
style: Constant.body_1(context: context)
.copyWith(color: Colors.white)),
// blink
// ? FadeTransition(
// opacity: _ac,
// child: Text(nomorAntrian,
// style: Constant.body_1(context: context)
// .copyWith(color: Colors.white)),
// )
// :
Text(nomorAntrian,
style: Constant.S75(context: context)
.copyWith(color: Colors.white)),
],
),
)
],
);
}
}

View File

@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import '../../app/constant.dart';
Future<String?> myErrorDialog(
BuildContext context, String errorMsg, String header) {
return showDialog<String>(
context: context,
builder: (BuildContext context) => Dialog(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
header,
style: Constant.subTitle(context: context),
),
const SizedBox(
height: 10,
),
SizedBox(
width: Constant.getActualX(context: context, x: 700),
child: const Divider()),
SizedBox(
height: Constant.getActualY(context: context, y: 500),
width: Constant.getActualX(context: context, x: 700),
child: ListView(
children: [Text(errorMsg)],
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 700),
child: const Divider()),
const SizedBox(
height: 10,
),
SizedBox(
width: Constant.getActualX(context: context, x: 700),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Tutup'),
),
],
),
),
],
),
),
),
);
}

View File

@@ -0,0 +1,88 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:queuedisplay/model/error_msg_model.dart';
import 'package:queuedisplay/provider/all_service_provider.dart';
import '../../app/constant.dart';
Future<String?> myErrorDialogState(BuildContext context, String header) {
return showDialog<String>(
barrierDismissible: false,
context: context,
builder: (BuildContext context) =>
HookConsumer(builder: (context, ref, child) {
return Dialog(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Error",
style: Constant.subTitle(context: context),
),
const SizedBox(
height: 10,
),
SizedBox(
width: Constant.getActualX(context: context, x: 700),
child: const Divider()),
SizedBox(
height: Constant.getActualY(context: context, y: 500),
width: Constant.getActualX(context: context, x: 700),
child: ListView(
// children: [Text(jsonEncode(ref.watch(errorListMsgProvider)))],
children: ref
.watch(errorListMsgProvider)
.map((e) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
e.title.toString(),
style: TextStyle(color: Colors.red),
),
Text(e.msg.toString()),
// Text(jsonEncode(ref.watch(errorListMsgProvider))),
SizedBox(
height: Constant.getActualY(
context: context, y: 20),
)
],
))
.toList(),
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 700),
child: const Divider()),
const SizedBox(
height: 10,
),
SizedBox(
width: Constant.getActualX(context: context, x: 700),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
Navigator.pop(context);
ref.read(errorListMsgProvider.notifier).state =
List.empty(growable: true);
},
child: const Text('Tutup'),
),
],
),
),
],
),
),
);
}),
);
}