Browse Source

Fix Expanded

main
padmanto 2 years ago
parent
commit
52ffaffefd
  1. 10
      README.md
  2. 3
      lib/js/initial_route.dart
  3. 48
      lib/model/ac_doctor_model.dart
  4. 7
      lib/model/ac_mou_response_model.dart
  5. 4
      lib/provider/local_auth_provider.dart
  6. 33
      lib/repository/mitra_repository.dart
  7. 0
      lib/screen/home/new_screen.dart
  8. 2
      lib/screen/md_lab_mitra/md_lab_mitra_screen.dart
  9. 5
      lib/screen/md_lab_mitra/mitra_lookup_mou_provider.dart
  10. 2
      lib/screen/md_lab_mitra/mitra_search_provider.dart
  11. 32
      lib/screen/md_lab_mitra/timer_provider.dart
  12. 22
      lib/widget/fx_company_lookup.dart
  13. 1
      lib/widget/fx_data_mitra.dart
  14. 90
      lib/widget/fx_doctor_address.dart
  15. 102
      lib/widget/fx_doctor_lookup.dart
  16. 29
      lib/widget/fx_mitra_add_dialog.dart
  17. 52
      lib/widget/fx_mitra_mou.dart
  18. 46
      lib/widget/fx_text_field.dart
  19. 74
      lib/widget/provider/doctor_address_lookup_provider.dart
  20. 73
      lib/widget/provider/doctor_lookup_provider.dart
  21. 0
      lib/widget/provider/selectedCompanyProvider.dart
  22. 5
      lib/widget/provider/selectedDoctorProvider.dart
  23. 37
      php-api/mitra/Md.php
  24. 18
      web/index.html
  25. 14
      web/md_mitra_lab.html

10
README.md

