Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
C
Crm Attendance
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dio Maulana
Crm Attendance
Commits
77a3594d
Commit
77a3594d
authored
Jun 07, 2023
by
Dio Maulana
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jagain absen masuk keluar di frontend
parent
6ae1e7c8
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1128 additions
and
488 deletions
+1128
-488
api.dart
lib/api/api.dart
+3
-0
modal_dialog.dart
lib/helper/modal_dialog.dart
+96
-0
profile.dart
lib/models/profile.dart
+25
-0
absent_camera.dart
lib/page/absent_camera/absent_camera.dart
+770
-322
home.dart
lib/page/home/home.dart
+60
-2
onboarding.dart
lib/page/onboarding/onboarding.dart
+164
-161
strings.dart
lib/resource/strings.dart
+5
-0
pubspec.lock
pubspec.lock
+2
-2
pubspec.yaml
pubspec.yaml
+2
-0
index.html
web/index.html
+1
-1
No files found.
lib/api/api.dart
View file @
77a3594d
...
@@ -5,6 +5,7 @@ import 'package:excelso_attendance/helper/pref.dart';
...
@@ -5,6 +5,7 @@ import 'package:excelso_attendance/helper/pref.dart';
import
'package:excelso_attendance/main.dart'
;
import
'package:excelso_attendance/main.dart'
;
import
'package:excelso_attendance/models/absent.dart'
;
import
'package:excelso_attendance/models/absent.dart'
;
import
'package:excelso_attendance/models/branch.dart'
;
import
'package:excelso_attendance/models/branch.dart'
;
import
'package:excelso_attendance/models/profile.dart'
;
import
'package:excelso_attendance/models/shift.dart'
;
import
'package:excelso_attendance/models/shift.dart'
;
import
'package:excelso_attendance/resource/strings.dart'
;
import
'package:excelso_attendance/resource/strings.dart'
;
import
'package:http/http.dart'
as
http
;
import
'package:http/http.dart'
as
http
;
...
@@ -113,9 +114,11 @@ class Api {
...
@@ -113,9 +114,11 @@ class Api {
return
ApiResponse
(
error:
true
,
msg:
Strings
.
cantConnectToServer
);
return
ApiResponse
(
error:
true
,
msg:
Strings
.
cantConnectToServer
);
}
else
{
}
else
{
if
(
jsonObject
[
'status'
]
==
"ok"
)
{
if
(
jsonObject
[
'status'
]
==
"ok"
)
{
Map
<
String
,
dynamic
>
user
=
jsonObject
[
'data'
][
'user'
];
return
ApiResponse
(
return
ApiResponse
(
error:
false
,
error:
false
,
msg:
Strings
.
succesGetData
,
msg:
Strings
.
succesGetData
,
data:
ProfileModel
.
json
(
user
),
);
);
}
else
{
}
else
{
return
ApiResponse
(
return
ApiResponse
(
...
...
lib/helper/modal_dialog.dart
0 → 100644
View file @
77a3594d
import
'package:excelso_attendance/helper/component/button.dart'
;
import
'package:excelso_attendance/resource/font.dart'
;
import
'package:excelso_attendance/resource/style.dart'
;
import
'package:flutter/material.dart'
;
Future
<
dynamic
>
modalDialogGlobal
({
required
BuildContext
context
,
required
Size
size
,
required
String
title
,
required
String
contentBody
,
required
String
buttonText
,
required
void
Function
()
tapButton
,
bool
isActiveCancelButton
=
false
,
bool
isCustomSecondButton
=
false
,
String
customSecondButtonText
=
''
,
Widget
?
navigateToCustomButton
,
})
async
{
return
showDialog
(
context:
context
,
barrierDismissible:
false
,
builder:
(
BuildContext
ctxDialog
)
=>
AlertDialog
(
shape:
const
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
15
))),
content:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
title
,
style:
getBoldStyle
(
color:
Colors
.
black
,
fontFamily:
FontConstants
.
montserrat
,
fontSize:
FontSize
.
s24
,
),
),
const
SizedBox
(
height:
16
,
),
Text
(
contentBody
,
style:
getMediumStyle
(
color:
Colors
.
black
,
fontFamily:
FontConstants
.
openSans
,
fontSize:
FontSize
.
s16
,
),
),
const
SizedBox
(
height:
42
,
),
InkWell
(
onTap:
()
{
tapButton
();
},
child:
CustomButton
(
text:
buttonText
,
),
),
(
isActiveCancelButton
)
?
InkWell
(
onTap:
()
{
Navigator
.
pop
(
context
);
},
child:
const
CustomButton
(
text:
"Cancel"
,
colorButton:
Colors
.
transparent
,
colorText:
Colors
.
black
,
),
)
:
const
SizedBox
(),
(
isCustomSecondButton
)
?
Column
(
children:
[
const
SizedBox
(
height:
10
,
),
InkWell
(
onTap:
()
{
Navigator
.
pop
(
context
);
Navigator
.
push
(
context
,
MaterialPageRoute
(
builder:
(
_
)
=>
navigateToCustomButton
!),
);
},
child:
CustomButton
(
text:
customSecondButtonText
,
),
),
],
)
:
const
SizedBox
()
],
),
),
);
}
lib/models/profile.dart
0 → 100644
View file @
77a3594d
class
ProfileModel
{
String
id
;
String
brand
;
String
name
;
bool
attendanceIn
;
bool
attendanceOut
;
ProfileModel
({
required
this
.
id
,
required
this
.
brand
,
required
this
.
name
,
required
this
.
attendanceIn
,
required
this
.
attendanceOut
,
});
factory
ProfileModel
.
json
(
Map
<
String
,
dynamic
>
json
)
{
return
ProfileModel
(
id:
json
[
'id'
],
brand:
json
[
'brand'
],
name:
json
[
'name'
],
attendanceIn:
json
[
'today_attendance_in'
],
attendanceOut:
json
[
'today_attendance_out'
],
);
}
}
lib/page/absent_camera/absent_camera.dart
View file @
77a3594d
...
@@ -6,6 +6,7 @@ import 'dart:io';
...
@@ -6,6 +6,7 @@ import 'dart:io';
import
'package:excelso_attendance/api/api.dart'
;
import
'package:excelso_attendance/api/api.dart'
;
import
'package:excelso_attendance/helper/arguments/error_args.dart'
;
import
'package:excelso_attendance/helper/arguments/error_args.dart'
;
import
'package:excelso_attendance/helper/arguments/route_args.dart'
;
import
'package:excelso_attendance/helper/arguments/route_args.dart'
;
import
'package:excelso_attendance/helper/modal_dialog.dart'
;
import
'package:excelso_attendance/helper/widget_responsive.dart'
;
import
'package:excelso_attendance/helper/widget_responsive.dart'
;
import
'package:excelso_attendance/main.dart'
;
import
'package:excelso_attendance/main.dart'
;
import
'package:excelso_attendance/models/absent.dart'
;
import
'package:excelso_attendance/models/absent.dart'
;
...
@@ -26,6 +27,7 @@ import 'package:excelso_attendance/resource/size.dart';
...
@@ -26,6 +27,7 @@ import 'package:excelso_attendance/resource/size.dart';
import
'package:excelso_attendance/resource/style.dart'
;
import
'package:excelso_attendance/resource/style.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_easyloading/flutter_easyloading.dart'
;
import
'package:flutter_easyloading/flutter_easyloading.dart'
;
// import 'package:quiver/async.dart';
class
AbsentCameraView
extends
StatefulWidget
{
class
AbsentCameraView
extends
StatefulWidget
{
const
AbsentCameraView
({
const
AbsentCameraView
({
...
@@ -62,6 +64,8 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
...
@@ -62,6 +64,8 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
// bool isPermissionAccept = true;
// bool isPermissionAccept = true;
// String? errorCamera;
// String? errorCamera;
bool
isCameraLoading
=
true
;
@override
@override
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
...
@@ -82,6 +86,10 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
...
@@ -82,6 +86,10 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
void
initStateFunc
()
{
void
initStateFunc
()
{
getCameraDescrption
().
then
((
value
)
{
getCameraDescrption
().
then
((
value
)
{
cameras
=
value
;
cameras
=
value
;
if
(
debug
)
{
// ignore: avoid_print
print
(
"JUMLAH CAMERA TEDETEKSI:
${cameras!.length}
"
);
}
if
(
cameras
!.
length
>
1
)
{
if
(
cameras
!.
length
>
1
)
{
_cameraDescription
=
cameras
![
1
];
_cameraDescription
=
cameras
![
1
];
}
else
{
}
else
{
...
@@ -100,12 +108,76 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
...
@@ -100,12 +108,76 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
// Define the resolution to use.
// Define the resolution to use.
ResolutionPreset
.
medium
,
ResolutionPreset
.
medium
,
imageFormatGroup:
ImageFormatGroup
.
jpeg
,
imageFormatGroup:
ImageFormatGroup
.
jpeg
,
enableAudio:
false
,
);
initCamera
(
_controller
!);
}
}).
catchError
((
e
)
{
if
(
e
is
CameraException
)
{
switch
(
e
.
code
)
{
case
'CameraAccessDenied'
:
// setState(() {
// isPermissionAccept = false;
// });
Navigator
.
pushNamedAndRemoveUntil
(
context
,
Routes
.
errorWidget
,
(
route
)
=>
false
,
arguments:
ErrorWidgetArguments
(
errorMessage:
Strings
.
cameraNotActive
,
),
);
default
:
// setState(() {
// errorCamera = "$e";
// });
// Navigator.pushNamedAndRemoveUntil(
// context,
// Routes.errorWidget,
// (route) => false,
// arguments: ErrorWidgetArguments(
// errorMessage: "ERROR: $e",
// ),
// );
modalDialogGlobal
(
context:
context
,
size:
MediaQuery
.
of
(
context
).
size
,
title:
"Error"
,
contentBody:
"
$e
"
,
buttonText:
"OK"
,
tapButton:
()
{
Navigator
.
pop
(
context
);
},
);
if
(
debug
)
{
// ignore: avoid_print
print
(
"CAMERA PERMISSION PROB ERROR:
$e
"
);
}
}
}
});
}
Future
<
void
>
initCamera
(
CameraController
c
)
async
{
c
.
initialize
().
then
((
_
)
{
if
(!
mounted
)
{
Navigator
.
pushNamedAndRemoveUntil
(
context
,
Routes
.
errorWidget
,
(
route
)
=>
false
,
arguments:
ErrorWidgetArguments
(
errorMessage:
Strings
.
cameraNotMounted
,
),
);
);
setState
(()
{
return
;
_initializeControllerFuture
=
_controller
!.
initialize
();
});
}
}
setState
(()
{
isCameraLoading
=
false
;
});
}).
catchError
((
e
)
{
}).
catchError
((
e
)
{
setState
(()
{
isCameraLoading
=
false
;
});
if
(
e
is
CameraException
)
{
if
(
e
is
CameraException
)
{
switch
(
e
.
code
)
{
switch
(
e
.
code
)
{
case
'CameraAccessDenied'
:
case
'CameraAccessDenied'
:
...
@@ -124,6 +196,25 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
...
@@ -124,6 +196,25 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
// setState(() {
// setState(() {
// errorCamera = "$e";
// errorCamera = "$e";
// });
// });
// Navigator.pushNamedAndRemoveUntil(
// context,
// Routes.errorWidget,
// (route) => false,
// arguments: ErrorWidgetArguments(
// errorMessage: "ERROR: $e",
// ),
// );
modalDialogGlobal
(
context:
context
,
size:
MediaQuery
.
of
(
context
).
size
,
title:
"Error"
,
contentBody:
"
$e
"
,
buttonText:
"OK"
,
tapButton:
()
{
Navigator
.
pop
(
context
);
},
);
if
(
debug
)
{
if
(
debug
)
{
// ignore: avoid_print
// ignore: avoid_print
print
(
"CAMERA PERMISSION PROB ERROR:
$e
"
);
print
(
"CAMERA PERMISSION PROB ERROR:
$e
"
);
...
@@ -137,6 +228,32 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
...
@@ -137,6 +228,32 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
return
await
availableCameras
();
return
await
availableCameras
();
}
}
// untuk mengetahui lama proses taking foto sampai response sukses
// final int _start = 10000;
// int _longTime = 0;
// CountdownTimer? countDownTimer;
// void startTimer() {
// print("START TIMER");
// countDownTimer = CountdownTimer(
// Duration(milliseconds: _start),
// const Duration(milliseconds: 1),
// );
// var sub = countDownTimer!.listen(null);
// sub.onData((duration) {
// setState(() {
// _longTime = duration.elapsed.inMilliseconds;
// });
// });
// }
// void stopTimer() {
// print("TIMER STOP");
// print("LAMA PROSES $_longTime miliseconds");
// countDownTimer!.cancel();
// }
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
Size
size
=
MediaQuery
.
of
(
context
).
size
;
Size
size
=
MediaQuery
.
of
(
context
).
size
;
...
@@ -153,343 +270,674 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
...
@@ -153,343 +270,674 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
return
Column
(
return
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
children:
[
// (isPermissionAccept) ?
isCameraLoading
(
_initializeControllerFuture
!=
null
)
?
const
Center
(
child:
CircularProgressIndicator
())
?
FutureBuilder
(
:
Stack
(
future:
_initializeControllerFuture
,
children:
[
builder:
((
context
,
snapshot
)
{
Container
(
if
(
snapshot
.
connectionState
==
ConnectionState
.
done
)
{
width:
size
.
width
,
return
Stack
(
height:
size
.
height
,
padding:
EdgeInsets
.
only
(
top:
AppPadding
.
safeAreaTop
(
context
)
+
40
),
child:
(
pictureIsTaken
)
?
(
isPhone
)
?
Image
.
file
(
File
(
imagePathPhone
!),
fit:
BoxFit
.
fill
,
)
:
Image
.
memory
(
imagePath
!,
// fit: BoxFit.fill,
)
:
CameraPreview
(
_controller
!,
),
),
Container
(
width:
size
.
width
,
height:
size
.
height
,
padding:
EdgeInsets
.
only
(
top:
AppPadding
.
safeAreaTop
(
context
)
+
40
),
child:
Image
(
fit:
BoxFit
.
fill
,
image:
AssetImage
(
Assets
.
frameOverlay
),
),
),
Container
(
width:
size
.
width
,
height:
size
.
height
,
child:
Column
(
children:
[
children:
[
Container
(
Container
(
width:
size
.
width
,
height:
AppPadding
.
safeAreaTop
(
context
)
+
60
,
height:
size
.
height
,
width:
double
.
infinity
,
padding:
EdgeInsets
.
only
(
decoration:
BoxDecoration
(
top:
AppPadding
.
safeAreaTop
(
context
)
+
40
),
borderRadius:
const
BorderRadius
.
only
(
child:
(
pictureIsTaken
)
bottomRight:
Radius
.
circular
(
20
),
?
(
isPhone
)
bottomLeft:
Radius
.
circular
(
20
),
?
Image
.
file
(
),
File
(
imagePathPhone
!),
color:
ColorManager
.
primary
,
fit:
BoxFit
.
fill
,
)
:
Image
.
memory
(
imagePath
!,
// fit: BoxFit.fill,
)
:
CameraPreview
(
_controller
!,
),
),
Container
(
width:
size
.
width
,
height:
size
.
height
,
padding:
EdgeInsets
.
only
(
top:
AppPadding
.
safeAreaTop
(
context
)
+
40
),
child:
Image
(
fit:
BoxFit
.
fill
,
image:
AssetImage
(
Assets
.
frameOverlay
),
),
),
),
child:
Container
(
Container
(
padding:
EdgeInsets
.
symmetric
(
width:
size
.
width
,
horizontal:
AppPadding
.
p20
),
height:
size
.
height
,
margin:
EdgeInsets
.
only
(
child:
Column
(
top:
AppPadding
.
safeAreaTop
(
context
),
children:
[
),
Container
(
child:
Row
(
height:
AppPadding
.
safeAreaTop
(
context
)
+
60
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
width:
double
.
infinity
,
children:
[
decoration:
BoxDecoration
(
GestureDetector
(
borderRadius:
const
BorderRadius
.
only
(
onTap:
()
{
bottomRight:
Radius
.
circular
(
20
),
Navigator
.
pop
(
context
);
bottomLeft:
Radius
.
circular
(
20
),
},
child:
const
Icon
(
Icons
.
arrow_back
,
color:
Colors
.
white
,
size:
24
,
),
),
color:
ColorManager
.
primary
,
),
),
child:
Container
(
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
AppPadding
.
p20
),
margin:
EdgeInsets
.
only
(
margin:
EdgeInsets
.
only
(
top:
AppPadding
.
safeAreaTop
(
context
)
,
left:
AppMargin
.
m16
,
),
),
child:
Row
(
child:
Text
(
crossAxisAlignment:
"Verifikasi Wajah (
${cameras!.length}
)"
,
CrossAxisAlignment
.
center
,
style:
getBoldStyle
(
color:
Colors
.
white
,
fontSize:
17
,
),
),
)
],
),
),
),
const
SizedBox
(
height:
15
,
),
WidgetAbsentAndTime
(
isIn:
widget
.
isIn
,
outletName:
widget
.
branchModel
.
code
,
),
const
Spacer
(),
(
pictureIsTaken
)
?
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
Container
(
width:
100
,
child:
CustomButton
(
text:
"Submit"
,
onTap:
()
async
{
// startTimer();
await
EasyLoading
.
show
(
status:
Strings
.
pleaseWait
,
maskType:
EasyLoadingMaskType
.
none
,
);
if
(
widget
.
isIn
)
{
Api
.
shiftIn
(
widget
.
branchModel
.
id
,
widget
.
nik
,
widget
.
shiftModel
!.
id
,
imageBase64
!,
).
then
((
apiResponse
)
{
// stopTimer();
EasyLoading
.
dismiss
();
if
(
apiResponse
.
error
)
{
EasyLoading
.
showToast
(
apiResponse
.
msg
);
return
;
}
AbsentSuccessModel
absentSuccess
=
apiResponse
.
data
as
AbsentSuccessModel
;
Navigator
.
pushNamedAndRemoveUntil
(
context
,
Routes
.
absentSuccess
,
(
route
)
=>
false
,
arguments:
AbsentSuccessArguments
(
absentSuccess:
absentSuccess
,
isIn:
true
,
),
);
});
}
else
{
Api
.
shiftOut
(
widget
.
branchModel
.
id
,
widget
.
nik
,
imageBase64
!,
).
then
((
apiResponse
)
{
// stopTimer();
EasyLoading
.
dismiss
();
if
(
apiResponse
.
error
)
{
EasyLoading
.
showToast
(
apiResponse
.
msg
,
);
return
;
}
AbsentSuccessModel
absentSuccess
=
apiResponse
.
data
as
AbsentSuccessModel
;
Navigator
.
pushNamedAndRemoveUntil
(
context
,
Routes
.
absentSuccess
,
(
route
)
=>
false
,
arguments:
AbsentSuccessArguments
(
absentSuccess:
absentSuccess
,
isIn:
false
,
),
);
});
}
},
),
),
Container
(
width:
100
,
margin:
const
EdgeInsets
.
only
(
top:
10
,
),
child:
GestureDetector
(
onTap:
()
{
setState
(()
{
pictureIsTaken
=
false
;
_controller
=
CameraController
(
// Get a specific camera from the list of available cameras.
_cameraDescription
!,
// Define the resolution to use.
ResolutionPreset
.
medium
,
imageFormatGroup:
ImageFormatGroup
.
jpeg
,
enableAudio:
false
,
);
initCamera
(
_controller
!);
});
},
child:
CustomButton
(
text:
"Foto Ulang"
,
colorButton:
ColorManager
.
grey
,
),
),
),
],
)
:
Stack
(
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
children:
[
GestureDetector
(
// GestureDetector(
onTap:
()
{
// onTap: () {
Navigator
.
pop
(
context
);
// if (flashMode ==
// FlashMode.always) {
// flashMode = FlashMode.off;
// } else {
// flashMode = FlashMode.always;
// }
// setState(() {
// _controller!
// .setFlashMode(flashMode);
// });
// },
// child: Icon(
// Icons.flash_auto,
// size: 35,
// color: ColorManager.primary,
// ),
// ),
const
SizedBox
(
width:
100
,
),
InkWell
(
onTap:
()
async
{
try
{
await
_initializeControllerFuture
;
// ambil imagenya
XFile
image
=
await
_controller
!
.
takePicture
();
String
?
imageResultPhone
;
Uint8List
?
imageResultWeb
;
if
(
isPhone
)
{
imageResultPhone
=
image
.
path
;
imageResultWeb
=
await
image
.
readAsBytes
();
}
else
{
imageResultWeb
=
await
image
.
readAsBytes
();
}
// kalau gak ke ambil gak ngelakuin aksi apa2
if
(!
mounted
)
return
;
setState
(()
{
pictureIsTaken
=
true
;
imagePath
=
imageResultWeb
;
imagePathPhone
=
imageResultPhone
;
imageBase64
=
base64Encode
(
imageResultWeb
!);
});
}
catch
(
e
)
{
if
(
debug
)
{
// ignore: avoid_print
print
(
"TERJADI KESALAHAAN SAAT AMBIL GAMBER, ERROR:
$e
"
);
}
}
},
},
child:
const
Icon
(
child:
Container
(
Icons
.
arrow_back
,
width:
80
,
color:
Colors
.
white
,
height:
80
,
size:
24
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
100
),
border:
Border
.
all
(
width:
1.5
,
color:
Colors
.
black
,
),
color:
Colors
.
red
,
),
),
),
),
),
Container
(
const
SizedBox
(
margin:
EdgeInsets
.
only
(
width:
60
,
left:
AppMargin
.
m16
,
),
),
GestureDetector
(
child:
Text
(
onTap:
()
{
"Verifikasi Wajah"
,
if
(
cameras
!.
length
>
1
)
{
style:
getBoldStyle
(
setState
(()
{
color:
Colors
.
white
,
isCameraLoading
=
true
;
fontSize:
17
,
if
(
_cameraDescription
==
),
cameras
![
0
])
{
_cameraDescription
=
cameras
![
1
];
}
else
{
_cameraDescription
=
cameras
![
0
];
}
_controller
=
CameraController
(
// Get a specific camera from the list of available cameras.
_cameraDescription
!,
// Define the resolution to use.
ResolutionPreset
.
medium
,
imageFormatGroup:
ImageFormatGroup
.
jpeg
,
enableAudio:
false
,
);
initCamera
(
_controller
!);
});
}
else
{
EasyLoading
.
showToast
(
"Kamera lain tidak terdeteksi"
);
}
},
child:
Icon
(
Icons
.
switch_camera_outlined
,
size:
35
,
color:
ColorManager
.
primary
,
),
),
)
)
],
],
),
),
)
,
]
,
),
),
const
SizedBox
(
const
SizedBox
(
height:
15
,
height:
30
,
),
)
WidgetAbsentAndTime
(
isIn:
widget
.
isIn
,
outletName:
widget
.
branchModel
.
code
,
),
const
Spacer
(),
(
pictureIsTaken
)
?
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
Container
(
width:
100
,
child:
CustomButton
(
text:
"Submit"
,
onTap:
()
async
{
await
EasyLoading
.
show
(
status:
Strings
.
pleaseWait
,
maskType:
EasyLoadingMaskType
.
none
,
);
if
(
widget
.
isIn
)
{
Api
.
shiftIn
(
widget
.
branchModel
.
id
,
widget
.
nik
,
widget
.
shiftModel
!.
id
,
imageBase64
!,
).
then
((
apiResponse
)
{
EasyLoading
.
dismiss
();
if
(
apiResponse
.
error
)
{
EasyLoading
.
showToast
(
apiResponse
.
msg
);
return
;
}
AbsentSuccessModel
absentSuccess
=
apiResponse
.
data
as
AbsentSuccessModel
;
Navigator
.
pushNamed
(
context
,
Routes
.
absentSuccess
,
arguments:
AbsentSuccessArguments
(
absentSuccess:
absentSuccess
,
isIn:
true
,
),
);
});
}
else
{
Api
.
shiftOut
(
widget
.
branchModel
.
id
,
widget
.
nik
,
imageBase64
!,
).
then
((
apiResponse
)
{
EasyLoading
.
dismiss
();
if
(
apiResponse
.
error
)
{
EasyLoading
.
showToast
(
apiResponse
.
msg
,
);
return
;
}
AbsentSuccessModel
absentSuccess
=
apiResponse
.
data
as
AbsentSuccessModel
;
Navigator
.
pushNamed
(
context
,
Routes
.
absentSuccess
,
arguments:
AbsentSuccessArguments
(
absentSuccess:
absentSuccess
,
isIn:
false
,
),
);
});
}
},
),
),
Container
(
width:
100
,
margin:
const
EdgeInsets
.
only
(
top:
10
,
),
child:
GestureDetector
(
onTap:
()
{
setState
(()
{
pictureIsTaken
=
false
;
_controller
=
CameraController
(
// Get a specific camera from the list of available cameras.
_cameraDescription
!,
// Define the resolution to use.
ResolutionPreset
.
medium
,
imageFormatGroup:
ImageFormatGroup
.
jpeg
,
);
_initializeControllerFuture
=
_controller
!.
initialize
();
});
},
child:
CustomButton
(
text:
"Foto Ulang"
,
colorButton:
ColorManager
.
grey
,
),
),
),
],
)
:
Stack
(
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
// GestureDetector(
// onTap: () {
// if (flashMode ==
// FlashMode.always) {
// flashMode = FlashMode.off;
// } else {
// flashMode = FlashMode.always;
// }
// setState(() {
// _controller!
// .setFlashMode(flashMode);
// });
// },
// child: Icon(
// Icons.flash_auto,
// size: 35,
// color: ColorManager.primary,
// ),
// ),
const
SizedBox
(
width:
100
,
),
InkWell
(
onTap:
()
async
{
try
{
await
_initializeControllerFuture
;
// ambil imagenya
XFile
image
=
await
_controller
!
.
takePicture
();
String
?
imageResultPhone
;
Uint8List
?
imageResultWeb
;
if
(
isPhone
)
{
imageResultPhone
=
image
.
path
;
imageResultWeb
=
await
image
.
readAsBytes
();
}
else
{
imageResultWeb
=
await
image
.
readAsBytes
();
}
// kalau gak ke ambil gak ngelakuin aksi apa2
if
(!
mounted
)
return
;
setState
(()
{
pictureIsTaken
=
true
;
imagePath
=
imageResultWeb
;
imagePathPhone
=
imageResultPhone
;
imageBase64
=
base64Encode
(
imageResultWeb
!);
});
}
catch
(
e
)
{
if
(
debug
)
{
// ignore: avoid_print
print
(
"TERJADI KESALAHAAN SAAT AMBIL GAMBER, ERROR:
$e
"
);
}
}
},
child:
Container
(
width:
80
,
height:
80
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
100
),
border:
Border
.
all
(
width:
1.5
,
color:
Colors
.
black
,
),
color:
Colors
.
red
,
),
),
),
const
SizedBox
(
width:
60
,
),
GestureDetector
(
onTap:
()
{
if
(
cameras
!.
length
>
1
)
{
setState
(()
{
if
(
_cameraDescription
==
cameras
![
0
])
{
_cameraDescription
=
cameras
![
1
];
}
else
{
_cameraDescription
=
cameras
![
0
];
}
_controller
=
CameraController
(
// Get a specific camera from the list of available cameras.
_cameraDescription
!,
// Define the resolution to use.
ResolutionPreset
.
medium
,
imageFormatGroup:
ImageFormatGroup
.
jpeg
,
);
_initializeControllerFuture
=
_controller
!
.
initialize
();
});
}
},
child:
Icon
(
Icons
.
switch_camera_outlined
,
size:
35
,
color:
ColorManager
.
primary
,
),
)
],
),
],
),
const
SizedBox
(
height:
30
,
)
],
),
),
],
],
);
),
}
else
{
),
return
const
Center
(
child:
CircularProgressIndicator
());
],
}
}),
)
)
:
const
Center
(
child:
CircularProgressIndicator
())
// (isPermissionAccept) ?
// (_initializeControllerFuture != null)
// ? FutureBuilder(
// future: _initializeControllerFuture,
// builder: ((context, snapshot) {
// if (snapshot.connectionState == ConnectionState.done) {
// return Stack(
// children: [
// Container(
// width: size.width,
// height: size.height,
// padding: EdgeInsets.only(
// top: AppPadding.safeAreaTop(context) + 40),
// child: (pictureIsTaken)
// ? (isPhone)
// ? Image.file(
// File(imagePathPhone!),
// fit: BoxFit.fill,
// )
// : Image.memory(
// imagePath!,
// // fit: BoxFit.fill,
// )
// : CameraPreview(
// _controller!,
// ),
// ),
// Container(
// width: size.width,
// height: size.height,
// padding: EdgeInsets.only(
// top: AppPadding.safeAreaTop(context) + 40),
// child: Image(
// fit: BoxFit.fill,
// image: AssetImage(Assets.frameOverlay),
// ),
// ),
// Container(
// width: size.width,
// height: size.height,
// child: Column(
// children: [
// Container(
// height: AppPadding.safeAreaTop(context) + 60,
// width: double.infinity,
// decoration: BoxDecoration(
// borderRadius: const BorderRadius.only(
// bottomRight: Radius.circular(20),
// bottomLeft: Radius.circular(20),
// ),
// color: ColorManager.primary,
// ),
// child: Container(
// padding: EdgeInsets.symmetric(
// horizontal: AppPadding.p20),
// margin: EdgeInsets.only(
// top: AppPadding.safeAreaTop(context),
// ),
// child: Row(
// crossAxisAlignment:
// CrossAxisAlignment.center,
// children: [
// GestureDetector(
// onTap: () {
// Navigator.pop(context);
// },
// child: const Icon(
// Icons.arrow_back,
// color: Colors.white,
// size: 24,
// ),
// ),
// Container(
// margin: EdgeInsets.only(
// left: AppMargin.m16,
// ),
// child: Text(
// "Verifikasi Wajah (${cameras!.length})",
// style: getBoldStyle(
// color: Colors.white,
// fontSize: 17,
// ),
// ),
// )
// ],
// ),
// ),
// ),
// const SizedBox(
// height: 15,
// ),
// WidgetAbsentAndTime(
// isIn: widget.isIn,
// outletName: widget.branchModel.code,
// ),
// const Spacer(),
// (pictureIsTaken)
// ? Column(
// crossAxisAlignment:
// CrossAxisAlignment.center,
// children: [
// Container(
// width: 100,
// child: CustomButton(
// text: "Submit",
// onTap: () async {
// // startTimer();
// await EasyLoading.show(
// status: Strings.pleaseWait,
// maskType:
// EasyLoadingMaskType.none,
// );
// if (widget.isIn) {
// Api.shiftIn(
// widget.branchModel.id,
// widget.nik,
// widget.shiftModel!.id,
// imageBase64!,
// ).then((apiResponse) {
// // stopTimer();
// EasyLoading.dismiss();
// if (apiResponse.error) {
// EasyLoading.showToast(
// apiResponse.msg);
// return;
// }
// AbsentSuccessModel
// absentSuccess =
// apiResponse.data
// as AbsentSuccessModel;
// Navigator
// .pushNamedAndRemoveUntil(
// context,
// Routes.absentSuccess,
// (route) => false,
// arguments:
// AbsentSuccessArguments(
// absentSuccess:
// absentSuccess,
// isIn: true,
// ),
// );
// });
// } else {
// Api.shiftOut(
// widget.branchModel.id,
// widget.nik,
// imageBase64!,
// ).then((apiResponse) {
// // stopTimer();
// EasyLoading.dismiss();
// if (apiResponse.error) {
// EasyLoading.showToast(
// apiResponse.msg,
// );
// return;
// }
// AbsentSuccessModel
// absentSuccess =
// apiResponse.data
// as AbsentSuccessModel;
// Navigator
// .pushNamedAndRemoveUntil(
// context,
// Routes.absentSuccess,
// (route) => false,
// arguments:
// AbsentSuccessArguments(
// absentSuccess:
// absentSuccess,
// isIn: false,
// ),
// );
// });
// }
// },
// ),
// ),
// Container(
// width: 100,
// margin: const EdgeInsets.only(
// top: 10,
// ),
// child: GestureDetector(
// onTap: () {
// setState(() {
// pictureIsTaken = false;
// _controller = CameraController(
// // Get a specific camera from the list of available cameras.
// _cameraDescription!,
// // Define the resolution to use.
// ResolutionPreset.medium,
// imageFormatGroup:
// ImageFormatGroup.jpeg,
// );
// _initializeControllerFuture =
// _controller!.initialize();
// });
// },
// child: CustomButton(
// text: "Foto Ulang",
// colorButton: ColorManager.grey,
// ),
// ),
// ),
// ],
// )
// : Stack(
// children: [
// Row(
// mainAxisAlignment:
// MainAxisAlignment.center,
// children: [
// // GestureDetector(
// // onTap: () {
// // if (flashMode ==
// // FlashMode.always) {
// // flashMode = FlashMode.off;
// // } else {
// // flashMode = FlashMode.always;
// // }
// // setState(() {
// // _controller!
// // .setFlashMode(flashMode);
// // });
// // },
// // child: Icon(
// // Icons.flash_auto,
// // size: 35,
// // color: ColorManager.primary,
// // ),
// // ),
// const SizedBox(
// width: 100,
// ),
// InkWell(
// onTap: () async {
// try {
// await _initializeControllerFuture;
// // ambil imagenya
// XFile image =
// await _controller!
// .takePicture();
// String? imageResultPhone;
// Uint8List? imageResultWeb;
// if (isPhone) {
// imageResultPhone =
// image.path;
// imageResultWeb = await image
// .readAsBytes();
// } else {
// imageResultWeb = await image
// .readAsBytes();
// }
// // kalau gak ke ambil gak ngelakuin aksi apa2
// if (!mounted) return;
// setState(() {
// pictureIsTaken = true;
// imagePath = imageResultWeb;
// imagePathPhone =
// imageResultPhone;
// imageBase64 = base64Encode(
// imageResultWeb!);
// });
// } catch (e) {
// if (debug) {
// // ignore: avoid_print
// print(
// "TERJADI KESALAHAAN SAAT AMBIL GAMBER, ERROR: $e");
// }
// }
// },
// child: Container(
// width: 80,
// height: 80,
// decoration: BoxDecoration(
// borderRadius:
// BorderRadius.circular(
// 100),
// border: Border.all(
// width: 1.5,
// color: Colors.black,
// ),
// color: Colors.red,
// ),
// ),
// ),
// const SizedBox(
// width: 60,
// ),
// GestureDetector(
// onTap: () {
// if (cameras!.length > 1) {
// setState(() {
// if (_cameraDescription ==
// cameras![0]) {
// _cameraDescription =
// cameras![1];
// } else {
// _cameraDescription =
// cameras![0];
// }
// _controller =
// CameraController(
// // Get a specific camera from the list of available cameras.
// _cameraDescription!,
// // Define the resolution to use.
// ResolutionPreset.medium,
// imageFormatGroup:
// ImageFormatGroup.jpeg,
// );
// _initializeControllerFuture =
// _controller!
// .initialize();
// });
// } else {
// EasyLoading.showToast(
// "Kamera lain tidak terdeteksi");
// }
// },
// child: Icon(
// Icons.switch_camera_outlined,
// size: 35,
// color: ColorManager.primary,
// ),
// )
// ],
// ),
// ],
// ),
// const SizedBox(
// height: 30,
// )
// ],
// ),
// ),
// ],
// );
// } else {
// return const Center(child: CircularProgressIndicator());
// }
// }),
// )
// : const Center(child: CircularProgressIndicator())
// : Center(
// : Center(
// child: Padding(
// child: Padding(
// padding: EdgeInsets.symmetric(
// padding: EdgeInsets.symmetric(
...
...
lib/page/home/home.dart
View file @
77a3594d
...
@@ -6,9 +6,11 @@ import 'package:excelso_attendance/helper/arguments/route_args.dart';
...
@@ -6,9 +6,11 @@ import 'package:excelso_attendance/helper/arguments/route_args.dart';
import
'package:excelso_attendance/helper/component/button.dart'
;
import
'package:excelso_attendance/helper/component/button.dart'
;
// import 'package:excelso_attendance/helper/component/text_field.dart';
// import 'package:excelso_attendance/helper/component/text_field.dart';
import
'package:excelso_attendance/helper/global_function/date_time.dart'
;
import
'package:excelso_attendance/helper/global_function/date_time.dart'
;
import
'package:excelso_attendance/helper/modal_dialog.dart'
;
import
'package:excelso_attendance/helper/pref.dart'
;
import
'package:excelso_attendance/helper/pref.dart'
;
import
'package:excelso_attendance/helper/widget_responsive.dart'
;
import
'package:excelso_attendance/helper/widget_responsive.dart'
;
import
'package:excelso_attendance/models/branch.dart'
;
import
'package:excelso_attendance/models/branch.dart'
;
import
'package:excelso_attendance/models/profile.dart'
;
import
'package:excelso_attendance/models/shift.dart'
;
import
'package:excelso_attendance/models/shift.dart'
;
import
'package:excelso_attendance/resource/assets.dart'
;
import
'package:excelso_attendance/resource/assets.dart'
;
import
'package:excelso_attendance/resource/colors.dart'
;
import
'package:excelso_attendance/resource/colors.dart'
;
...
@@ -349,8 +351,42 @@ class _BodyWidgetState extends State<BodyWidget> {
...
@@ -349,8 +351,42 @@ class _BodyWidgetState extends State<BodyWidget> {
).
then
((
apiResponse
)
{
).
then
((
apiResponse
)
{
EasyLoading
.
dismiss
();
EasyLoading
.
dismiss
();
if
(
apiResponse
.
error
)
{
if
(
apiResponse
.
error
)
{
EasyLoading
.
showToast
(
apiResponse
.
msg
);
modalDialogGlobal
(
context:
context
,
size:
MediaQuery
.
of
(
context
).
size
,
title:
"Gagal"
,
contentBody:
apiResponse
.
msg
,
buttonText:
"Ok"
,
tapButton:
()
{
Navigator
.
pop
(
context
);
});
}
else
{
}
else
{
ProfileModel
profileUser
=
apiResponse
.
data
as
ProfileModel
;
if
(
profileUser
.
attendanceOut
)
{
modalDialogGlobal
(
context:
context
,
size:
MediaQuery
.
of
(
context
).
size
,
title:
"Gagal"
,
contentBody:
Strings
.
alreadyOut
,
buttonText:
"Ok"
,
tapButton:
()
{
Navigator
.
pop
(
context
);
});
return
;
}
if
(
profileUser
.
attendanceIn
==
false
)
{
modalDialogGlobal
(
context:
context
,
size:
MediaQuery
.
of
(
context
).
size
,
title:
"Gagal"
,
contentBody:
Strings
.
outButNotIn
,
buttonText:
"Ok"
,
tapButton:
()
{
Navigator
.
pop
(
context
);
});
return
;
}
Navigator
.
pushNamed
(
Navigator
.
pushNamed
(
context
,
context
,
Routes
.
absentCamera
,
Routes
.
absentCamera
,
...
@@ -966,8 +1002,30 @@ class _WidgetSelectShiftState extends State<WidgetSelectShift> {
...
@@ -966,8 +1002,30 @@ class _WidgetSelectShiftState extends State<WidgetSelectShift> {
EasyLoading
.
dismiss
();
EasyLoading
.
dismiss
();
if
(
apiResponse
.
error
)
{
if
(
apiResponse
.
error
)
{
Navigator
.
pop
(
context
);
Navigator
.
pop
(
context
);
EasyLoading
.
showToast
(
apiResponse
.
msg
);
modalDialogGlobal
(
context:
context
,
size:
MediaQuery
.
of
(
context
).
size
,
title:
"Gagal"
,
contentBody:
apiResponse
.
msg
,
buttonText:
"Ok"
,
tapButton:
()
{
Navigator
.
pop
(
context
);
});
}
else
{
}
else
{
ProfileModel
profileUser
=
apiResponse
.
data
as
ProfileModel
;
if
(
profileUser
.
attendanceIn
)
{
modalDialogGlobal
(
context:
context
,
size:
MediaQuery
.
of
(
context
).
size
,
title:
"Gagal"
,
contentBody:
Strings
.
alreadyIn
,
buttonText:
"Ok"
,
tapButton:
()
{
Navigator
.
pop
(
context
);
Navigator
.
pop
(
context
);
});
return
;
}
Navigator
.
popAndPushNamed
(
Navigator
.
popAndPushNamed
(
context
,
context
,
Routes
.
absentCamera
,
Routes
.
absentCamera
,
...
...
lib/page/onboarding/onboarding.dart
View file @
77a3594d
...
@@ -157,184 +157,187 @@ class BodyWidget extends StatelessWidget {
...
@@ -157,184 +157,187 @@ class BodyWidget extends StatelessWidget {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
SingleChildScrollView
(
Size
size
=
MediaQuery
.
of
(
context
).
size
;
child:
Column
(
return
Column
(
children:
[
children:
[
Container
(
Container
(
width:
double
.
infinity
,
width:
double
.
infinity
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
ColorManager
.
primary
,
color:
ColorManager
.
primary
,
borderRadius:
const
BorderRadius
.
only
(
borderRadius:
const
BorderRadius
.
only
(
bottomLeft:
Radius
.
circular
(
50
),
bottomLeft:
Radius
.
circular
(
50
),
bottomRight:
Radius
.
circular
(
50
),
bottomRight:
Radius
.
circular
(
50
),
),
),
),
child:
Column
(
),
mainAxisSize:
MainAxisSize
.
min
,
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
mainAxisSize:
MainAxisSize
.
min
,
children:
[
crossAxisAlignment:
CrossAxisAlignment
.
start
,
Container
(
children:
[
padding:
EdgeInsets
.
only
(
Container
(
top:
AppPadding
.
safeAreaTop
(
context
)
+
38
,
padding:
EdgeInsets
.
only
(
left:
AppPadding
.
p20
,
top:
AppPadding
.
safeAreaTop
(
context
)
+
38
,
right:
AppPadding
.
p20
,
left:
AppPadding
.
p20
,
),
right:
AppPadding
.
p20
,
child:
Center
(
child:
Image
(
width:
119
,
height:
46
,
image:
AssetImage
(
Assets
.
excelso
),
),
),
),
),
Container
(
child:
Center
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
AppPadding
.
p20
,
),
margin:
EdgeInsets
.
only
(
top:
AppMargin
.
m16
,
),
width:
double
.
infinity
,
height:
332
,
child:
Image
(
child:
Image
(
fit:
BoxFit
.
fill
,
width:
119
,
image:
AssetImage
(
height:
46
,
Assets
.
onboarding
,
image:
AssetImage
(
Assets
.
excelso
),
),
),
),
),
),
Container
(
),
padding:
const
EdgeInsets
.
symmetric
(
Container
(
horizontal:
40
,
padding:
EdgeInsets
.
symmetric
(
),
horizontal:
AppPadding
.
p20
,
margin:
const
EdgeInsets
.
only
(
),
top:
32
,
margin:
EdgeInsets
.
only
(
bottom:
59
,
top:
AppMargin
.
m16
,
),
width:
double
.
infinity
,
height:
size
.
height
*
0.37
,
child:
Image
(
fit:
BoxFit
.
fill
,
image:
AssetImage
(
Assets
.
onboarding
,
),
),
child:
Column
(
),
crossAxisAlignment:
CrossAxisAlignment
.
start
,
),
children:
[
Container
(
Text
(
padding:
const
EdgeInsets
.
symmetric
(
"Attendance"
,
horizontal:
40
,
style:
getSemiBoldStyle
(
),
color:
Colors
.
white
,
margin:
const
EdgeInsets
.
only
(
fontSize:
24
,
top:
32
,
fontFamily:
FontConstants
.
montserrat
,
bottom:
59
,
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
"Attendance"
,
style:
getSemiBoldStyle
(
color:
Colors
.
white
,
fontSize:
24
,
fontFamily:
FontConstants
.
montserrat
,
),
),
Text
(
),
'''Memudahkan anda melakukan absen
Text
(
'''Memudahkan anda melakukan absen
dengan sekali klik'''
,
dengan sekali klik'''
,
style:
getRegularStyle
(
style:
getRegularStyle
(
color:
Colors
.
white
,
color:
Colors
.
white
,
fontSize:
12
,
fontSize:
12
,
),
),
)
)
],
],
),
),
)
)
],
],
),
),
),
GestureDetector
(
),
onTap:
()
{
GestureDetector
(
if
(
getAllApi
)
{
onTap:
()
{
Navigator
.
pushNamed
(
if
(
getAllApi
)
{
context
,
Navigator
.
pushNamed
(
Routes
.
home
,
context
,
arguments:
HomeArguments
(
Routes
.
home
,
branchModel:
nearestBranch
,
arguments:
HomeArguments
(
shiftModel:
shiftList
,
branchModel:
nearestBranch
,
),
shiftModel:
shiftList
,
);
),
}
);
},
}
child:
Container
(
},
margin:
const
EdgeInsets
.
only
(
child:
Container
(
top:
60
,
margin:
EdgeInsets
.
only
(
),
top:
size
.
height
*
0.05
,
padding:
EdgeInsets
.
symmetric
(
),
horizontal:
AppPadding
.
p20
,
padding:
EdgeInsets
.
symmetric
(
),
horizontal:
AppPadding
.
p20
,
child:
Center
(
),
child:
(
getAllApi
)
child:
Center
(
?
(
errorMessage
==
null
)
child:
(
getAllApi
)
?
Container
(
?
(
errorMessage
==
null
)
width:
60
,
?
Container
(
height:
60
,
width:
60
,
decoration:
BoxDecoration
(
height:
60
,
borderRadius:
BorderRadius
.
circular
(
100
),
decoration:
BoxDecoration
(
color:
ColorManager
.
primary
,
borderRadius:
BorderRadius
.
circular
(
100
),
color:
ColorManager
.
primary
,
),
child:
const
Center
(
child:
Icon
(
Icons
.
arrow_forward_ios_rounded
,
color:
Colors
.
white
,
size:
23
,
),
),
child:
const
Center
(
),
child:
Icon
(
)
Icons
.
arrow_forward_ios_rounded
,
:
Column
(
color:
Colors
.
white
,
children:
[
size:
23
,
Text
(
errorMessage
!,
style:
getSemiBoldStyle
(
color:
Colors
.
black
,
fontSize:
16
,
),
),
textAlign:
TextAlign
.
center
,
),
),
)
(
errorMessage
==
Strings
.
cantConnectToServer
)
:
Column
(
?
GestureDetector
(
children:
[
onTap:
()
{
Text
(
Navigator
.
pushNamedAndRemoveUntil
(
errorMessage
!,
context
,
style:
getSemiBoldStyle
(
Routes
.
onBoarding
,
color:
Colors
.
black
,
(
route
)
=>
false
,
fontSize:
16
,
);
),
},
textAlign:
TextAlign
.
center
,
child:
Container
(
),
width:
60
,
(
errorMessage
==
Strings
.
cantConnectToServer
)
height:
60
,
?
GestureDetector
(
margin:
EdgeInsets
.
only
(
onTap:
()
{
top:
AppMargin
.
m10
,
Navigator
.
pushNamedAndRemoveUntil
(
),
context
,
decoration:
BoxDecoration
(
Routes
.
onBoarding
,
borderRadius:
(
route
)
=>
false
,
BorderRadius
.
circular
(
100
),
);
color:
ColorManager
.
primary
,
},
),
child:
Container
(
child:
const
Center
(
width:
60
,
child:
Icon
(
height:
60
,
Icons
.
refresh_rounded
,
margin:
EdgeInsets
.
only
(
color:
Colors
.
white
,
top:
AppMargin
.
m10
,
size:
23
,
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
100
),
color:
ColorManager
.
primary
,
),
child:
const
Center
(
child:
Icon
(
Icons
.
refresh_rounded
,
color:
Colors
.
white
,
size:
23
,
),
),
),
),
),
)
)
,
:
const
SizedBox
(),
)
]
,
:
const
SizedBox
()
,
)
],
:
CircularProgressIndicator
(
)
color:
ColorManager
.
primary
,
:
CircularProgressIndicator
(
)
,
color:
ColorManager
.
primary
,
),
),
),
),
),
),
Container
(
),
margin:
const
EdgeInsets
.
only
(
const
Spacer
(),
top:
30
,
Container
(
),
margin:
const
EdgeInsets
.
only
(
child:
Text
(
top:
30
,
"Since © 2023"
,
),
style:
getMediumStyle
(
child:
Text
(
color:
Colors
.
black
,
"Since © 2023"
,
),
style:
getMediumStyle
(
color:
Colors
.
black
,
),
),
)
),
],
),
),
SizedBox
(
height:
AppMargin
.
m10
,
)
],
);
);
}
}
}
}
lib/resource/strings.dart
View file @
77a3594d
...
@@ -13,4 +13,9 @@ class Strings {
...
@@ -13,4 +13,9 @@ class Strings {
static
String
serverError
=
"Something wrong with our server, refresh page"
;
static
String
serverError
=
"Something wrong with our server, refresh page"
;
static
String
succesGetData
=
"Success get data"
;
static
String
succesGetData
=
"Success get data"
;
static
String
pleaseWait
=
"Please wait..."
;
static
String
pleaseWait
=
"Please wait..."
;
static
String
cameraNotMounted
=
"Kamera tidak berhasil di load"
;
static
String
alreadyIn
=
"Anda sudah melakukan absen masuk hari ini"
;
static
String
alreadyOut
=
"Anda sudah melakukan absen keluar hari ini"
;
static
String
outButNotIn
=
"Anda belum melaukan absen masuk"
;
}
}
pubspec.lock
View file @
77a3594d
...
@@ -74,7 +74,7 @@ packages:
...
@@ -74,7 +74,7 @@ packages:
source: hosted
source: hosted
version: "2.5.1"
version: "2.5.1"
camera_web:
camera_web:
dependency:
transitive
dependency:
"direct main"
description:
description:
name: camera_web
name: camera_web
sha256: bcbd775fb3a9d51cc3ece899d54ad66f6306410556bac5759f78e13f9228841f
sha256: bcbd775fb3a9d51cc3ece899d54ad66f6306410556bac5759f78e13f9228841f
...
@@ -425,7 +425,7 @@ packages:
...
@@ -425,7 +425,7 @@ packages:
source: hosted
source: hosted
version: "4.2.4"
version: "4.2.4"
quiver:
quiver:
dependency:
transitive
dependency:
"direct main"
description:
description:
name: quiver
name: quiver
sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
...
...
pubspec.yaml
View file @
77a3594d
...
@@ -31,6 +31,7 @@ environment:
...
@@ -31,6 +31,7 @@ environment:
dependencies
:
dependencies
:
autocomplete_textfield
:
^2.0.1
autocomplete_textfield
:
^2.0.1
camera
:
^0.10.5+2
camera
:
^0.10.5+2
camera_web
:
^0.3.1+4
cupertino_icons
:
^1.0.2
cupertino_icons
:
^1.0.2
dropdown_button2
:
^2.1.3
dropdown_button2
:
^2.1.3
flutter
:
flutter
:
...
@@ -39,6 +40,7 @@ dependencies:
...
@@ -39,6 +40,7 @@ dependencies:
flutter_native_splash
:
^2.3.0
flutter_native_splash
:
^2.3.0
geolocator
:
^9.0.2
geolocator
:
^9.0.2
http
:
^0.13.5
http
:
^0.13.5
quiver
:
^3.2.1
shared_preferences
:
^2.1.1
shared_preferences
:
^2.1.1
url_strategy
:
^0.2.0
url_strategy
:
^0.2.0
...
...
web/index.html
View file @
77a3594d
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
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=
"
/attendance/
"
/>
<meta
charset=
"UTF-8"
/>
<meta
charset=
"UTF-8"
/>
<meta
content=
"IE=Edge"
http-equiv=
"X-UA-Compatible"
/>
<meta
content=
"IE=Edge"
http-equiv=
"X-UA-Compatible"
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment