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. 51
      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. 181
      php-api/mitra/Md.php
  24. 104
      web/index.html
  25. 32
      web/md_mitra_lab.html

10
README.md

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

3
lib/js/initial_route.dart

@ -5,6 +5,9 @@ import 'dart:html' as html;
@JS('fx_initial_route') @JS('fx_initial_route')
external String fxInitialRoute(); external String fxInitialRoute();
@JS('parent_home')
external String parentHome();
String? getToken() { String? getToken() {
return html.window.localStorage['token']; 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 mMouNote;
late String mMouNumber; late String mMouNumber;
late String mMouStartDate; late String mMouStartDate;
late bool isCheck;
AcMouResponseModel({ AcMouResponseModel({
required this.mMouEndDate, required this.mMouEndDate,
required this.mMouID, required this.mMouID,
@ -17,6 +17,7 @@ class AcMouResponseModel {
required this.mMouNote, required this.mMouNote,
required this.mMouNumber, required this.mMouNumber,
required this.mMouStartDate, required this.mMouStartDate,
this.isCheck = false,
}); });
AcMouResponseModel.fromJson(Map<String, dynamic> json) { AcMouResponseModel.fromJson(Map<String, dynamic> json) {
@ -28,6 +29,10 @@ class AcMouResponseModel {
mMouNote = json['M_MouNote'] ?? ""; mMouNote = json['M_MouNote'] ?? "";
mMouNumber = json['M_MouNumber'] ?? ""; mMouNumber = json['M_MouNumber'] ?? "";
mMouStartDate = json['M_MouStartDate'] ?? ""; mMouStartDate = json['M_MouStartDate'] ?? "";
isCheck = false;
}
void setCheck(bool val) {
isCheck = val;
} }
Map<String, dynamic> toJson() { 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 '../js/initial_route.dart';
import '../model/one_user_model.dart'; import '../model/one_user_model.dart';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
void redirectToHome() { void redirectToHome() {
html.window.location.href = "/one-ui/"; parentHome();
} }
final localAuthProvider = Provider<OneLocalUserModel?>((ref) { 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 '../app/constants.dart';
import '../model/ac_company_response_model.dart'; import '../model/ac_company_response_model.dart';
import '../model/ac_doctor_model.dart';
import '../model/ac_mou_response_model.dart'; import '../model/ac_mou_response_model.dart';
import '../model/mitra_response_model.dart'; import '../model/mitra_response_model.dart';
import 'base_repository.dart'; import 'base_repository.dart';
@ -24,6 +25,37 @@ class MitraRepository extends BaseRepository {
return result; 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({ Future<List<AcCompanyModel>> lookupCompany({
required String query, required String query,
CancelToken? cancelToken, CancelToken? cancelToken,
@ -49,6 +81,7 @@ class MitraRepository extends BaseRepository {
final List<AcMouResponseModel> result = List.empty(growable: true); final List<AcMouResponseModel> result = List.empty(growable: true);
for (final el in resp["data"]) { for (final el in resp["data"]) {
final model = AcMouResponseModel.fromJson(el); final model = AcMouResponseModel.fromJson(el);
model.isCheck = false;
result.add(model); result.add(model);
} }
return result; 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, color: Colors.white,
child: const Padding( child: const Padding(
padding: EdgeInsets.all(20.0), 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({ MitraLookupMouNotifier({
required this.ref, required this.ref,
}) : super(MitraLookupMouStateInit()); }) : super(MitraLookupMouStateInit());
void reset() {
state = MitraLookupMouStateInit();
}
void lookup({required String companyID}) async { void lookup({required String companyID}) async {
if (cancelToken == null) { if (cancelToken == null) {
@ -36,7 +39,7 @@ class MitraLookupMouNotifier extends StateNotifier<MitraLookupMouState> {
if (e is BaseRepositoryException) { if (e is BaseRepositoryException) {
state = MitraLookupMouStateError(message: e.message); state = MitraLookupMouStateError(message: e.message);
} else { } 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) { if (e is BaseRepositoryException) {
state = MitraSearchStateError(message: e.message); state = MitraSearchStateError(message: e.message);
} else { } 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 '../model/ac_company_response_model.dart';
import '../provider/dio_provider.dart'; import '../provider/dio_provider.dart';
import '../repository/mitra_repository.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_data_mitra.dart';
import 'fx_text_field.dart';
import 'provider/selectedCompanyProvider.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class FxAcCompany extends HookConsumerWidget { class FxAcCompany extends HookConsumerWidget {
@ -25,14 +27,24 @@ class FxAcCompany extends HookConsumerWidget {
if (selectedCompany != null) { if (selectedCompany != null) {
ctrl.text = selectedCompany.mCompanyName; ctrl.text = selectedCompany.mCompanyName;
} }
ref.listen<AcCompanyModel?>(selectdAcCompanyProvider, ((prev, next) {
if (next != null) {
ref
.read(mitraLookupMouProvider.notifier)
.lookup(companyID: next.mCompanyID);
}
}));
return RawAutocomplete<AcCompanyModel>( return RawAutocomplete<AcCompanyModel>(
textEditingController: ctrl, textEditingController: ctrl,
displayStringForOption: (model) => model.mCompanyName, displayStringForOption: (model) => model.mCompanyName,
focusNode: fc, focusNode: fc,
fieldViewBuilder: (context, ctrl, fc, onChange) { fieldViewBuilder: (context, ctrl, fc, onChange) {
return TextField( return FxTextField(
controller: ctrl, ctrl: ctrl,
focusNode: fc, fc: fc,
hint: "Company",
label: "Company",
); );
}, },
optionsBuilder: (tv) async { optionsBuilder: (tv) async {
@ -43,7 +55,7 @@ class FxAcCompany extends HookConsumerWidget {
.lookupCompany(query: ctrl.text, cancelToken: cancelToken); .lookupCompany(query: ctrl.text, cancelToken: cancelToken);
return resp; return resp;
} catch (e) { } catch (e) {
errorMessage.value = e.toString(); errorMessage.value = "Lookup Company Error";
} }
return []; 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 '../model/mitra_response_model.dart';
import '../screen/md_lab_mitra/mitra_search_provider.dart'; import '../screen/md_lab_mitra/mitra_search_provider.dart';
import '../screen/md_lab_mitra/selectedCompanyProvider.dart';
import 'fx_error_text.dart'; import 'fx_error_text.dart';
import 'fx_mitra_add_dialog.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,
),
],
),
),
));
}),
),
),
);
});
}
}

51
lib/widget/fx_mitra_add_dialog.dart

@ -1,14 +1,20 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:onemd/widget/fx_doctor_address.dart';
import 'fx_company_lookup.dart'; import 'fx_company_lookup.dart';
import 'fx_doctor_lookup.dart';
import 'fx_mitra_mou.dart'; import 'fx_mitra_mou.dart';
import 'fx_text_field.dart';
class FxMitraAddDialog extends HookConsumerWidget { class FxMitraAddDialog extends HookConsumerWidget {
const FxMitraAddDialog({Key? key}) : super(key: key); const FxMitraAddDialog({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final ctrlLogin = useTextEditingController(text: "");
final fcLogin = FocusNode();
return Dialog( return Dialog(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
side: const BorderSide(), side: const BorderSide(),
@ -17,21 +23,40 @@ class FxMitraAddDialog extends HookConsumerWidget {
child: SizedBox( child: SizedBox(
width: 800, width: 800,
height: 600, height: 600,
child: Padding( child: SingleChildScrollView(
padding: const EdgeInsets.all(20.0), child: Padding(
child: Column( padding: const EdgeInsets.all(20.0),
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
FxAcCompany(), children: [
const SizedBox(height: 10), FxAcCompany(),
const FxMitraMou(), const SizedBox(height: 10),
const Text("Login"), const FxMitraMou(),
const SizedBox(height: 10), const SizedBox(height: 10),
const Text("ID -- auto generated"), FxAcDoctor(),
const SizedBox(height: 10), 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:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../model/ac_company_response_model.dart';
import '../model/ac_mou_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/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 { class FxMitraMou extends HookConsumerWidget {
final double? width; final double? width;
@ -19,19 +19,16 @@ class FxMitraMou extends HookConsumerWidget {
final listMou = useState<List<AcMouResponseModel>>(List.empty()); final listMou = useState<List<AcMouResponseModel>>(List.empty());
final companyModel = ref.watch(selectdAcCompanyProvider); final companyModel = ref.watch(selectdAcCompanyProvider);
String companyName = companyModel?.mCompanyName ?? " -- null -- "; String companyName = companyModel?.mCompanyName ?? "";
if (companyModel != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ref
.read(mitraLookupMouProvider.notifier)
.lookup(companyID: companyModel.mCompanyID);
});
}
ref.listen(mitraLookupMouProvider, (prev, next) { ref.listen(mitraLookupMouProvider, (prev, next) {
if (next is MitraLookupMouStateDone) { if (next is MitraLookupMouStateDone) {
for (int idx = 0; idx < next.list.length; idx++) {
next.list[idx].isCheck = false;
}
listMou.value = next.list; listMou.value = next.list;
} }
}); });
return Container( return Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -40,24 +37,45 @@ class FxMitraMou extends HookConsumerWidget {
color: Colors.blue.shade100.withOpacity(0.3), color: Colors.blue.shade100.withOpacity(0.3),
), ),
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints(minHeight: 50, maxHeight: 200), constraints: BoxConstraints.loose(const Size(double.infinity, 150)),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( FxNormalBlueText(
"Agreement " + companyName, title: "Agreement $companyName",
isBold: true,
), ),
SizedBox(height: 10), const SizedBox(height: 10),
if (listMou.value.length > 0) if (listMou.value.isNotEmpty)
Expanded( ConstrainedBox(
constraints:
BoxConstraints.loose(const Size(double.infinity, 100)),
child: ListView.builder( child: ListView.builder(
shrinkWrap: true,
itemCount: listMou.value.length, itemCount: listMou.value.length,
itemBuilder: (context, idx) { itemBuilder: (context, idx) {
final model = listMou.value[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);

181
php-api/mitra/Md.php

@ -4,45 +4,45 @@ ini_set("display_startup_errors", 1);
error_reporting(E_ALL); error_reporting(E_ALL);
class Md extends MY_Controller class Md extends MY_Controller
{ {
function __construct() function __construct()
{ {
parent::__construct(); parent::__construct();
} }
function index() function index()
{ {
echo "Mitra:MD:API"; echo "Mitra:MD:API";
} }
function add() function add()
{ {
$param = $this->sys_input; $param = $this->sys_input;
print_r($param); print_r($param);
} }
function corss() function corss()
{ {
global $_SERVER; global $_SERVER;
if (isset($_SERVER["HTTP_ORIGIN"])) { if (isset($_SERVER["HTTP_ORIGIN"])) {
header("Access-Control-Allow-Origin:" . $_SERVER["HTTP_ORIGIN"]); header("Access-Control-Allow-Origin:" . $_SERVER["HTTP_ORIGIN"]);
} else { } else {
header("Access-Control-Allow-Origin: */*"); header("Access-Control-Allow-Origin: */*");
}
header("Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS");
header(
"Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
if (
isset($_SERVER["REQUEST_METHOD"]) &&
$_SERVER["REQUEST_METHOD"] == "OPTIONS"
) {
http_response_code(200);
echo json_encode("OK");
exit();
}
} }
function search() header("Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS");
{ header(
$this->corss(); "Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization"
$sql = "select mitra.*, );
if (
isset($_SERVER["REQUEST_METHOD"]) &&
$_SERVER["REQUEST_METHOD"] == "OPTIONS"
) {
http_response_code(200);
echo json_encode("OK");
exit();
}
}
function search()
{
$this->corss();
$sql = "select mitra.*,
M_CompanyName, M_CompanyAddress, M_CompanyName, M_CompanyAddress,
group_concat(concat(M_MouName,' [', date_format(M_MouEndDate,'%d/%m/%Y'),'] ') separator '^') aggrement group_concat(concat(M_MouName,' [', date_format(M_MouEndDate,'%d/%m/%Y'),'] ') separator '^') aggrement
from mitra from mitra
@ -57,51 +57,88 @@ class Md extends MY_Controller
and MitraMouIsActive ='Y' and MitraMouIsActive ='Y'
join m_mou on MitraMouM_MouID = M_MouID join m_mou on MitraMouM_MouID = M_MouID
group by MitraID "; group by MitraID ";
$query = "%" . $this->sys_input["query"] . "%"; $query = "%" . $this->sys_input["query"] . "%";
$qry = $this->db->query($sql, [$query, $query]); $qry = $this->db->query($sql, [$query, $query]);
if (!$qry) { if (!$qry) {
echo json_encode([ echo json_encode([
"status" => "ERR", "status" => "ERR",
"message" => $this->db->error()["message"], "message" => $this->db->error()["message"],
]); ]);
exit(); exit();
} }
echo json_encode(["status" => "OK", "data" => $qry->result_array()]); 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();
} }
function lookup_company() echo json_encode(["status" => "OK", "data" => $qry->result_array()]);
{ }
$param = $this->sys_input; function lookup_company()
$sql = "select * from m_company {
$param = $this->sys_input;
$sql = "select * from m_company
where M_CompanyName like ? where M_CompanyName like ?
and M_CompanyIsActive = 'Y' and M_CompanyIsActive = 'Y'
limit 0,50"; limit 0,50";
$qry = $this->db->query($sql, ["%" . $param["query"] . "%"]); $qry = $this->db->query($sql, ["%" . $param["query"] . "%"]);
if (!$qry) { if (!$qry) {
echo json_encode([ echo json_encode([
"status" => "ERR", "status" => "ERR",
"message" => $this->db->error()["message"], "message" => $this->db->error()["message"],
]); ]);
exit(); exit();
}
echo json_encode(["status" => "OK", "data" => $qry->result_array()]);
} }
function lookup_mou($companyID) echo json_encode(["status" => "OK", "data" => $qry->result_array()]);
{ }
$sql = "select function lookup_mou($companyID)
{
$sql = "select
* from m_mou * from m_mou
where M_MouM_CompanyID = ? where M_MouM_CompanyID = ?
and M_MouIsReleased = 'Y' and M_MouIsReleased = 'Y'
and M_MouIsActive ='Y'"; and M_MouIsActive ='Y'";
$qry = $this->db->query($sql, [$companyID]); $qry = $this->db->query($sql, [$companyID]);
if (!$qry) { if (!$qry) {
echo json_encode([ echo json_encode([
"status" => "ERR", "status" => "ERR",
"message" => $this->db->error()["message"], "message" => $this->db->error()["message"],
]); ]);
exit(); exit();
}
echo json_encode(["status" => "OK", "data" => $qry->result_array()]);
} }
echo json_encode(["status" => "OK", "data" => $qry->result_array()]);
}
} }
/* /*
drop table if exists mitra; drop table if exists mitra;

104
web/index.html

@ -1,7 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<!-- <head>
<!--
If you are serving your web app in a path other than the root, change the 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. href value below to reflect the base path you are serving from.
@ -14,59 +15,58 @@
This is a placeholder for base href that will be replaced by the value of This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`. the `--base-href` argument provided to `flutter build`.
--> -->
<base href="$FLUTTER_BASE_HREF" /> <base href="$FLUTTER_BASE_HREF" />
<meta charset="UTF-8" />
<meta content="IE=Edge" http-equiv="X-UA-Compatible" />
<meta name="description" content="A new Flutter project." />
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="onemd" />
<link rel="apple-touch-icon" href="icons/Icon-192.png" />
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png" />
<meta charset="UTF-8" /> <title>onemd</title>
<meta content="IE=Edge" http-equiv="X-UA-Compatible" /> <link rel="manifest" href="manifest.json" />
<meta name="description" content="A new Flutter project." />
<!-- iOS meta tags & icons --> <script>
<meta name="apple-mobile-web-app-capable" content="yes" /> // The value below is injected by flutter build, do not touch.
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> var serviceWorkerVersion = null;
<meta name="apple-mobile-web-app-title" content="onemd" /> function fx_initial_route() {
<link rel="apple-touch-icon" href="icons/Icon-192.png" /> return "/mdLabMitra";
}
localStorage.setItem(
"token",
`eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJNX1VzZXJJRCI6IjM0MCIsIk1fVXNlclVzZXJuYW1lIjoiYWRtaW5zYXMgIiwiTV9Vc2VyR3JvdXBEYXNoYm9hcmQiOiJvbmUtdWlcL3Rlc3RcL3Z1ZXhcL29uZS1mby1yZWdpc3RyYXRpb24tdjEyIiwiTV9Vc2VyRGVmYXVsdFRfU2FtcGxlU3RhdGlvbklEIjoiMCIsIk1fU3RhZmZOYW1lIjoiQURNSU4iLCJpc19jb3VyaWVyIjoiTiIsImlwIjoiMTgyLjI1My4xOTQuNCIsImFnZW50IjoiTW96aWxsYVwvNS4wIChYMTE7IExpbnV4IHg4Nl82NCkgQXBwbGVXZWJLaXRcLzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZVwvMTAxLjAuNDk1MS42NCBTYWZhcmlcLzUzNy4zNiIsInZlcnNpb24iOiJ2MiIsImxhc3QtbG9naW4iOiIyMDIyLTA1LTIzIDE0OjA2OjQ5IiwiTV9TYXRlbGxpdGVJRCI6MH0.amPh-paITGRM2Kb1c0LciDsWd_OdC0jN2WN5ugN-gvI`
);
localStorage.setItem(
"user",
`{"M_UserID":"340","M_UserUsername":"adminsas ","M_UserGroupDashboard":"one-ui/test/vuex/one-fo-registration-v12","M_UserDefaultT_SampleStationID":"0","M_StaffName":"ADMIN","is_courier":"N","ip":"182.253.194.4","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36","version":"v2","last-login":"2022-05-23 14:06:49","M_SatelliteID":0}`
);
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<!-- Favicon --> <body>
<link rel="icon" type="image/png" href="favicon.png" /> <script>
window.addEventListener("load", function (ev) {
<title>onemd</title> // Download main.dart.js
<link rel="manifest" href="manifest.json" /> _flutter.loader
.loadEntrypoint()
.then(function (engineInitializer) {
return engineInitializer.initializeEngine();
})
.then(function (appRunner) {
return appRunner.runApp();
});
});
</script>
</body>
<script>
// The value below is injected by flutter build, do not touch.
var serviceWorkerVersion = null;
function fx_initial_route() {
return "/mdLabMitra";
}
localStorage.setItem(
"token",
`eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJNX1VzZXJJRCI6IjM0MCIsIk1fVXNlclVzZXJuYW1lIjoiYWRtaW5zYXMgIiwiTV9Vc2VyR3JvdXBEYXNoYm9hcmQiOiJvbmUtdWlcL3Rlc3RcL3Z1ZXhcL29uZS1mby1yZWdpc3RyYXRpb24tdjEyIiwiTV9Vc2VyRGVmYXVsdFRfU2FtcGxlU3RhdGlvbklEIjoiMCIsIk1fU3RhZmZOYW1lIjoiQURNSU4iLCJpc19jb3VyaWVyIjoiTiIsImlwIjoiMTgyLjI1My4xOTQuNCIsImFnZW50IjoiTW96aWxsYVwvNS4wIChYMTE7IExpbnV4IHg4Nl82NCkgQXBwbGVXZWJLaXRcLzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZVwvMTAxLjAuNDk1MS42NCBTYWZhcmlcLzUzNy4zNiIsInZlcnNpb24iOiJ2MiIsImxhc3QtbG9naW4iOiIyMDIyLTA1LTIzIDE0OjA2OjQ5IiwiTV9TYXRlbGxpdGVJRCI6MH0.amPh-paITGRM2Kb1c0LciDsWd_OdC0jN2WN5ugN-gvI`
);
localStorage.setItem(
"user",
`{"M_UserID":"340","M_UserUsername":"adminsas ","M_UserGroupDashboard":"one-ui/test/vuex/one-fo-registration-v12","M_UserDefaultT_SampleStationID":"0","M_StaffName":"ADMIN","is_courier":"N","ip":"182.253.194.4","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36","version":"v2","last-login":"2022-05-23 14:06:49","M_SatelliteID":0}`
);
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<body>
<script>
window.addEventListener("load", function (ev) {
// Download main.dart.js
_flutter.loader
.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
})
.then(function (engineInitializer) {
return engineInitializer.initializeEngine();
})
.then(function (appRunner) {
return appRunner.runApp();
});
});
</script>
</body>
</html> </html>

32
web/md_mitra_lab.html

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

Loading…
Cancel
Save