@ -1,5 +1,7 @@
# onemd
Create web/md_mitra_lab.html
>Create web/md_mitra_lab.html
>(* will be build and ulded to one-ui-flutter/md-mitra/)
```html
<html lang="en">
<head>
@ -62,10 +64,12 @@ ul_flutter_ui devone.aplikasi.web.id
# one-ui from existing vuejs
( one-ui/flutter/one-md-mitralab/ )
>used file :
> index.php
> store.js
update store.js
>update store.js
```js
import system from "../../apps/modules/system/system.js";
export const store = new Vuex.Store({
@ -75,7 +79,7 @@ export const store = new Vuex.Store({
});
```
update index.php
>update index.php
```php
<!DOCTYPE html>
<html lang="en">

3
lib/js/initial_route.dart

@ -5,6 +5,9 @@ import 'dart:html' as html;
@JS('fx_initial_route')
external String fxInitialRoute();
@JS('parent_home')
external String parentHome();
String? getToken() {
return html.window.localStorage['token'];
}

48
lib/model/ac_doctor_model.dart

@ -0,0 +1,48 @@
class AcDoctorResponseModel {
late String fullName;
late String mDoctorID;
AcDoctorResponseModel({
required this.fullName,
required this.mDoctorID,
});
AcDoctorResponseModel.fromJson(Map<String, dynamic> json) {
fullName = json['FullName'];
mDoctorID = json['M_DoctorID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['FullName'] = fullName;
data['M_DoctorID'] = mDoctorID;
return data;
}
}
class AcDoctorAddressResponseModel {
late String mDoctorAddressDescription;
late String mDoctorAddressID;
late bool isCheck;
AcDoctorAddressResponseModel({
required this.mDoctorAddressDescription,
required this.mDoctorAddressID,
});
void setIsCheck(bool val) {
isCheck = val;
}
AcDoctorAddressResponseModel.fromJson(Map<String, dynamic> json) {
mDoctorAddressDescription = json['M_DoctorAddressDescription'];
mDoctorAddressID = json['M_DoctorAddressID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['M_DoctorAddressDescription'] = mDoctorAddressDescription;
data['M_DoctorAddressID'] = mDoctorAddressID;
data['isCheck'] = isCheck;
return data;
}
}

7
lib/model/ac_mou_response_model.dart

@ -7,7 +7,7 @@ class AcMouResponseModel {
late String mMouNote;
late String mMouNumber;
late String mMouStartDate;
late bool isCheck;
AcMouResponseModel({
required this.mMouEndDate,
required this.mMouID,
@ -17,6 +17,7 @@ class AcMouResponseModel {
required this.mMouNote,
required this.mMouNumber,
required this.mMouStartDate,
this.isCheck = false,
});
AcMouResponseModel.fromJson(Map<String, dynamic> json) {
@ -28,6 +29,10 @@ class AcMouResponseModel {
mMouNote = json['M_MouNote'] ?? "";
mMouNumber = json['M_MouNumber'] ?? "";
mMouStartDate = json['M_MouStartDate'] ?? "";
isCheck = false;
}
void setCheck(bool val) {
isCheck = val;
}
Map<String, dynamic> toJson() {

4
lib/provider/local_auth_provider.dart

@ -4,11 +4,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../js/initial_route.dart';
import '../model/one_user_model.dart';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
void redirectToHome() {
html.window.location.href = "/one-ui/";
parentHome();
}
final localAuthProvider = Provider<OneLocalUserModel?>((ref) {

33
lib/repository/mitra_repository.dart

@ -2,6 +2,7 @@ import 'package:dio/dio.dart';
import '../app/constants.dart';
import '../model/ac_company_response_model.dart';
import '../model/ac_doctor_model.dart';
import '../model/ac_mou_response_model.dart';
import '../model/mitra_response_model.dart';
import 'base_repository.dart';
@ -24,6 +25,37 @@ class MitraRepository extends BaseRepository {
return result;
}
Future<List<AcDoctorResponseModel>> lookupDoctor({
required String query,
CancelToken? cancelToken,
}) async {
final param = {"query": query};
final service = "${Constants.baseUrl}md/lookup_doctor";
final resp = await post(
service: service, jsonParam: param, cancelToken: cancelToken);
final List<AcDoctorResponseModel> result = List.empty(growable: true);
for (final el in resp["data"]) {
final model = AcDoctorResponseModel.fromJson(el);
result.add(model);
}
return result;
}
Future<List<AcDoctorAddressResponseModel>> lookupDoctorAddress({
required String doctorID,
CancelToken? cancelToken,
}) async {
final service = "${Constants.baseUrl}md/lookup_doctoraddress/$doctorID";
final resp = await get(service: service, cancelToken: cancelToken);
final List<AcDoctorAddressResponseModel> result =
List.empty(growable: true);
for (final el in resp["data"]) {
final model = AcDoctorAddressResponseModel.fromJson(el);
result.add(model);
}
return result;
}
Future<List<AcCompanyModel>> lookupCompany({
required String query,
CancelToken? cancelToken,
@ -49,6 +81,7 @@ class MitraRepository extends BaseRepository {
final List<AcMouResponseModel> result = List.empty(growable: true);
for (final el in resp["data"]) {
final model = AcMouResponseModel.fromJson(el);
model.isCheck = false;
result.add(model);
}
return result;

0
lib/screen/home/new_screen.dart

2
lib/screen/md_lab_mitra/md_lab_mitra_screen.dart

@ -32,7 +32,7 @@ class MdLabMitraScreen extends HookConsumerWidget {
color: Colors.white,
child: const Padding(
padding: EdgeInsets.all(20.0),
child: Expanded(child: FxDataMitra()),
child: FxDataMitra(),
),
),
);

5
lib/screen/md_lab_mitra/mitra_lookup_mou_provider.dart

@ -18,6 +18,9 @@ class MitraLookupMouNotifier extends StateNotifier<MitraLookupMouState> {
MitraLookupMouNotifier({
required this.ref,
}) : super(MitraLookupMouStateInit());
void reset() {
state = MitraLookupMouStateInit();
}
void lookup({required String companyID}) async {
if (cancelToken == null) {
@ -36,7 +39,7 @@ class MitraLookupMouNotifier extends StateNotifier<MitraLookupMouState> {
if (e is BaseRepositoryException) {
state = MitraLookupMouStateError(message: e.message);
} else {
state = MitraLookupMouStateError(message: e.toString());
state = MitraLookupMouStateError(message: "Error lookupMou");
}
}
}

2
lib/screen/md_lab_mitra/mitra_search_provider.dart

@ -36,7 +36,7 @@ class MitraSearchNotifier extends StateNotifier<MitraSearchState> {
if (e is BaseRepositoryException) {
state = MitraSearchStateError(message: e.message);
} else {
state = MitraSearchStateError(message: e.toString());
state = MitraSearchStateError(message: "Error Mitra Search");
}
}
}

32
lib/screen/md_lab_mitra/timer_provider.dart

@ -0,0 +1,32 @@
// ignore_for_file: must_be_immutable
import 'dart:async';
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final timerProvider =
StateNotifierProvider.autoDispose<TimerNotifier, TimerState>(
(ref) => TimerNotifier());
class TimerNotifier extends StateNotifier<TimerState> {
TimerNotifier() : super(TimerStateInit()) {
Timer.periodic(const Duration(seconds: 5), (tmr) {
state = TimerStateTick();
});
}
}
class TimerState extends Equatable {
late DateTime dateTime;
TimerState() {
dateTime = DateTime.now();
}
@override
List<Object?> get props => [dateTime];
}
class TimerStateInit extends TimerState {}
class TimerStateTick extends TimerState {}

22
lib/widget/fx_company_lookup.dart

@ -6,8 +6,10 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../model/ac_company_response_model.dart';
import '../provider/dio_provider.dart';
import '../repository/mitra_repository.dart';
import '../screen/md_lab_mitra/selectedCompanyProvider.dart';
import '../screen/md_lab_mitra/mitra_lookup_mou_provider.dart';
import 'fx_data_mitra.dart';
import 'fx_text_field.dart';
import 'provider/selectedCompanyProvider.dart';
// ignore: must_be_immutable
class FxAcCompany extends HookConsumerWidget {
@ -25,14 +27,24 @@ class FxAcCompany extends HookConsumerWidget {
if (selectedCompany != null) {
ctrl.text = selectedCompany.mCompanyName;
}
ref.listen<AcCompanyModel?>(selectdAcCompanyProvider, ((prev, next) {
if (next != null) {
ref
.read(mitraLookupMouProvider.notifier)
.lookup(companyID: next.mCompanyID);
}
}));
return RawAutocomplete<AcCompanyModel>(
textEditingController: ctrl,
displayStringForOption: (model) => model.mCompanyName,
focusNode: fc,
fieldViewBuilder: (context, ctrl, fc, onChange) {
return TextField(
controller: ctrl,
focusNode: fc,
return FxTextField(
ctrl: ctrl,
fc: fc,
hint: "Company",
label: "Company",
);
},
optionsBuilder: (tv) async {
@ -43,7 +55,7 @@ class FxAcCompany extends HookConsumerWidget {
.lookupCompany(query: ctrl.text, cancelToken: cancelToken);
return resp;
} catch (e) {
errorMessage.value = e.toString();
errorMessage.value = "Lookup Company Error";
}
return [];
},

1
lib/widget/fx_data_mitra.dart

@ -6,7 +6,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../model/mitra_response_model.dart';
import '../screen/md_lab_mitra/mitra_search_provider.dart';
import '../screen/md_lab_mitra/selectedCompanyProvider.dart';
import 'fx_error_text.dart';
import 'fx_mitra_add_dialog.dart';

90
lib/widget/fx_doctor_address.dart

@ -0,0 +1,90 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:onemd/model/ac_doctor_model.dart';
import 'fx_data_mitra.dart';
import 'provider/doctor_address_lookup_provider.dart';
import 'provider/doctor_lookup_provider.dart';
import 'provider/selectedDoctorProvider.dart';
class FxDoctorAddress extends HookConsumerWidget {
final double? width;
const FxDoctorAddress({
Key? key,
this.width,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final listAddress =
useState<List<AcDoctorAddressResponseModel>>(List.empty());
final doctorModel = ref.watch(selectedAcDoctorProvider);
String doctorName = doctorModel?.fullName ?? "";
ref.listen(doctorAddressLookupProvider, (prev, next) {
if (next is DoctorAddressLookupStateDone) {
for (int idx = 0; idx < next.list.length; idx++) {
next.list[idx].isCheck = false;
}
listAddress.value = next.list;
}
});
return Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.blue.shade700),
color: Colors.blue.shade100.withOpacity(0.3),
),
child: ConstrainedBox(
constraints: BoxConstraints.loose(const Size(double.infinity, 150)),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FxNormalBlueText(
title: "Alamat dari $doctorName",
isBold: true,
),
const SizedBox(height: 10),
if (listAddress.value.isNotEmpty)
ConstrainedBox(
constraints:
BoxConstraints.loose(const Size(double.infinity, 100)),
child: ListView.builder(
shrinkWrap: true,
itemCount: listAddress.value.length,
itemBuilder: (context, idx) {
final model = listAddress.value[idx];
return Row(
children: [
Checkbox(
value: model.isCheck,
onChanged: ((val) {
final List<AcDoctorAddressResponseModel> list =
List.empty(growable: true);
list.addAll(listAddress.value);
list[idx].isCheck = val ?? false;
listAddress.value = list;
}),
),
const SizedBox(width: 10),
Expanded(
child: FxNormalBlueText(
title: model.mDoctorAddressDescription),
),
],
);
},
),
),
],
),
),
));
}
}

102
lib/widget/fx_doctor_lookup.dart

@ -0,0 +1,102 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:onemd/widget/provider/selectedDoctorProvider.dart';
import '../model/ac_doctor_model.dart';
import '../provider/dio_provider.dart';
import '../repository/mitra_repository.dart';
import 'fx_data_mitra.dart';
import 'fx_text_field.dart';
import 'provider/doctor_address_lookup_provider.dart';
// ignore: must_be_immutable
class FxAcDoctor extends HookConsumerWidget {
FxAcDoctor({Key? key}) : super(key: key);
CancelToken? cancelToken;
@override
Widget build(BuildContext context, WidgetRef ref) {
final errorMessage = useState("");
final ctrl = useTextEditingController(text: "");
cancelToken = CancelToken();
final fc = FocusNode();
final selectedDoctor = ref.read(selectedAcDoctorProvider);
if (selectedDoctor != null) {
ctrl.text = selectedDoctor.fullName;
}
ref.listen<AcDoctorResponseModel?>(selectedAcDoctorProvider, ((prev, next) {
if (next != null) {
print("Calling for " + next.fullName);
ref
.read(doctorAddressLookupProvider.notifier)
.lookup(doctorID: next.mDoctorID);
}
}));
return RawAutocomplete<AcDoctorResponseModel>(
textEditingController: ctrl,
displayStringForOption: (model) => model.fullName,
focusNode: fc,
fieldViewBuilder: (context, ctrl, fc, onChange) {
return FxTextField(
label: "Doctor",
hint: "Doctor",
fc: fc,
ctrl: ctrl,
);
},
optionsBuilder: (tv) async {
try {
final dio = ref.read(dioProvider);
await Future.delayed(const Duration(milliseconds: 300));
final resp = await MitraRepository(dio: dio)
.lookupDoctor(query: ctrl.text, cancelToken: cancelToken);
return resp;
} catch (e) {
errorMessage.value = "lookupDoctor Error";
}
return [];
},
optionsViewBuilder: (context, onSelect, listModel) {
return Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 400,
child: Material(
child: ListView.builder(
itemCount: listModel.length,
itemBuilder: (context, idx) {
final model = listModel.elementAt(idx);
return InkWell(
onTap: () {
ref.read(selectedAcDoctorProvider.notifier).state =
model;
onSelect(model);
},
child: Container(
color: (idx % 2 == 1)
? Colors.blue.shade100.withOpacity(0.2)
: null,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FxNormalBlueText(
title: model.fullName,
isBold: true,
),
],
),
),
));
}),
),
),
);
});
}
}

29
lib/widget/fx_mitra_add_dialog.dart

@ -1,14 +1,20 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:onemd/widget/fx_doctor_address.dart';
import 'fx_company_lookup.dart';
import 'fx_doctor_lookup.dart';
import 'fx_mitra_mou.dart';
import 'fx_text_field.dart';
class FxMitraAddDialog extends HookConsumerWidget {
const FxMitraAddDialog({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final ctrlLogin = useTextEditingController(text: "");
final fcLogin = FocusNode();
return Dialog(
shape: RoundedRectangleBorder(
side: const BorderSide(),
@ -17,6 +23,7 @@ class FxMitraAddDialog extends HookConsumerWidget {
child: SizedBox(
width: 800,
height: 600,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
@ -25,13 +32,31 @@ class FxMitraAddDialog extends HookConsumerWidget {
FxAcCompany(),
const SizedBox(height: 10),
const FxMitraMou(),
const Text("Login"),
const SizedBox(height: 10),
const Text("ID -- auto generated"),
FxAcDoctor(),
const SizedBox(height: 10),
FxDoctorAddress(),
const SizedBox(height: 10),
FxTextField(
ctrl: ctrlLogin,
fc: fcLogin,
hint: "Login",
label: "Login",
),
const SizedBox(height: 10),
FxTextField(
hint: "ID",
label: "ID",
isReadOnly: true,
isEnabled: false,
suffixText: "Auto Generated"),
const SizedBox(height: 10),
],
),
),
)),
);
}
}
useTextEditingController({required String text}) {}

52
lib/widget/fx_mitra_mou.dart

@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../model/ac_company_response_model.dart';
import '../model/ac_mou_response_model.dart';
import '../screen/md_lab_mitra/mitra_lookup_mou_provider.dart';
import '../screen/md_lab_mitra/selectedCompanyProvider.dart';
import 'fx_data_mitra.dart';
import 'provider/selectedCompanyProvider.dart';
class FxMitraMou extends HookConsumerWidget {
final double? width;
@ -19,19 +19,16 @@ class FxMitraMou extends HookConsumerWidget {
final listMou = useState<List<AcMouResponseModel>>(List.empty());
final companyModel = ref.watch(selectdAcCompanyProvider);
String companyName = companyModel?.mCompanyName ?? " -- null -- ";
if (companyModel != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ref
.read(mitraLookupMouProvider.notifier)
.lookup(companyID: companyModel.mCompanyID);
});
}
String companyName = companyModel?.mCompanyName ?? "";
ref.listen(mitraLookupMouProvider, (prev, next) {
if (next is MitraLookupMouStateDone) {
for (int idx = 0; idx < next.list.length; idx++) {
next.list[idx].isCheck = false;
}
listMou.value = next.list;
}
});
return Container(
width: double.infinity,
decoration: BoxDecoration(
@ -40,24 +37,45 @@ class FxMitraMou extends HookConsumerWidget {
color: Colors.blue.shade100.withOpacity(0.3),
),
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: 50, maxHeight: 200),
constraints: BoxConstraints.loose(const Size(double.infinity, 150)),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Agreement " + companyName,
FxNormalBlueText(
title: "Agreement $companyName",
isBold: true,
),
SizedBox(height: 10),
if (listMou.value.length > 0)
Expanded(
const SizedBox(height: 10),
if (listMou.value.isNotEmpty)
ConstrainedBox(
constraints:
BoxConstraints.loose(const Size(double.infinity, 100)),
child: ListView.builder(
shrinkWrap: true,
itemCount: listMou.value.length,
itemBuilder: (context, idx) {
final model = listMou.value[idx];
return Text(model.mMouName);
return Row(
children: [
Checkbox(
value: model.isCheck,
onChanged: ((val) {
final List<AcMouResponseModel> list =
List.empty(growable: true);
list.addAll(listMou.value);
list[idx].isCheck = val ?? false;
listMou.value = list;
}),
),
const SizedBox(width: 10),
Expanded(
child: FxNormalBlueText(title: model.mMouName),
),
],
);
}),
),
]),

46
lib/widget/fx_text_field.dart

@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
class FxTextField extends StatelessWidget {
final TextEditingController? ctrl;
final FocusNode? fc;
final String label;
final String hint;
final String? errorMessage;
final bool? isReadOnly;
final bool? isEnabled;
final String? suffixText;
const FxTextField({
Key? key,
this.ctrl,
this.fc,
required this.label,
required this.hint,
this.errorMessage,
this.isReadOnly,
this.isEnabled,
this.suffixText,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
hintText: hint,
labelText: label,
errorText: errorMessage,
suffixIcon: Padding(
padding: const EdgeInsets.only(right: 10.0, top: 10.0),
child: Text(suffixText ?? ""),
),
),
controller: ctrl,
focusNode: fc,
readOnly: isReadOnly ?? false,
enabled: isEnabled ?? true,
);
}
}

74
lib/widget/provider/doctor_address_lookup_provider.dart

@ -0,0 +1,74 @@
import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../model/ac_doctor_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/mitra_repository.dart';
final doctorAddressLookupProvider = StateNotifierProvider<
DoctorAddressLookupNotifier, DoctorAddressLookupState>(
(ref) => DoctorAddressLookupNotifier(ref: ref),
);
class DoctorAddressLookupNotifier
extends StateNotifier<DoctorAddressLookupState> {
final Ref ref;
CancelToken? cancelToken;
DoctorAddressLookupNotifier({
required this.ref,
}) : super(DoctorAddressLookupStateInit());
void reset() {
state = DoctorAddressLookupStateInit();
}
void lookup({required String doctorID}) async {
if (cancelToken == null) {
cancelToken = CancelToken();
} else {
cancelToken!.cancel();
cancelToken = CancelToken();
}
try {
state = DoctorAddressLookupStateLoading();
final dio = ref.read(dioProvider);
final resp = await MitraRepository(dio: dio)
.lookupDoctorAddress(doctorID: doctorID, cancelToken: cancelToken);
state = DoctorAddressLookupStateDone(list: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = DoctorAddressLookupStateError(message: e.message);
} else {
state = DoctorAddressLookupStateError(message: "Unknown Error");
}
}
}
}
abstract class DoctorAddressLookupState extends Equatable {
final DateTime date;
DoctorAddressLookupState() : date = DateTime.now();
@override
List<Object?> get props => throw [date];
}
class DoctorAddressLookupStateInit extends DoctorAddressLookupState {}
class DoctorAddressLookupStateLoading extends DoctorAddressLookupState {}
class DoctorAddressLookupStateError extends DoctorAddressLookupState {
final String message;
DoctorAddressLookupStateError({
required this.message,
});
}
class DoctorAddressLookupStateDone extends DoctorAddressLookupState {
final List<AcDoctorAddressResponseModel> list;
DoctorAddressLookupStateDone({
required this.list,
});
}

73
lib/widget/provider/doctor_lookup_provider.dart

@ -0,0 +1,73 @@
import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../model/ac_doctor_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/mitra_repository.dart';
final doctorLookupProvider =
StateNotifierProvider<DoctorLookupNotifier, DoctorLookupState>(
(ref) => DoctorLookupNotifier(ref: ref),
);
class DoctorLookupNotifier extends StateNotifier<DoctorLookupState> {
final Ref ref;
CancelToken? cancelToken;
DoctorLookupNotifier({
required this.ref,
}) : super(DoctorLookupStateInit());
void reset() {
state = DoctorLookupStateInit();
}
void lookup({required String query}) async {
if (cancelToken == null) {
cancelToken = CancelToken();
} else {
cancelToken!.cancel();
cancelToken = CancelToken();
}
try {
state = DoctorLookupStateLoading();
final dio = ref.read(dioProvider);
final resp = await MitraRepository(dio: dio)
.lookupDoctor(query: query, cancelToken: cancelToken);
state = DoctorLookupStateDone(list: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = DoctorLookupStateError(message: e.message);
} else {
state = DoctorLookupStateError(message: "Unknown Error ");
}
}
}
}
abstract class DoctorLookupState extends Equatable {
final DateTime date;
DoctorLookupState() : date = DateTime.now();
@override
List<Object?> get props => throw [date];
}
class DoctorLookupStateInit extends DoctorLookupState {}
class DoctorLookupStateLoading extends DoctorLookupState {}
class DoctorLookupStateError extends DoctorLookupState {
final String message;
DoctorLookupStateError({
required this.message,
});
}
class DoctorLookupStateDone extends DoctorLookupState {
final List<AcDoctorResponseModel> list;
DoctorLookupStateDone({
required this.list,
});
}

0
lib/screen/md_lab_mitra/selectedCompanyProvider.dart → lib/widget/provider/selectedCompanyProvider.dart

5
lib/widget/provider/selectedDoctorProvider.dart

@ -0,0 +1,5 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:onemd/model/ac_doctor_model.dart';
final selectedAcDoctorProvider =
StateProvider<AcDoctorResponseModel?>((ref) => null);

37
php-api/mitra/Md.php

@ -68,6 +68,43 @@ class Md extends MY_Controller
}
echo json_encode(["status" => "OK", "data" => $qry->result_array()]);
}
function lookup_doctor()
{
$param = $this->sys_input;
$sql = "select M_DoctorID, fn_get_doctor_fullname(M_DoctorID) FullName
from m_doctor
where M_DoctorName like ?
and M_DoctorIsActive = 'Y'
limit 0,50";
$qry = $this->db->query($sql, ["%" . $param["query"] . "%"]);
if (!$qry) {
echo json_encode([
"status" => "ERR",
"message" => $this->db->error()["message"],
]);
exit();
}
echo json_encode(["status" => "OK", "data" => $qry->result_array()]);
}
function lookup_doctoraddress($doctorID)
{
$param = $this->sys_input;
$sql = "select M_DoctorAddressID,M_DoctorAddressDescription
from m_doctoraddress
where M_DoctorAddressM_DoctorID = ?
and M_DoctorAddressIsActive = 'Y'
limit 0,50";
$qry = $this->db->query($sql, [$doctorID]);
if (!$qry) {
echo json_encode([
"status" => "ERR",
"message" => $this->db->error()["message"],
]);
exit();
}
echo json_encode(["status" => "OK", "data" => $qry->result_array()]);
}
function lookup_company()
{
$param = $this->sys_input;

18
web/index.html

@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
@ -49,17 +50,15 @@
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<body>
</head>
<body>
<script>
window.addEventListener("load", function (ev) {
// Download main.dart.js
_flutter.loader
.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
})
.loadEntrypoint()
.then(function (engineInitializer) {
return engineInitializer.initializeEngine();
})
@ -68,5 +67,6 @@
});
});
</script>
</body>
</body>
</html>

14
web/md_mitra_lab.html

@ -1,6 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mitra Lab MasterData</title>
@ -8,9 +9,14 @@
function fx_initial_route() {
return "/mdLabMitra";
}
function parent_home() {
parent.window.location.href = "/one-ui/";
}
</script>
</head>
<body>
</head>
<body>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</body>
</html>

Loading…
Cancel
Save