2021-08-27 19:24:30 +02:00
import ' dart:convert ' ;
import ' package:flutter/cupertino.dart ' ;
import ' package:http/http.dart ' as http ;
import ' package:flutter/material.dart ' ;
import ' package:shared_preferences/shared_preferences.dart ' ;
2021-09-14 20:55:58 +02:00
import ' timetable.dart ' ;
import ' login.dart ' ;
import ' main.dart ' ;
2021-08-27 19:24:30 +02:00
2021-09-14 20:55:58 +02:00
Future < http . Response > getToken (
2021-08-27 19:24:30 +02:00
String user , String password , String otp , String devId ) async {
2021-08-31 17:49:57 +02:00
var uri = Uri . https ( " mein.cantorgymnasium.de " , " /login " ) ;
2021-08-27 19:24:30 +02:00
String body =
' {"user":" $ user ", "password": " $ password ", "otp": " $ otp ", "devid": " $ devId "} ' ;
print ( uri ) ;
final response = await http . post ( uri , body: body ) ;
2021-09-14 20:55:58 +02:00
return ( response ) ;
2021-08-27 19:24:30 +02:00
}
Future < String > getUserInfo (
String user , String password , String otp , String devId ) async {
2021-08-31 17:49:57 +02:00
var uri = Uri . https ( " mein.cantorgymnasium.de " , " /api/userinfo " ) ;
2021-08-27 19:24:30 +02:00
String body =
' {"user":" $ user ", "password": " $ password ", "otp": " $ otp ", "devid": " $ devId "} ' ;
print ( uri ) ;
final response = await http . post ( uri , body: body ) ;
if ( response . statusCode = = 200 ) {
return utf8 . decode ( response . bodyBytes ) ;
} else {
throw Exception ( ' Failed to log in ' ) ;
}
}
Future < http . Response > fetchClassTimetable ( ) async {
SharedPreferences prefs = await SharedPreferences . getInstance ( ) ;
2021-09-14 20:55:58 +02:00
String classNum ;
2021-08-27 19:24:30 +02:00
print ( prefs . getString ( ' class_num ' ) ) ;
if ( prefs . getString ( ' class_num ' ) ! = null ) {
2021-09-14 20:55:58 +02:00
classNum = prefs . getString ( ' class_num ' ) ! . replaceAll ( " / " , " _ " ) ;
2021-08-27 19:24:30 +02:00
} else {
2021-09-14 20:55:58 +02:00
classNum = ' 05_1 ' ;
2021-08-27 19:24:30 +02:00
}
2021-09-14 20:55:58 +02:00
var apiKey = prefs . getString ( ' api_key ' ) ;
var uri = Uri . https ( " mein.cantorgymnasium.de " , " /api/timetable/ $ classNum " ) ;
var headers = { " x-api-key " : " $ apiKey " } ;
2021-08-27 19:24:30 +02:00
print ( uri ) ;
2021-09-14 20:55:58 +02:00
final response = http . get ( uri , headers: headers ) . onError ( ( error , stackTrace ) { return ( http . Response ( " " , 404 ) ) ; } ) ;
return response ;
}
Future < http . Response > fetchTodayClassTimetable ( ) async {
SharedPreferences prefs = await SharedPreferences . getInstance ( ) ;
String classNum ;
print ( prefs . getString ( ' class_num ' ) ) ;
if ( prefs . getString ( ' class_num ' ) ! = null ) {
classNum = prefs . getString ( ' class_num ' ) ! . replaceAll ( " / " , " _ " ) ;
} else {
classNum = ' 05_1 ' ;
}
var apiKey = prefs . getString ( ' api_key ' ) ;
var uri =
Uri . https ( " mein.cantorgymnasium.de " , " /api/timetable/ $ classNum /today " ) ;
var headers = { " x-api-key " : " $ apiKey " } ;
print ( uri ) ;
final response = http . get ( uri , headers: headers ) . onError ( ( error , stackTrace ) { return ( http . Response ( " " , 404 ) ) ; } ) ;
2021-08-27 19:24:30 +02:00
return response ;
}
Widget buildClassTimetable ( ) {
return FutureBuilder < http . Response > (
future: fetchClassTimetable ( ) ,
builder: ( context , snapshot ) {
if ( snapshot . hasData ) {
int statusCode = snapshot . data ! . statusCode ;
if ( statusCode = = 200 ) {
ListView timetableView = ClassTimetableBuilder . buildView (
jsonDecode ( utf8 . decode ( snapshot . data ! . bodyBytes ) ) )
. view ;
return timetableView ;
2021-09-14 20:55:58 +02:00
} else if ( statusCode = = 400 ) {
Navigator . pushReplacement (
context , MaterialPageRoute ( builder: ( context ) = > Login ( ) ) ) ;
} else if ( statusCode = = 500 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Es konnte kein Vertretungsplan gefunden werden. " ) ) ,
) ;
} else if ( statusCode = = 404 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Keine Verbindung mit dem MeinCantor-Server möglich. Bitte prüfe deine Internetverbindung und deine DNS-Einstellungen oder wende dich an den MeinCantor-Support. " ) ) ,
) ;
2021-08-27 19:24:30 +02:00
}
2021-09-14 20:55:58 +02:00
return Center ( child: Text ( ' Error $ statusCode ' ) ) ;
} else if ( snapshot . hasError ) {
return Text ( ' $ snapshot .error ' ) ;
} else {
return const Center ( child: CircularProgressIndicator ( ) ) ;
}
} ,
) ;
}
Widget buildTodayClassTimetable ( ) {
return FutureBuilder < http . Response > (
future: fetchTodayClassTimetable ( ) ,
builder: ( context , snapshot ) {
if ( snapshot . hasData ) {
int statusCode = snapshot . data ! . statusCode ;
if ( statusCode = = 200 ) {
ListView timetableView = ClassTimetableBuilder . buildView (
jsonDecode ( utf8 . decode ( snapshot . data ! . bodyBytes ) ) )
. view ;
return timetableView ;
} else if ( statusCode = = 400 ) {
Navigator . push (
context , MaterialPageRoute ( builder: ( context ) = > Login ( ) ) ) ;
} else if ( statusCode = = 500 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Es konnte kein Vertretungsplan für heute gefunden werden. " ) ) ,
) ;
} else if ( statusCode = = 404 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Keine Verbindung mit dem MeinCantor-Server möglich. Bitte prüfe deine Internetverbindung und deine DNS-Einstellungen oder wende dich an den MeinCantor-Support. " ) ) ,
) ;
2021-08-27 19:24:30 +02:00
}
return Center ( child: Text ( ' Error $ statusCode ' ) ) ;
} else if ( snapshot . hasError ) {
return Text ( ' $ snapshot .error ' ) ;
} else {
2021-09-14 20:55:58 +02:00
return const Center ( child: CircularProgressIndicator ( ) ) ;
}
} ,
) ;
}
Widget buildClassTimetableLesson ( int count ) {
return FutureBuilder < http . Response > (
future: fetchClassTimetable ( ) ,
builder: ( context , snapshot ) {
if ( snapshot . hasData ) {
int statusCode = snapshot . data ! . statusCode ;
if ( statusCode = = 200 ) {
List < Widget > lessons = LessonsListBuilder . buildList (
jsonDecode ( utf8 . decode ( snapshot . data ! . bodyBytes ) ) , count: count )
. lessons ;
return Column ( children: lessons ) ;
} else if ( statusCode = = 400 ) {
Navigator . push (
context , MaterialPageRoute ( builder: ( context ) = > Login ( ) ) ) ;
} else if ( statusCode = = 500 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Es konnte kein Vertretungsplan gefunden werden. " ) ) ,
) ;
} else if ( statusCode = = 404 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Keine Verbindung mit dem MeinCantor-Server möglich. Bitte prüfe deine Internetverbindung und deine DNS-Einstellungen oder wende dich an den MeinCantor-Support " ) ) ,
) ;
}
return Center ( child: Text ( ' Error $ statusCode ' ) ) ;
} else if ( snapshot . hasError ) {
return Text ( ' $ snapshot .error ' ) ;
} else {
return const Center ( child: CircularProgressIndicator ( ) ) ;
}
} ,
) ;
}
Widget buildTodayClassTimetableLesson ( int count ) {
return FutureBuilder < http . Response > (
future: fetchTodayClassTimetable ( ) ,
builder: ( context , snapshot ) {
if ( snapshot . hasData ) {
int statusCode = snapshot . data ! . statusCode ;
if ( statusCode = = 200 ) {
List < Widget > lessons = LessonsListBuilder . buildList (
jsonDecode ( utf8 . decode ( snapshot . data ! . bodyBytes ) ) , count: count )
. lessons ;
if ( lessons . isNotEmpty ) {
return Column ( children: lessons ) ;
} else {
var chars = Runes ( ' Keine Stunden mehr gefunden. Sieht so aus als hättest du Schluss für heute \u{1F389} ' ) ;
List < Widget > cardChildren = [ ] ;
cardChildren . add ( ListTile (
title: Text ( String . fromCharCodes ( chars ) ,
style: const TextStyle ( color: Palette . primary ) )
) ) ;
Card card = Card (
shape: RoundedRectangleBorder (
borderRadius: BorderRadius . circular ( 15.0 ) ,
) ,
color: Colors . white ,
child: Column (
children: cardChildren ,
) ) ;
return card ;
}
} else if ( statusCode = = 400 ) {
Navigator . push (
context , MaterialPageRoute ( builder: ( context ) = > Login ( ) ) ) ;
} else if ( statusCode = = 500 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Es konnte kein Vertretungsplan für heute gefunden werden. " ) ) ,
) ;
} else if ( statusCode = = 404 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Keine Verbindung mit dem MeinCantor-Server möglich. Bitte prüfe deine Internetverbindung und deine DNS-Einstellungen oder wende dich an den MeinCantor-Support " ) ) ,
) ;
}
return Center ( child: Text ( ' Error $ statusCode ' ) ) ;
} else if ( snapshot . hasError ) {
return Text ( ' $ snapshot .error ' ) ;
} else {
return const Center ( child: CircularProgressIndicator ( ) ) ;
2021-08-27 19:24:30 +02:00
}
} ,
) ;
}
Future < http . Response > fetchClassesList ( ) async {
SharedPreferences prefs = await SharedPreferences . getInstance ( ) ;
2021-09-14 20:55:58 +02:00
var apiKey = prefs . getString ( ' api_key ' ) ;
2021-08-27 19:24:30 +02:00
var uri = Uri . https ( " mein.cantorgymnasium.de " , " /api/classes " ) ;
2021-09-14 20:55:58 +02:00
var headers = { " x-api-key " : " $ apiKey " } ;
2021-08-27 19:24:30 +02:00
print ( uri ) ;
2021-09-14 20:55:58 +02:00
final response = http . get ( uri , headers: headers ) . onError ( ( error , stackTrace ) { return ( http . Response ( " " , 404 ) ) ; } ) ;
2021-08-27 19:24:30 +02:00
return response ;
}
Widget buildClassesChooser ( ) {
return FutureBuilder < http . Response > (
future: fetchClassesList ( ) ,
builder: ( context , snapshot ) {
if ( snapshot . hasData ) {
int statusCode = snapshot . data ! . statusCode ;
if ( statusCode = = 200 ) {
List < String > items = [ ] ;
jsonDecode ( utf8 . decode ( snapshot . data ! . bodyBytes ) ) . forEach ( ( value ) {
items . add ( value . . toString ( ) ) ;
} ) ;
return ClassesChooser ( items: items ) ;
2021-09-14 20:55:58 +02:00
} else if ( statusCode = = 400 ) {
Navigator . push (
context , MaterialPageRoute ( builder: ( context ) = > Login ( ) ) ) ;
} else if ( statusCode = = 500 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Serverfehler. Bitte wende dich an den MeinCantor-Support. " ) ) ,
) ;
} else if ( statusCode = = 404 ) {
return const Padding (
padding: EdgeInsets . fromLTRB ( 10 , 10 , 10 , 10 ) ,
child: Center ( child: Text ( " Keine Verbindung mit dem MeinCantor-Server möglich. Bitte prüfe deine Internetverbindung und deine DNS-Einstellungen oder wende dich an den MeinCantor-Support " ) ) ,
) ;
2021-08-27 19:24:30 +02:00
}
return Text ( ' $ statusCode ' ) ;
} else if ( snapshot . hasError ) {
return Text ( ' $ snapshot .error ' ) ;
} else {
2021-09-14 20:55:58 +02:00
return const Center ( child: CircularProgressIndicator ( ) ) ;
2021-08-27 19:24:30 +02:00
}
} ,
) ;
}
class ClassesChooser extends StatefulWidget {
final List < String > items ;
const ClassesChooser ( { Key ? key , required this . items } ) : super ( key: key ) ;
@ override
State < ClassesChooser > createState ( ) = > _ClassesChooserState ( items ) ;
}
class _ClassesChooserState extends State < ClassesChooser > {
final List < String > items ;
//final String dropdownValue;
2021-09-14 20:55:58 +02:00
String ? dropdownValue ;
2021-08-27 19:24:30 +02:00
_ClassesChooserState ( this . items ) ;
2021-09-14 20:55:58 +02:00
@ override
void initState ( ) {
super . initState ( ) ;
_read ( ) ; // read in initState
}
_read ( ) async {
SharedPreferences prefs = await SharedPreferences . getInstance ( ) ;
setState ( ( ) {
dropdownValue = prefs . getString ( " class_num " ) ; // get the value
} ) ;
}
2021-08-27 19:24:30 +02:00
@ override
Widget build ( BuildContext context ) {
return DropdownButtonFormField < String > (
2021-09-14 20:55:58 +02:00
value: dropdownValue ,
decoration: const InputDecoration (
2021-08-27 19:24:30 +02:00
icon: Icon ( CupertinoIcons . number ) ,
border: OutlineInputBorder ( ) ,
2021-09-14 20:55:58 +02:00
labelText: ' Klasse (05/1, 07/3, 10/2...) ' ,
2021-08-27 19:24:30 +02:00
) ,
onChanged: ( String ? newValue ) {
setState ( ( ) async {
dropdownValue = newValue ! ;
SharedPreferences prefs = await SharedPreferences . getInstance ( ) ;
2021-09-14 20:55:58 +02:00
String classNum = newValue ;
print ( ' Set new class to $ classNum ' ) ;
await prefs . setString ( ' class_num ' , classNum ) ;
2021-08-27 19:24:30 +02:00
} ) ;
} ,
items: items . map < DropdownMenuItem < String > > ( ( String value ) {
return DropdownMenuItem < String > (
value: value ,
child: Text ( value ) ,
) ;
} ) . toList ( ) ,
) ;
}
}