Commit e8e4274e authored by Dio Maulana's avatar Dio Maulana

fixed API for onboarding and HOME view

parent bc1bc4a3
import 'dart:convert';
import 'package:excelso_attendance/helper/logger.dart';
import 'package:excelso_attendance/helper/pref.dart';
import 'package:excelso_attendance/main.dart';
import 'package:excelso_attendance/models/branch.dart';
import 'package:excelso_attendance/models/shift.dart';
import 'package:http/http.dart' as http;
String baseUrl = "";
String endPoint = "rav/attendance/";
class Api {
static Future<Map<String, dynamic>> getNearestBranch() async {
static Future<ApiResponse> getNearestBranch() async {
String apiUrl = "$baseUrl${endPoint}nearest_branch_list";
Map<String, dynamic> result;
try {
dynamic jsonObject =
await httpRequest(typePost, apiUrl, "getNearestBranch");
Map<String, dynamic> data = {
"brand_code": brandCode,
"user_lat": getLatitude(),
"user_long": getLongitude(),
};
String bodies = jsonEncode(data);
dynamic jsonObject = await httpRequest(
typePost, apiUrl, "getNearestBranch",
bodies: bodies);
if (jsonObject == false) {
result = {"error": true, "msg": "Can't connect to server"};
return result;
return ApiResponse(error: true, msg: "Can't connect to server");
} else {
List<BranchModel> branchList = [];
......@@ -30,20 +34,50 @@ class Api {
),
);
}
result = {
"error": false,
"msg": "Success get data",
"branchs": branchList,
};
return result;
return ApiResponse(
error: false,
msg: "Success get data",
data: branchList,
);
}
} catch (e) {
result = {
"error": true,
"msg": "Something wrong with our server, try again later"
return ApiResponse(
error: true, msg: "Something wrong with our server, refresh page");
}
}
static Future<ApiResponse> getShiftList() async {
String apiUrl = "$baseUrl${endPoint}shift_list";
try {
Map<String, dynamic> data = {
"brand_code": brandCode,
};
return result;
String bodies = jsonEncode(data);
dynamic jsonObject =
await httpRequest(typePost, apiUrl, "getShiftList", bodies: bodies);
if (jsonObject == false) {
return ApiResponse(error: true, msg: "Can't connect to server");
} else {
List<ShiftModel> shiftList = [];
List<dynamic> shift = jsonObject['data']['shift_list'];
for (int i = 0; i < shift.length; i++) {
shiftList.add(
ShiftModel.json(
shift[i],
),
);
}
return ApiResponse(
error: false,
msg: "Success get data",
data: shiftList,
);
}
} catch (e) {
return ApiResponse(
error: true, msg: "Something wrong with our server, refresh page");
}
}
}
......@@ -79,3 +113,15 @@ Future<dynamic> httpRequest(int typeRequest, String apiUrl, String namaFungsi,
return false;
}
}
class ApiResponse {
bool error;
String msg;
dynamic data;
ApiResponse({
required this.error,
required this.msg,
this.data,
});
}
import 'package:excelso_attendance/models/branch.dart';
import 'package:excelso_attendance/models/shift.dart';
class AbsentCameraArguments {
final bool isIn;
final String outletName;
final BranchModel branchModel;
final ShiftModel? shiftModel;
AbsentCameraArguments({
required this.isIn,
required this.outletName,
required this.branchModel,
this.shiftModel,
});
}
class HomeArguments {
final List<BranchModel> branchModel;
final List<ShiftModel> shiftModel;
HomeArguments({
required this.branchModel,
required this.shiftModel,
});
}
class DateFormatCustom {
static String monthLocal(String month) {
static String monthLocal(String m) {
String month;
if (m.length == 1) {
month = "0$m";
} else {
month = m;
}
switch (month) {
case "01":
return "Januari";
......@@ -44,24 +50,41 @@ class DateFormatCustom {
}
}
static String getLocalTime({bool timeZoneActive = false}) {
static String getLocalTime(
{bool timeZoneActive = false, bool secondActive = false}) {
DateTime localTime = DateTime.now().toLocal();
int hour = localTime.hour;
String min = localTime.minute.toString();
String second = localTime.second.toString();
String minute;
String sec;
if (min.length == 1) {
minute = "0$min";
} else {
minute = min;
}
if (second.length == 1) {
sec = "0$second";
} else {
sec = second;
}
// int sec = localTime.second;
String timeZone = localTimeZoneName(localTime.timeZoneOffset.toString());
String result;
if (timeZoneActive) {
result = "$hour : $minute $timeZone";
if (secondActive) {
result = "$hour : $minute : $sec $timeZone";
} else {
result = "$hour : $minute $timeZone";
}
} else {
result = "$hour : $minute";
if (secondActive) {
result = "$hour : $minute : $sec";
} else {
result = "$hour : $minute";
}
}
return result;
......@@ -76,4 +99,13 @@ class DateFormatCustom {
String result = "$day $month $year";
return result;
}
static String getTimeHourMinuteOnly(String time) {
// awalnya dari API 00:00:00, balikin 00:00 ke UI
List<String> timeSplit = time.split(":");
String result;
result = "${timeSplit[0]} : ${timeSplit[1]}";
return result;
}
}
......@@ -4,9 +4,16 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_strategy/url_strategy.dart';
// all config here
bool debug = true;
late SharedPreferences prefs;
String titleApp = 'Excelso Attendances';
String brandCode = "EXC";
String baseUrl = "https://hibiscus-dev.ravku.com/";
String endPoint = "rav/attendance/";
// final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
void main() async {
......
......@@ -2,11 +2,13 @@ class BranchModel {
String id;
String code;
String name;
double distance;
BranchModel({
required this.id,
required this.code,
required this.name,
required this.distance,
});
factory BranchModel.json(Map<String, dynamic> json) {
......@@ -14,6 +16,7 @@ class BranchModel {
id: json['id'],
code: json['code'],
name: json['name'],
distance: json['distance'],
);
}
}
......@@ -5,6 +5,8 @@ import 'dart:io';
import 'package:excelso_attendance/helper/arguments/error_args.dart';
import 'package:excelso_attendance/helper/widget_responsive.dart';
import 'package:excelso_attendance/main.dart';
import 'package:excelso_attendance/models/branch.dart';
import 'package:excelso_attendance/models/shift.dart';
import 'package:excelso_attendance/resource/routes.dart';
import 'package:excelso_attendance/resource/strings.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
......@@ -21,11 +23,16 @@ import 'package:excelso_attendance/resource/style.dart';
import 'package:flutter/material.dart';
class AbsentCameraView extends StatefulWidget {
const AbsentCameraView(
{super.key, required this.outletName, required this.isIn});
const AbsentCameraView({
super.key,
required this.isIn,
required this.branchModel,
this.shiftModel,
});
final String outletName;
final bool isIn;
final BranchModel branchModel;
final ShiftModel? shiftModel;
@override
State<AbsentCameraView> createState() => _AbsentCameraViewState();
......@@ -229,7 +236,7 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
),
WidgetAbsentAndTime(
isIn: widget.isIn,
outletName: widget.outletName,
outletName: widget.branchModel.code,
),
const Spacer(),
(pictureIsTaken)
......@@ -258,6 +265,14 @@ class _AbsentCameraViewState extends State<AbsentCameraView> {
onTap: () {
setState(() {
pictureIsTaken = false;
_controller = CameraController(
// Get a specific camera from the list of available cameras.
_cameraDescription!,
// Define the resolution to use.
ResolutionPreset.medium,
);
_initializeControllerFuture =
_controller!.initialize();
});
},
child: CustomButton(
......@@ -507,13 +522,17 @@ class _WidgetAbsentAndTimeState extends State<WidgetAbsentAndTime> {
fontFamily: FontConstants.poppins,
),
),
Text(
"${widget.outletName} - ${DateFormatCustom.getLocalTime(
timeZoneActive: true,
)}",
style: getSemiBoldStyle(
color: Colors.black,
fontSize: FontSize.s24,
Expanded(
child: Text(
"${widget.outletName} - ${DateFormatCustom.getLocalTime(
timeZoneActive: true,
)}",
style: getSemiBoldStyle(
color: Colors.black,
fontSize: FontSize.s24,
),
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
),
],
......
This diff is collapsed.
import 'package:excelso_attendance/api/api.dart';
import 'package:excelso_attendance/helper/arguments/error_args.dart';
import 'package:excelso_attendance/helper/arguments/route_args.dart';
import 'package:excelso_attendance/helper/pref.dart';
import 'package:excelso_attendance/helper/widget_responsive.dart';
import 'package:excelso_attendance/models/branch.dart';
import 'package:excelso_attendance/models/shift.dart';
import 'package:excelso_attendance/resource/assets.dart';
import 'package:excelso_attendance/resource/colors.dart';
import 'package:excelso_attendance/resource/font.dart';
......@@ -21,10 +25,29 @@ class OnBoardingView extends StatefulWidget {
}
class _OnBoardingViewState extends State<OnBoardingView> {
bool getAllApi = false;
String? errorMessage;
List<BranchModel> nearestBranch = [];
List<ShiftModel> shiftList = [];
@override
void initState() {
super.initState();
getUserPermission();
getUserPermission().then((value) {
if (value) {
getNearestBranch().then((branchBool) {
if (branchBool) {
// ambil list shift kalau ada outlet
getShiftList();
} else {
// setstate aja, gausah ambil list shift karena gak ada utlet
setState(() {});
}
});
}
});
// final perm =
// await html.window.navigator.permissions!.query({"name": "camera"});
// if (perm.state == "denied") {
......@@ -35,7 +58,43 @@ class _OnBoardingViewState extends State<OnBoardingView> {
// }
}
void getUserPermission() async {
Future<bool> getNearestBranch() async {
ApiResponse getNearestBranch = await Api.getNearestBranch();
if (getNearestBranch.error) {
errorMessage = getNearestBranch.msg;
getAllApi = true;
return false;
} else {
List<BranchModel> dataBranchs =
getNearestBranch.data as List<BranchModel>;
nearestBranch = dataBranchs;
if (dataBranchs.isEmpty) {
errorMessage = Strings.noOutletArround;
getAllApi = true;
return false;
}
return true;
}
}
void getShiftList() async {
ApiResponse getShiftList = await Api.getShiftList();
setState(() {
getAllApi = true;
if (getShiftList.error) {
errorMessage = Strings.errorGetShiftList;
} else {
List<ShiftModel> dataShift = getShiftList.data as List<ShiftModel>;
shiftList = dataShift;
if (dataShift.isEmpty) {
errorMessage = Strings.errorGetShiftList;
}
}
});
}
Future<bool> getUserPermission() async {
LocationPermission permission = await Geolocator.requestPermission();
if (permission == LocationPermission.always ||
permission == LocationPermission.whileInUse) {
......@@ -43,6 +102,7 @@ class _OnBoardingViewState extends State<OnBoardingView> {
setLatitude(position.latitude.toString());
setLongitude(position.longitude.toString());
});
return true;
} else {
// ignore: use_build_context_synchronously
Navigator.pushNamedAndRemoveUntil(
......@@ -53,6 +113,7 @@ class _OnBoardingViewState extends State<OnBoardingView> {
errorMessage: Strings.locationNotActive,
),
);
return false;
}
// await html.window.navigator.getUserMedia(audio: true, video: true);
}
......@@ -62,7 +123,12 @@ class _OnBoardingViewState extends State<OnBoardingView> {
return Scaffold(
backgroundColor: ColorManager.backgroundColor,
body: ScreenResponsive(
widget: const BodyWidget(),
widget: BodyWidget(
getAllApi: getAllApi,
errorMessage: errorMessage,
nearestBranch: nearestBranch,
shiftList: shiftList,
),
widthScreen: MediaQuery.of(context).size.width,
),
);
......@@ -72,8 +138,17 @@ class _OnBoardingViewState extends State<OnBoardingView> {
class BodyWidget extends StatelessWidget {
const BodyWidget({
super.key,
required this.getAllApi,
required this.nearestBranch,
this.errorMessage,
required this.shiftList,
});
final bool getAllApi;
final String? errorMessage;
final List<BranchModel> nearestBranch;
final List<ShiftModel> shiftList;
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
......@@ -157,28 +232,53 @@ dengan sekali klik''',
),
GestureDetector(
onTap: () {
Navigator.pushNamed(context, Routes.home);
if (getAllApi) {
Navigator.pushNamed(
context,
Routes.home,
arguments: HomeArguments(
branchModel: nearestBranch,
shiftModel: shiftList,
),
);
}
},
child: Container(
margin: const EdgeInsets.only(
top: 60,
),
padding: EdgeInsets.symmetric(
horizontal: AppPadding.p20,
),
child: Center(
child: Container(
width: 60,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: ColorManager.primary,
),
child: const Center(
child: Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.white,
size: 23,
),
),
),
child: (getAllApi)
? (errorMessage == null)
? Container(
width: 60,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: ColorManager.primary,
),
child: const Center(
child: Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.white,
size: 23,
),
),
)
: Text(
errorMessage!,
style: getSemiBoldStyle(
color: Colors.black,
fontSize: 16,
),
textAlign: TextAlign.center,
)
: CircularProgressIndicator(
color: ColorManager.primary,
),
),
),
),
......
......@@ -24,14 +24,24 @@ class RouteGenerator {
return pageRouteCustom(const OnBoardingView(),
nameRoute: Routes.onBoarding);
case Routes.home:
return pageRouteCustom(HomeView(), nameRoute: Routes.home);
HomeArguments args = routeSettings.arguments as HomeArguments;
return pageRouteCustom(
HomeView(
nearestBranch: args.branchModel,
shiftList: args.shiftModel,
),
nameRoute: Routes.home,
routeSettings: routeSettings,
);
case Routes.absentCamera:
AbsentCameraArguments args =
routeSettings.arguments as AbsentCameraArguments;
return pageRouteCustom(
AbsentCameraView(
outletName: args.outletName,
isIn: args.isIn,
branchModel: args.branchModel,
shiftModel: args.shiftModel,
),
nameRoute: Routes.absentCamera,
routeSettings: routeSettings,
......@@ -72,8 +82,9 @@ class RouteGenerator {
routeSettings!.arguments as AbsentCameraArguments;
return PageRouteBuilder(
pageBuilder: (context, a, b) => AbsentCameraView(
outletName: args.outletName,
isIn: args.isIn,
branchModel: args.branchModel,
shiftModel: args.shiftModel,
),
transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero,
......@@ -94,6 +105,20 @@ class RouteGenerator {
// name: nameRoute.replaceFirst("/", ""), arguments: args),
);
}
if (nameRoute == Routes.home) {
HomeArguments args = routeSettings!.arguments as HomeArguments;
return PageRouteBuilder(
pageBuilder: (context, a, b) => HomeView(
nearestBranch: args.branchModel,
shiftList: args.shiftModel,
),
transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero,
// settings: RouteSettings(
// name: nameRoute.replaceFirst("/", ""), arguments: args),
);
}
// else if (nameRoute == Routes.errorWidget) {
// ErrorWidgetArguments args =
// routeSettings!.arguments as ErrorWidgetArguments;
......
......@@ -3,4 +3,8 @@ class Strings {
"Silakan aktifkan permission kamera pada pengaturan browser anda";
static String locationNotActive =
"Silakan aktifkan permission lokasi pada pengaturan browser anda";
static String noOutletArround =
"Tidak ada outlet yang ditemukan dalam radius 10Km";
static String errorGetShiftList =
"Tidak dapat terhubung ke server, shift tidak ditemukan";
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment