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
c71dbe0b
Commit
c71dbe0b
authored
Jan 02, 2026
by
William Goszal
🚴
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tambah break_start dan break_end
parent
c21740a1
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
538 additions
and
295 deletions
+538
-295
api.dart
lib/api/api.dart
+73
-20
route_args.dart
lib/helper/arguments/route_args.dart
+4
-0
absent_camera.dart
lib/page/absent_camera/absent_camera.dart
+265
-198
absent_success.dart
lib/page/absent_success/absent_success.dart
+15
-5
home.dart
lib/page/home/home.dart
+169
-58
routes.dart
lib/resource/routes.dart
+12
-14
No files found.
lib/api/api.dart
View file @
c71dbe0b
...
...
@@ -29,9 +29,7 @@ class Api {
// dynamic jsonObject = await httpRequest(
// typePost, apiUrl, "getNearestBranch",
// bodies: bodies);
HttpResponseApi
apiResult
=
await
ConstantApi
.
httpRequest
(
typePost
,
apiUrl
,
"getNearestBranch"
,
bodies:
bodies
);
HttpResponseApi
apiResult
=
await
ConstantApi
.
httpRequest
(
typePost
,
apiUrl
,
"getNearestBranch"
,
bodies:
bodies
);
if
(
apiResult
.
succes
==
false
)
{
return
apiResult
.
apiResponse
!;
}
else
{
...
...
@@ -47,12 +45,9 @@ class Api {
),
);
}
ConstantString
.
outletDistance
=
jsonObject
[
'data'
][
'max_distance'
].
toString
();
ConstantString
.
logoUrlHome
=
jsonObject
[
'data'
][
'logo_attendance_home'
];
ConstantString
.
logoUrlCamera
=
jsonObject
[
'data'
][
'logo_attendance_camera'
];
ConstantString
.
outletDistance
=
jsonObject
[
'data'
][
'max_distance'
].
toString
();
ConstantString
.
logoUrlHome
=
jsonObject
[
'data'
][
'logo_attendance_home'
];
ConstantString
.
logoUrlCamera
=
jsonObject
[
'data'
][
'logo_attendance_camera'
];
return
ApiResponse
(
error:
false
,
msg:
Strings
.
succesGetData
,
...
...
@@ -169,8 +164,7 @@ class Api {
}
}
static
Future
<
ApiResponse
>
shiftIn
(
String
branchId
,
String
nik
,
String
shiftId
,
String
photoBase64
,
static
Future
<
ApiResponse
>
shiftIn
(
String
branchId
,
String
nik
,
String
shiftId
,
String
photoBase64
,
{
int
forceSubmit
=
0
})
async
{
String
apiUrl
=
"
$baseUrl${endPoint}
clock_in"
;
// Position position = await Geolocator.getCurrentPosition();
...
...
@@ -212,8 +206,7 @@ class Api {
if
(
jsonObject
[
'status'
]
==
"ok"
)
{
// simpan NIK user
List
<
String
>
listAbsentUser
=
getListAbsentUser
();
int
indexList
=
listAbsentUser
.
indexWhere
((
element
)
=>
element
==
nik
);
int
indexList
=
listAbsentUser
.
indexWhere
((
element
)
=>
element
==
nik
);
if
(
indexList
==
-
1
)
{
listAbsentUser
.
add
(
nik
);
setListAbsentUser
(
listAbsentUser
);
...
...
@@ -243,9 +236,7 @@ class Api {
}
}
static
Future
<
ApiResponse
>
shiftOut
(
String
branchId
,
String
nik
,
String
photoBase64
,
{
int
forceSubmit
=
0
})
async
{
static
Future
<
ApiResponse
>
shiftOut
(
String
branchId
,
String
nik
,
String
photoBase64
,
{
int
forceSubmit
=
0
})
async
{
String
apiUrl
=
"
$baseUrl${endPoint}
clock_out"
;
// Position position = await Geolocator.getCurrentPosition();
...
...
@@ -286,8 +277,72 @@ class Api {
if
(
jsonObject
[
'status'
]
==
"ok"
)
{
// simpan NIK user
List
<
String
>
listAbsentUser
=
getListAbsentUser
();
int
indexList
=
listAbsentUser
.
indexWhere
((
element
)
=>
element
==
nik
);
int
indexList
=
listAbsentUser
.
indexWhere
((
element
)
=>
element
==
nik
);
if
(
indexList
==
-
1
)
{
listAbsentUser
.
add
(
nik
);
setListAbsentUser
(
listAbsentUser
);
}
return
ApiResponse
(
error:
false
,
msg:
Strings
.
succesGetData
,
data:
AbsentSuccessModel
.
json
(
jsonObject
[
'data'
],
),
);
}
else
{
return
ApiResponse
(
error:
true
,
msg:
jsonObject
[
'msg'
],
code:
jsonObject
[
'code'
],
);
}
}
}
catch
(
e
)
{
return
ApiResponse
(
error:
true
,
msg:
"Error:
$e
"
);
}
}
static
Future
<
ApiResponse
>
submitBreak
(
bool
isIn
,
String
branchId
,
String
nik
,
String
photoBase64
,
{
int
forceSubmit
=
0
})
async
{
String
action
=
isIn
?
"break_start"
:
"break_end"
;
String
apiUrl
=
"
$baseUrl$endPoint$action
"
;
IpAddress
ipAddress
=
IpAddress
(
type:
RequestType
.
json
);
dynamic
dataIp
=
await
ipAddress
.
getIpAddress
();
DeviceInfoPlugin
deviceInfo
=
DeviceInfoPlugin
();
String
userAgent
=
""
;
if
(
kIsWeb
)
{
WebBrowserInfo
browser
=
await
deviceInfo
.
webBrowserInfo
;
userAgent
=
browser
.
userAgent
??
""
;
}
try
{
Map
<
String
,
dynamic
>
data
=
{
"branch_id"
:
branchId
,
"brand_code"
:
brandCode
,
"nik"
:
nik
,
"user_lat"
:
getLatitude
(),
"user_long"
:
getLongitude
(),
"photo_base64"
:
photoBase64
,
"ip"
:
dataIp
[
'ip'
],
"user_agent"
:
userAgent
,
"forced_submit"
:
forceSubmit
,
};
String
bodies
=
jsonEncode
(
data
);
HttpResponseApi
apiResult
=
await
ConstantApi
.
httpRequest
(
typePost
,
apiUrl
,
"shiftIn"
,
bodies:
bodies
,
);
if
(
apiResult
.
succes
==
false
)
{
return
ApiResponse
(
error:
true
,
msg:
Strings
.
cantConnectToServer
);
}
else
{
Map
<
String
,
dynamic
>
jsonObject
=
apiResult
.
jsonObject
!;
if
(
jsonObject
[
'status'
]
==
"ok"
)
{
// simpan NIK user
List
<
String
>
listAbsentUser
=
getListAbsentUser
();
int
indexList
=
listAbsentUser
.
indexWhere
((
element
)
=>
element
==
nik
);
if
(
indexList
==
-
1
)
{
listAbsentUser
.
add
(
nik
);
setListAbsentUser
(
listAbsentUser
);
...
...
@@ -369,5 +424,3 @@ int typePost = 2;
// this.code = "",
// });
// }
lib/helper/arguments/route_args.dart
View file @
c71dbe0b
...
...
@@ -4,6 +4,7 @@ import 'package:ravintola_attendance/models/profile.dart';
import
'package:ravintola_attendance/models/shift.dart'
;
class
AbsentCameraArguments
{
final
int
actionType
;
// 1 = Absent, 2 = Break
final
bool
isIn
;
final
BranchModel
branchModel
;
final
ShiftModel
?
shiftModel
;
...
...
@@ -14,6 +15,7 @@ class AbsentCameraArguments {
final
String
shiftEndTime
;
AbsentCameraArguments
({
this
.
actionType
=
1
,
required
this
.
isIn
,
required
this
.
branchModel
,
required
this
.
nik
,
...
...
@@ -39,6 +41,7 @@ class AbsentSuccessArguments {
final
AbsentSuccessModel
absentSuccess
;
final
ProfileModel
profil
;
final
String
nik
;
final
int
actionType
;
final
bool
isIn
;
final
String
shiftStart
;
final
String
shiftEnd
;
...
...
@@ -48,6 +51,7 @@ class AbsentSuccessArguments {
required
this
.
absentSuccess
,
required
this
.
profil
,
required
this
.
nik
,
required
this
.
actionType
,
required
this
.
isIn
,
required
this
.
shiftStart
,
required
this
.
shiftEnd
,
...
...
lib/page/absent_camera/absent_camera.dart
View file @
c71dbe0b
This diff is collapsed.
Click to expand it.
lib/page/absent_success/absent_success.dart
View file @
c71dbe0b
...
...
@@ -11,11 +11,21 @@ import 'package:ravintola_attendance/resource/size.dart';
import
'package:ravintola_attendance/resource/style.dart'
;
import
'package:flutter/material.dart'
;
String
getAbsentText
(
bool
isIn
,
int
actionType
)
{
if
(
actionType
==
1
)
{
return
isIn
?
"Absen Masuk"
:
"Absen Keluar"
;
}
else
if
(
actionType
==
2
)
{
return
isIn
?
"Break Start"
:
"Break End"
;
}
return
"Unknown"
;
}
class
AbsentSuccessView
extends
StatelessWidget
{
const
AbsentSuccessView
({
super
.
key
,
required
this
.
absentSuccess
,
required
this
.
isIn
,
required
this
.
actionType
,
required
this
.
nik
,
required
this
.
profil
,
required
this
.
shiftStart
,
...
...
@@ -26,6 +36,7 @@ class AbsentSuccessView extends StatelessWidget {
final
AbsentSuccessModel
absentSuccess
;
final
ProfileModel
profil
;
final
String
nik
;
final
int
actionType
;
final
bool
isIn
;
final
String
shiftStart
;
final
String
shiftEnd
;
...
...
@@ -37,6 +48,7 @@ class AbsentSuccessView extends StatelessWidget {
backgroundColor:
ColorManager
.
backgroundColor
,
body:
ScreenResponsive
(
widget:
BodyWidget
(
actionType:
actionType
,
isIn:
isIn
,
profil:
profil
,
nik:
nik
,
...
...
@@ -54,6 +66,7 @@ class AbsentSuccessView extends StatelessWidget {
class
BodyWidget
extends
StatelessWidget
{
const
BodyWidget
({
super
.
key
,
required
this
.
actionType
,
required
this
.
isIn
,
required
this
.
profil
,
required
this
.
nik
,
...
...
@@ -63,6 +76,7 @@ class BodyWidget extends StatelessWidget {
required
this
.
shiftName
,
});
final
int
actionType
;
final
bool
isIn
;
final
ProfileModel
profil
;
final
String
nik
;
...
...
@@ -134,11 +148,7 @@ class BodyWidget extends StatelessWidget {
width:
double
.
infinity
,
child:
Center
(
child:
Text
(
(
isIn
)
?
'''Absen Masuk
Sukses'''
:
'''Absen Keluar
Sukses'''
,
getAbsentText
(
isIn
,
actionType
),
style:
getSemiBoldStyle
(
color:
Colors
.
black
,
fontSize:
FontSize
.
s24
,
...
...
lib/page/home/home.dart
View file @
c71dbe0b
This diff is collapsed.
Click to expand it.
lib/resource/routes.dart
View file @
c71dbe0b
...
...
@@ -23,8 +23,7 @@ class RouteGenerator {
static
Route
<
dynamic
>
getRoute
(
RouteSettings
routeSettings
)
{
switch
(
routeSettings
.
name
)
{
case
Routes
.
onBoarding
:
return
pageRouteCustom
(
const
OnBoardingView
(),
nameRoute:
Routes
.
onBoarding
);
return
pageRouteCustom
(
const
OnBoardingView
(),
nameRoute:
Routes
.
onBoarding
);
case
Routes
.
home
:
HomeArguments
args
=
routeSettings
.
arguments
as
HomeArguments
;
return
pageRouteCustom
(
...
...
@@ -37,10 +36,11 @@ class RouteGenerator {
);
case
Routes
.
absentCamera
:
AbsentCameraArguments
args
=
routeSettings
.
arguments
as
AbsentCameraArguments
;
AbsentCameraArguments
args
=
routeSettings
.
arguments
as
AbsentCameraArguments
;
print
(
"Generating route for AbsentCamera with isIn:
${args.isIn}
, actionType:
${args.actionType}
"
)
;
return
pageRouteCustom
(
AbsentCameraView
(
actionType:
args
.
actionType
,
isIn:
args
.
isIn
,
branchModel:
args
.
branchModel
,
shiftModel:
args
.
shiftModel
,
...
...
@@ -54,13 +54,13 @@ class RouteGenerator {
routeSettings:
routeSettings
,
);
case
Routes
.
absentSuccess
:
AbsentSuccessArguments
args
=
routeSettings
.
arguments
as
AbsentSuccessArguments
;
AbsentSuccessArguments
args
=
routeSettings
.
arguments
as
AbsentSuccessArguments
;
return
pageRouteCustom
(
AbsentSuccessView
(
absentSuccess:
args
.
absentSuccess
,
profil:
args
.
profil
,
nik:
args
.
nik
,
actionType:
args
.
actionType
,
isIn:
args
.
isIn
,
shiftEnd:
args
.
shiftEnd
,
shiftStart:
args
.
shiftStart
,
...
...
@@ -70,8 +70,7 @@ class RouteGenerator {
routeSettings:
routeSettings
,
);
case
Routes
.
errorWidget
:
ErrorWidgetArguments
args
=
routeSettings
.
arguments
as
ErrorWidgetArguments
;
ErrorWidgetArguments
args
=
routeSettings
.
arguments
as
ErrorWidgetArguments
;
return
pageRouteCustom
(
ErrorWidgetView
(
messageError:
args
.
errorMessage
,
...
...
@@ -104,10 +103,10 @@ class RouteGenerator {
})
{
// setTitle(title);
if
(
nameRoute
==
Routes
.
absentCamera
)
{
AbsentCameraArguments
args
=
routeSettings
!.
arguments
as
AbsentCameraArguments
;
AbsentCameraArguments
args
=
routeSettings
!.
arguments
as
AbsentCameraArguments
;
return
PageRouteBuilder
(
pageBuilder:
(
context
,
a
,
b
)
=>
AbsentCameraView
(
actionType:
args
.
actionType
,
isIn:
args
.
isIn
,
branchModel:
args
.
branchModel
,
shiftModel:
args
.
shiftModel
,
...
...
@@ -123,8 +122,7 @@ class RouteGenerator {
// name: nameRoute.replaceFirst("/", ""), arguments: args),
);
}
else
if
(
nameRoute
==
Routes
.
errorWidget
)
{
ErrorWidgetArguments
args
=
routeSettings
!.
arguments
as
ErrorWidgetArguments
;
ErrorWidgetArguments
args
=
routeSettings
!.
arguments
as
ErrorWidgetArguments
;
return
PageRouteBuilder
(
pageBuilder:
(
context
,
a
,
b
)
=>
ErrorWidgetView
(
messageError:
args
.
errorMessage
,
...
...
@@ -147,13 +145,13 @@ class RouteGenerator {
// name: nameRoute.replaceFirst("/", ""), arguments: args),
);
}
else
if
(
nameRoute
==
Routes
.
absentSuccess
)
{
AbsentSuccessArguments
args
=
routeSettings
!.
arguments
as
AbsentSuccessArguments
;
AbsentSuccessArguments
args
=
routeSettings
!.
arguments
as
AbsentSuccessArguments
;
return
PageRouteBuilder
(
pageBuilder:
(
context
,
a
,
b
)
=>
AbsentSuccessView
(
absentSuccess:
args
.
absentSuccess
,
profil:
args
.
profil
,
nik:
args
.
nik
,
actionType:
args
.
actionType
,
isIn:
args
.
isIn
,
shiftEnd:
args
.
shiftEnd
,
shiftStart:
args
.
shiftStart
,
...
...
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