init
This commit is contained in:
116
lib/backend/DataManager.dart
Normal file
116
lib/backend/DataManager.dart
Normal file
@@ -0,0 +1,116 @@
|
||||
import 'dart:convert';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:queue_client/backend/DebugHelper.dart';
|
||||
// DateFormat dateFormat;
|
||||
|
||||
final String API_ENDPOINT= "https://vps.playpoolstudios.com/qms/api/";
|
||||
|
||||
final dateTimeFormat = DateFormat("yyyy-MM-dd hh:mm");
|
||||
|
||||
class DataManager{
|
||||
static _DataManager? m_instance = null;
|
||||
static _DataManager instance(){
|
||||
m_instance ??= _DataManager();
|
||||
return m_instance!;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class _DataManager{
|
||||
_DataManager();
|
||||
|
||||
List<dynamic> services = [];
|
||||
List<Map<String, dynamic>> AvailableServices = [];
|
||||
List<Map<String, dynamic>> JoinedServices = [];
|
||||
|
||||
int userId = -1;
|
||||
|
||||
Future<String> Login(String username,String password) async{
|
||||
String responseTxt = "";
|
||||
try{
|
||||
var response = (await http.post(
|
||||
Uri.parse('${API_ENDPOINT}login.php'),
|
||||
body: <String, String>{
|
||||
'username':username,
|
||||
'password':password
|
||||
}));
|
||||
responseTxt = response.body.toString();
|
||||
int result = int.parse(response.body.toString());
|
||||
userId = result;
|
||||
return "0";
|
||||
}catch(e){
|
||||
Debug.LogError(e);
|
||||
return responseTxt;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> GetData() async{
|
||||
try{
|
||||
var response = (await http.post(
|
||||
Uri.parse('${API_ENDPOINT}get_services.php'),
|
||||
body: <String, String>{}));
|
||||
Debug.LogResponse(response.body.toString());
|
||||
services = jsonDecode(response.body.toString());
|
||||
Debug.LogResponse(services);
|
||||
}catch(e){
|
||||
Debug.LogError(e);
|
||||
}
|
||||
|
||||
ProcessServices();
|
||||
}
|
||||
|
||||
void ProcessServices(){
|
||||
AvailableServices=[];
|
||||
JoinedServices=[];
|
||||
for (var m_service in services) {
|
||||
Map<String,dynamic> service= jsonDecode(m_service);
|
||||
List<String> members = service['members'].toString().split(',');
|
||||
|
||||
if(members.contains(userId.toString())){
|
||||
int tokenId = 0;
|
||||
for(int i=0;i<members.length; i++){
|
||||
if(members[i] == userId.toString()){
|
||||
tokenId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
service.putIfAbsent("tokenId", () => tokenId);
|
||||
JoinedServices.add(service);
|
||||
}else{
|
||||
AvailableServices.add(service);
|
||||
}
|
||||
|
||||
m_service = jsonEncode(service);
|
||||
}
|
||||
}
|
||||
|
||||
dynamic GetServiceFromID(int id){
|
||||
for (var service in services) {
|
||||
Map<String, dynamic> serviceData = jsonDecode(service);
|
||||
if(serviceData['id']==id.toString()){
|
||||
return serviceData;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> JoinService(int id) async {
|
||||
try{
|
||||
var response = (await http.post(
|
||||
Uri.parse('${API_ENDPOINT}join_service.php'),
|
||||
body: <String, String>{
|
||||
'service_id':id.toString(),
|
||||
'user_id':userId.toString(),
|
||||
}));
|
||||
Debug.LogResponse(response.body.toString());
|
||||
services = jsonDecode(response.body.toString());
|
||||
Debug.LogResponse(services);
|
||||
}catch(e){
|
||||
Debug.LogError(e);
|
||||
}
|
||||
|
||||
ProcessServices();
|
||||
}
|
||||
}
|
||||
32
lib/backend/DebugHelper.dart
Normal file
32
lib/backend/DebugHelper.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
import 'dart:developer';
|
||||
|
||||
class Debug{
|
||||
static bool enableLogging = true;
|
||||
static bool enableResponseLogging = true;
|
||||
static bool enableErrorLoggin = true;
|
||||
static bool enableTestLogging = true;
|
||||
|
||||
static void LogResponse(Object? response, {Object src= ''}){
|
||||
if(!enableLogging){return;}
|
||||
if(!enableResponseLogging) {return;}
|
||||
print('\x1B[32m$src response\n$response\x1B[0m');
|
||||
}
|
||||
|
||||
static void LogError(Object? msg){
|
||||
if(!enableLogging){return;}
|
||||
if(!enableErrorLoggin) {return;}
|
||||
print('\x1B[31m$msg\x1B[0m');
|
||||
}
|
||||
|
||||
static void Log(Object? msg){
|
||||
if(!enableLogging) {return;}
|
||||
print('\x1B[36m$msg\x1B[0m');
|
||||
}
|
||||
|
||||
static void LogTest(Object? msg){
|
||||
if(!enableLogging){return;}
|
||||
if(!enableTestLogging) {return;}
|
||||
print('\x1B[35m$msg\x1B[0m');
|
||||
}
|
||||
|
||||
}
|
||||
76
lib/backend/Dialogs.dart
Normal file
76
lib/backend/Dialogs.dart
Normal file
@@ -0,0 +1,76 @@
|
||||
// import 'package:fhub/backend/login_mgr.dart';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
// import 'package:shared_preferences/shared_preferences.dart';
|
||||
// import 'package:url_launcher/url_launcher.dart';
|
||||
import '../main.dart';
|
||||
|
||||
class Dialogs{
|
||||
|
||||
static showAlertDialog(BuildContext context, String title, String message) {
|
||||
// set up the button
|
||||
Widget okButton = TextButton(
|
||||
child: Text("OK"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
);
|
||||
|
||||
// set up the AlertDialog
|
||||
AlertDialog alert = AlertDialog(
|
||||
backgroundColor: Color(0xFF1F1F1F),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(40)),
|
||||
title: Text(title,textAlign: TextAlign.center,),
|
||||
content: Text(message,textAlign: TextAlign.center,),
|
||||
actions: [
|
||||
okButton,
|
||||
],
|
||||
|
||||
);
|
||||
|
||||
// show the dialog
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return alert;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static bool showing = false;
|
||||
static BuildContext? context;
|
||||
static waiting(){
|
||||
showing=true;
|
||||
// context=navigatorKey.currentContext;
|
||||
if(context!=null) {
|
||||
return showDialog(
|
||||
context: context!,
|
||||
barrierDismissible: false,
|
||||
routeSettings: const RouteSettings(name: "Progress"),
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
|
||||
backgroundColor: Color(0xaa101010),
|
||||
title: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// SpinKitChasingDots(color: Colors.green),
|
||||
Expanded(child: Text("Loading",textAlign: TextAlign.center,)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
// static hide(){
|
||||
// showing=false;
|
||||
// Navigator.of(navigatorKey.currentContext!).popUntil((route){
|
||||
// return route.settings.name!="Progress";
|
||||
// });
|
||||
// }
|
||||
|
||||
}
|
||||
93
lib/home.dart
Normal file
93
lib/home.dart
Normal file
@@ -0,0 +1,93 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:queue_client/backend/DataManager.dart';
|
||||
import 'package:queue_client/service_info.dart';
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
const HomePage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<HomePage> createState() => _HomePageState();
|
||||
}
|
||||
|
||||
class _HomePageState extends State<HomePage> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void refresh()async{
|
||||
await DataManager.instance().GetData();
|
||||
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("Queue Helper"),
|
||||
),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Joined"),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: DataManager.instance().JoinedServices.length,
|
||||
itemBuilder: (context, index){
|
||||
// Map<String,dynamic> service= jsonDecode(DataManager.instance().services[index]);
|
||||
Map<String,dynamic> service= DataManager.instance().JoinedServices[index];
|
||||
return ServiceCard(tokenId:service['tokenId'],id: int.parse(service['id']),sTime: DateTime.parse(service['start_time'] ?? DateTime.now().toString()), name: service['name']!, memberCount: service['members']!.split(',').length-1);
|
||||
}),
|
||||
SizedBox(height:50),
|
||||
Text("Available"),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: DataManager.instance().AvailableServices.length,
|
||||
itemBuilder: (context, index){
|
||||
// Map<String,dynamic> service= jsonDecode(DataManager.instance().services[index]);
|
||||
Map<String,dynamic> service= DataManager.instance().AvailableServices[index];
|
||||
return ServiceCard(tokenId: -1,id: int.parse(service['id']),sTime: DateTime.parse(service['start_time'] ?? DateTime.now().toString()), name: service['name']!, memberCount: service['members']!.split(',').length-1);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget ServiceCard(
|
||||
{required int id, required DateTime sTime,
|
||||
required String name,
|
||||
required int memberCount, required int tokenId}) {
|
||||
return InkWell(
|
||||
onTap: () async{
|
||||
await Navigator.of(context).push(MaterialPageRoute(builder: (context)=> ServiceInfoPage(id: id,tokenId: tokenId,)));
|
||||
setState(() {
|
||||
|
||||
});
|
||||
},
|
||||
child: Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("${sTime.year}-${sTime.month}-${sTime.day}"),
|
||||
Text(name),
|
||||
Container(width: 25,height: 25,decoration: BoxDecoration(borderRadius: BorderRadius.circular(50),color: Colors.deepPurple),child: Center(child: Text(memberCount.toString()),),)
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
51
lib/login.dart
Normal file
51
lib/login.dart
Normal file
@@ -0,0 +1,51 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:queue_client/backend/DataManager.dart';
|
||||
import 'package:queue_client/backend/Dialogs.dart';
|
||||
import 'package:queue_client/home.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
const LoginPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<LoginPage> createState() => _LoginPageState();
|
||||
}
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
TextEditingController usernameController = TextEditingController();
|
||||
TextEditingController passwordController = TextEditingController();
|
||||
bool logging = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Card(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text("Login"),
|
||||
SizedBox(height: 30,),
|
||||
ListTile(title: Text("Phone Number"),
|
||||
subtitle: TextField(controller: usernameController),),
|
||||
|
||||
ElevatedButton(onPressed: () async{
|
||||
setState(() {
|
||||
logging=true;
|
||||
});
|
||||
String results = await DataManager.instance().Login(usernameController.text, passwordController.text);
|
||||
if(results == "0"){
|
||||
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=>HomePage()));
|
||||
}else{
|
||||
Dialogs.showAlertDialog(context, "Failed login", results);
|
||||
}
|
||||
}, child: Text("Continue"))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
24
lib/main.dart
Normal file
24
lib/main.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:queue_client/home.dart';
|
||||
import 'package:queue_client/login.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple,brightness: Brightness.dark),
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: const LoginPage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
65
lib/service_info.dart
Normal file
65
lib/service_info.dart
Normal file
@@ -0,0 +1,65 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:queue_client/backend/DataManager.dart';
|
||||
import 'package:queue_client/backend/DebugHelper.dart';
|
||||
import 'package:queue_client/home.dart';
|
||||
|
||||
class ServiceInfoPage extends StatefulWidget {
|
||||
ServiceInfoPage({Key? key,required this.id, required this.tokenId}) : super(key: key);
|
||||
int id;
|
||||
int tokenId;
|
||||
@override
|
||||
State<ServiceInfoPage> createState() => _ServiceInfoPageState();
|
||||
}
|
||||
|
||||
class _ServiceInfoPageState extends State<ServiceInfoPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Map<String,dynamic> service = DataManager.instance().GetServiceFromID(widget.id);
|
||||
int hours = int.parse(service['duration'].toString().split(":")[0]);
|
||||
int mins = int.parse(service['duration'].toString().split(":")[1]);
|
||||
DateTime eta = DateTime.parse(service['start_time']).add(Duration(hours: hours, minutes: mins) * widget.tokenId);
|
||||
|
||||
Debug.Log(service);
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(service['name']),),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(children: [
|
||||
Text("Starting Time : "),
|
||||
Text(dateTimeFormat.format(DateTime.parse(service['start_time'])))
|
||||
],),
|
||||
Row(children: [
|
||||
Text("Ending Time : "),
|
||||
Text(dateTimeFormat.format(DateTime.parse(service['end_time'])))
|
||||
],),
|
||||
Row(children: [
|
||||
Text("Session Duration : "),
|
||||
Text(service['duration'])
|
||||
],),
|
||||
Row(children: [
|
||||
Text("Participants : "),
|
||||
Text((service['members'].toString().split(',').length-1).toString()),
|
||||
],),
|
||||
SizedBox(height: 20,),
|
||||
widget.tokenId > 0 ?Column(
|
||||
children: [
|
||||
Text("Already Joined"),
|
||||
SizedBox(height: 20,),
|
||||
Text("Token Id : ${widget.tokenId}"),
|
||||
Text("ETA : ${dateTimeFormat.format(eta)}")
|
||||
],
|
||||
) :ElevatedButton(onPressed: () async{
|
||||
await DataManager.instance().JoinService(widget.id);
|
||||
setState(() {
|
||||
|
||||
});
|
||||
Navigator.of(context).pop();
|
||||
}, child: Text("Join"))
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user