==0.6.5==
- added A LOT, TLTD - TODO: - update README - update license & copyright info - cleanup code - merge code parts to server side - add more settings - fix 11/12 - add more timetable options - add timetable additional info - muuuuuuuch more...
This commit is contained in:
parent
75e8c9ea2c
commit
bae624dd67
@ -1,414 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'Settings.dart';
|
|
||||||
import 'networking.dart';
|
|
||||||
import 'Login.dart';
|
|
||||||
|
|
||||||
class Dashboard extends StatefulWidget {
|
|
||||||
const Dashboard({
|
|
||||||
Key? key,
|
|
||||||
this.restorationId
|
|
||||||
}): super(key: key);
|
|
||||||
|
|
||||||
final String? restorationId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() => _DashboardState();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> getSettingsString(String key) async {
|
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
||||||
String? value = await prefs.getString(key);
|
|
||||||
if(value == null || value.isEmpty) {
|
|
||||||
value = "";
|
|
||||||
}
|
|
||||||
print(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildSettingsString(String key, TextStyle style) {
|
|
||||||
return FutureBuilder(
|
|
||||||
future: getSettingsString(key),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if(snapshot.hasData) {
|
|
||||||
return Text(snapshot.data as String, style: style);
|
|
||||||
} else {
|
|
||||||
return(Center(child: CircularProgressIndicator()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DashboardState extends State<Dashboard> with RestorationMixin {
|
|
||||||
final RestorableInt _currentIndex = RestorableInt(0);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final drawerElements = ListView(
|
|
||||||
children: [
|
|
||||||
UserAccountsDrawerHeader(
|
|
||||||
accountName: buildSettingsString('name', TextStyle()),
|
|
||||||
accountEmail: buildSettingsString('user', TextStyle()),
|
|
||||||
currentAccountPicture: const CircularProgressIndicator(backgroundColor: Colors.black,),
|
|
||||||
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text("Einstellungen"),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => Settings()),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
leading: Icon(CupertinoIcons.settings),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text("Abmelden"),
|
|
||||||
onTap: () async {
|
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
||||||
prefs.setString('api_key', "");
|
|
||||||
Navigator.pushReplacement(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => Login()),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
leading: Icon(Icons.exit_to_app_outlined),
|
|
||||||
),
|
|
||||||
AboutListTile(
|
|
||||||
child: Text("Info"),
|
|
||||||
icon: Icon(CupertinoIcons.info),
|
|
||||||
applicationVersion: "0.5.0-alpha1",
|
|
||||||
applicationIcon: Image.asset("assets/images/meincantor_r.png", height: 64, width: 64),
|
|
||||||
applicationName: "MeinCantor",
|
|
||||||
aboutBoxChildren: [
|
|
||||||
Text("MeinCantor ist die Schulplatform für Schüler des Georg-Cantor-Gymnasiums in Halle (Saale)."),
|
|
||||||
Divider(),
|
|
||||||
Text("Copyright © 2021 Denys Konovalov")
|
|
||||||
],
|
|
||||||
// applicationIcon: Image.,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
var bottomNavBarItems = [
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: const Icon(CupertinoIcons.home),
|
|
||||||
label: "Startseite",
|
|
||||||
),
|
|
||||||
BottomNavigationBarItem(icon: const Icon(CupertinoIcons.rectangle_grid_1x2), label: "Vertretungsplan"),
|
|
||||||
];
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: Text("GCG.MeinCantor"),
|
|
||||||
centerTitle: true,
|
|
||||||
),
|
|
||||||
body: _DashboardBottomNavView(
|
|
||||||
key: UniqueKey(),
|
|
||||||
item: bottomNavBarItems[_currentIndex.value]
|
|
||||||
),
|
|
||||||
drawer: Drawer(
|
|
||||||
child: drawerElements,
|
|
||||||
),
|
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
|
||||||
showUnselectedLabels: false,
|
|
||||||
items: bottomNavBarItems,
|
|
||||||
currentIndex: _currentIndex.value,
|
|
||||||
onTap: (index) {
|
|
||||||
setState(() {
|
|
||||||
_currentIndex.value = index;
|
|
||||||
});
|
|
||||||
//print(index);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String? get restorationId => widget.restorationId;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
|
||||||
registerForRestoration(_currentIndex, 'bottom_navigation_tab_index');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DashboardBottomNavView extends StatelessWidget {
|
|
||||||
_DashboardBottomNavView({
|
|
||||||
Key? key,
|
|
||||||
required this.item
|
|
||||||
}) : super(key:key);
|
|
||||||
final BottomNavigationBarItem item;
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return materialCard(item.label);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget materialCard(String? label) {
|
|
||||||
if (label == "Startseite") {
|
|
||||||
var view = SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(20, 30, 20, 5),
|
|
||||||
child: Text(
|
|
||||||
'Hallo,',
|
|
||||||
style: GoogleFonts.robotoSlab(
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(20, 5, 20, 20),
|
|
||||||
child: buildSettingsString("name", GoogleFonts.robotoSlab(
|
|
||||||
fontSize: 28,
|
|
||||||
fontWeight: FontWeight.w800,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(20, 10, 0, 10),
|
|
||||||
child: Text(
|
|
||||||
'Deine nächste Unterrichtsstunde:',
|
|
||||||
style: GoogleFonts.robotoSlab(
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.w100,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(20, 20, 20, 10),
|
|
||||||
child: Card(
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(15.0),
|
|
||||||
),
|
|
||||||
color: Colors.red,
|
|
||||||
child: Column(
|
|
||||||
children: [ListTile(
|
|
||||||
title: Text('3' + '.' + ' ' + 'Deutsch', style: TextStyle(color: Colors.white)),
|
|
||||||
subtitle: Row(
|
|
||||||
children: [Icon(CupertinoIcons.person, color: Colors.white), SizedBox(width: 5), Text("Herr Jünemann", style: TextStyle(color: Colors.white)), Spacer(), Icon(CupertinoIcons.home, color: Colors.white), SizedBox(width: 5), Text("106", style: TextStyle(color: Colors.white))]
|
|
||||||
),
|
|
||||||
leading:
|
|
||||||
Icon(CupertinoIcons.time, color: Colors.white)
|
|
||||||
)],
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(20, 20, 20, 10),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Card(
|
|
||||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding:
|
|
||||||
EdgeInsets.fromLTRB(20, 20, 10, 10),
|
|
||||||
child: Icon(
|
|
||||||
CupertinoIcons.news,
|
|
||||||
color: Color(0xFFFFBC3B),
|
|
||||||
size: 48,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Align(
|
|
||||||
alignment: Alignment(0, 0),
|
|
||||||
child: Padding(
|
|
||||||
padding:
|
|
||||||
EdgeInsets.fromLTRB(15, 50, 0, 15),
|
|
||||||
child: Text(
|
|
||||||
'Schülerzeitung',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Card(
|
|
||||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding:
|
|
||||||
EdgeInsets.fromLTRB(20, 20, 10, 10),
|
|
||||||
child: Icon(
|
|
||||||
CupertinoIcons.book,
|
|
||||||
color: Color(0xFFFFBC3B),
|
|
||||||
size: 48,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
|
|
||||||
child: Text(
|
|
||||||
'Schulbibliothek',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Card(
|
|
||||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding:
|
|
||||||
EdgeInsets.fromLTRB(20, 20, 10, 10),
|
|
||||||
child: Icon(
|
|
||||||
CupertinoIcons.device_laptop,
|
|
||||||
color: Color(0xFFFFBC3B),
|
|
||||||
size: 48,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
|
|
||||||
child: Text(
|
|
||||||
'Schulcomputer',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Card(
|
|
||||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding:
|
|
||||||
EdgeInsets.fromLTRB(20, 20, 10, 10),
|
|
||||||
child: Icon(
|
|
||||||
CupertinoIcons.house_alt,
|
|
||||||
color: Color(0xFFFFBC3B),
|
|
||||||
size: 48,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
|
|
||||||
child: Text(
|
|
||||||
'Raumübersicht',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return view;
|
|
||||||
} else if (label == "Vertretungsplan") {
|
|
||||||
return LayoutBuilder(
|
|
||||||
builder: (context, constraints) {
|
|
||||||
double widgetWidth = constraints.maxWidth;
|
|
||||||
double widgetHeight = constraints.maxHeight;
|
|
||||||
var factor;
|
|
||||||
|
|
||||||
if (widgetWidth <= 600) {
|
|
||||||
factor = 1;
|
|
||||||
} else if (widgetWidth <= 1400) {
|
|
||||||
factor = 2;
|
|
||||||
} else if (widgetWidth <= 2000) {
|
|
||||||
factor = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// print(screenType);
|
|
||||||
return Center(
|
|
||||||
child: Container(
|
|
||||||
constraints: BoxConstraints(
|
|
||||||
// minHeight: 500, //minimum height
|
|
||||||
// minWidth: 300, // minimum width
|
|
||||||
//maximum height set to 100% of vertical height
|
|
||||||
maxWidth: MediaQuery.of(context).size.width / factor,
|
|
||||||
//maximum width set to 100% of width
|
|
||||||
),
|
|
||||||
child: buildClassTimetable(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Text("Such page does not exist.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'networking.dart';
|
|
||||||
|
|
||||||
class Settings extends StatelessWidget {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: Text("Einstellungen"),
|
|
||||||
),
|
|
||||||
body: ListView(
|
|
||||||
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
|
|
||||||
child: TextField(
|
|
||||||
decoration: InputDecoration(
|
|
||||||
icon: Icon(CupertinoIcons.lock),
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
labelText: 'API Key (POST /login)',
|
|
||||||
),
|
|
||||||
onSubmitted: (String value) async {
|
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
||||||
String api_key = value;
|
|
||||||
print('Set new API key to $api_key');
|
|
||||||
await prefs.setString('api_key', api_key);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Divider(),
|
|
||||||
buildClassesChooser()
|
|
||||||
],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,174 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
|
|
||||||
|
|
||||||
class ClassTimetableBuilder {
|
|
||||||
final ListView view;
|
|
||||||
ClassTimetableBuilder({required this.view});
|
|
||||||
factory ClassTimetableBuilder.buildView(Map<String, dynamic> json) {
|
|
||||||
List<Widget> children = [];
|
|
||||||
ClassTimetable.fromJson(json).timetable.forEach((element) {
|
|
||||||
List<Widget> cardChildren = [];
|
|
||||||
cardChildren.add(ListTile(
|
|
||||||
title: Text(element.count.toString() + '.' + ' ' + element.name,
|
|
||||||
style: TextStyle(color: element.fontColor)),
|
|
||||||
subtitle: Row(
|
|
||||||
children: [
|
|
||||||
Icon(CupertinoIcons.person, color: element.fontColor),
|
|
||||||
SizedBox(width: 5),
|
|
||||||
Text(element.teacher,
|
|
||||||
style: TextStyle(color: element.fontColor)),
|
|
||||||
Spacer(),
|
|
||||||
Icon(CupertinoIcons.home, color: element.fontColor),
|
|
||||||
SizedBox(width: 5),
|
|
||||||
Text(element.room, style: TextStyle(color: element.fontColor))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
leading:
|
|
||||||
Icon(CupertinoIcons.time, color: element.fontColor)
|
|
||||||
));
|
|
||||||
if (element.info != '') {
|
|
||||||
cardChildren.add(ListTile(title: Text(
|
|
||||||
element.info, style: TextStyle(color: element.fontColor))));
|
|
||||||
}
|
|
||||||
Card card = Card(
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(15.0),
|
|
||||||
),
|
|
||||||
color: element.color,
|
|
||||||
child: Column(
|
|
||||||
children: cardChildren,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
children.add(card);
|
|
||||||
});
|
|
||||||
return ClassTimetableBuilder(
|
|
||||||
view: ListView(
|
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
|
||||||
children: children
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ClassTimetable {
|
|
||||||
final List timetable;
|
|
||||||
ClassTimetable({required this.timetable});
|
|
||||||
factory ClassTimetable.fromJson(Map<String, dynamic> json){
|
|
||||||
print(json);
|
|
||||||
List<TimetableLesson> lessons = [];
|
|
||||||
json['courses'].forEach((value){
|
|
||||||
var color;
|
|
||||||
var name;
|
|
||||||
var teacher;
|
|
||||||
var room;
|
|
||||||
dynamic teachers = {'Poli':'Herr Polity', 'Zura':'Frau Zuralski', 'Enzi': 'Frau Enzian', 'Bütt':'Frau Büttner', 'Brod':'Herr Brode', 'Rink':'Frau Rinke', 'Schk':'Frau Schmidt', 'Rudo':'Frau Rudolph', 'Kipp':'Frau Kipping', 'Bach':'Frau Bachran', 'Bad':'Herr Bader', 'Prei':'Frau Preiß', 'Scha':'Frau Schapitz', ' ':'', 'Link':'Herr Linke', 'Stei':'Herr Stein', 'Tupp':'Frau Tuppack', 'Hoff':'Frau Hoffman', 'Knol':'Frau Knoll', 'Bet':'Frau Bethin', 'Schu':'Frau Schulz', 'Seid':'Frau Seidel', 'Krug':'Frau Krug', 'Laer':'Frau Langer', 'Youn':'Frau Younso', 'Härt':'Frau Härtig', 'Bros':'Frau Brosig', 'Ber':'Frau Bernhardt', 'Stüb':'Frau Stüber', 'Bor':'Frau Borchert', 'Dubb':'Frau Dubberstein', 'Tren':'Frau Trentsch', 'Meit':'Herr Meitzner', 'Stol':'Frau Stolpe', 'Jac':'Frau Jacob', 'Jüne':'Herr Jünemann', 'Bert':'Frau Berthelmann', 'Felk':'Frau Felke', 'Kimm':'Herr Kimmel', 'PM1': 'Pädagosische(r) Mitarbeiter(in) 1', 'Schet':'Herr Schetler', 'Mani':'Herr Manigk', 'Segg':'Frau Seggern', 'Opel':'Frau Opel-Fritzler'};
|
|
||||||
if(value['Fa'].runtimeType != String){
|
|
||||||
name = value['Fa']['#text'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
name = value['Fa'];
|
|
||||||
}
|
|
||||||
if(value['Le'].runtimeType != String){
|
|
||||||
teacher = value['Le']['#text'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
teacher = value['Le'];
|
|
||||||
}
|
|
||||||
print(value['Ra']);
|
|
||||||
if(value['Ra'].runtimeType != String && value['Ra'].runtimeType != int){
|
|
||||||
if(value['Ra']['#text'] == ' ') {
|
|
||||||
room = '';
|
|
||||||
} else {
|
|
||||||
room = value['Ra']['#text'];
|
|
||||||
}
|
|
||||||
} else if(value['Ra'] == ' ') {
|
|
||||||
room = '';
|
|
||||||
} else {
|
|
||||||
room = value['Ra'];
|
|
||||||
}
|
|
||||||
var fontColor;
|
|
||||||
if(name == '---') {
|
|
||||||
fontColor = Colors.red;
|
|
||||||
} else {
|
|
||||||
fontColor = Colors.white;
|
|
||||||
}
|
|
||||||
var info;
|
|
||||||
if(value['If'].runtimeType != String) {
|
|
||||||
info = '';
|
|
||||||
} else {
|
|
||||||
info = value['If'];
|
|
||||||
}
|
|
||||||
if(name == 'Mat'){
|
|
||||||
color = Colors.indigo;
|
|
||||||
}
|
|
||||||
else if(name == 'Deu'){
|
|
||||||
color = Colors.red;
|
|
||||||
}
|
|
||||||
else if(name == 'Kun'){
|
|
||||||
color = Colors.deepPurple;
|
|
||||||
}
|
|
||||||
else if(name == 'Bio'){
|
|
||||||
color = Colors.green;
|
|
||||||
}
|
|
||||||
else if(name == 'Geo'){
|
|
||||||
color = Colors.brown;
|
|
||||||
}
|
|
||||||
else if(name == 'Lat'){
|
|
||||||
color = Colors.teal;
|
|
||||||
}
|
|
||||||
else if(name == 'Che'){
|
|
||||||
color = Colors.lightGreen;
|
|
||||||
}
|
|
||||||
else if(name == 'Eng'){
|
|
||||||
color = Colors.amber;
|
|
||||||
}
|
|
||||||
else if(name == 'Phy'){
|
|
||||||
color = Colors.cyan;
|
|
||||||
}
|
|
||||||
else if(name == 'Inf'){
|
|
||||||
color = Colors.tealAccent[400];
|
|
||||||
}
|
|
||||||
else if(name == 'Mus'){
|
|
||||||
color = Colors.deepOrange;
|
|
||||||
}
|
|
||||||
else if(name == 'Lme'){
|
|
||||||
color = Colors.amber[700];
|
|
||||||
}
|
|
||||||
else if(name == 'Ges'){
|
|
||||||
color = Colors.grey;
|
|
||||||
}
|
|
||||||
else if(name == 'Spa'){
|
|
||||||
color = Colors.redAccent;
|
|
||||||
}
|
|
||||||
else if(name == 'Frz'){
|
|
||||||
color = Colors.amberAccent[700];
|
|
||||||
}
|
|
||||||
else if(name == '---') {
|
|
||||||
color = Colors.white;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
color = Colors.grey[700];
|
|
||||||
}
|
|
||||||
dynamic names = {'Bio':'Biologie', 'Mat':'Mathematik', 'Kun':'Kunst', 'Mus':'Musik', 'Geo':'Geographie', 'Ges':'Geschichte', 'Che':'Chemie', 'Lat':'Latein', 'Inf':'Informatik', 'Eng':'Englisch', 'Frz':'Französisch', 'Phy':'Physik', '---':'---', 'Spo':'Sport', 'Deu':'Deutsch', 'Lme':'Lernmethoden', 'Eth':'Ethik', 'EvR':'Evangelische Religion', 'Spa':'Spanisch', 'Soz':'Sozialkunde', 'Ast':'Astronomie'};
|
|
||||||
dynamic colors = {'Bio':Colors.green, 'Mat':Colors.blue};
|
|
||||||
lessons.add(TimetableLesson(value['St'], names[name].toString(), teachers[teacher].toString(), room.toString(), value['If'].toString(), color, fontColor, info));
|
|
||||||
});
|
|
||||||
|
|
||||||
return ClassTimetable(
|
|
||||||
timetable: lessons
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimetableLesson {
|
|
||||||
final int count;
|
|
||||||
final String name;
|
|
||||||
final String teacher;
|
|
||||||
final String room;
|
|
||||||
final String comment;
|
|
||||||
final Color color;
|
|
||||||
final Color fontColor;
|
|
||||||
final String info;
|
|
||||||
const TimetableLesson(this.count, this.name, this.teacher, this.room, this.comment, this.color, this.fontColor, this.info);
|
|
||||||
}
|
|
516
lib/dashboard.dart
Normal file
516
lib/dashboard.dart
Normal file
@ -0,0 +1,516 @@
|
|||||||
|
//import 'package:MeinCantor/timetable.dart';
|
||||||
|
//import 'package:MeinCantor/main.dart';
|
||||||
|
import 'package:MeinCantor/raumuebersicht.dart';
|
||||||
|
import 'package:MeinCantor/schulbibliothek.dart';
|
||||||
|
import 'package:MeinCantor/schulcomputer.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'settings.dart';
|
||||||
|
import 'networking.dart';
|
||||||
|
import 'login.dart';
|
||||||
|
import 'schuelerzeitung.dart';
|
||||||
|
|
||||||
|
class Dashboard extends StatefulWidget {
|
||||||
|
const Dashboard({Key? key, this.restorationId}) : super(key: key);
|
||||||
|
|
||||||
|
final String? restorationId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _DashboardState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getSettingsString(String key) async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
String? value = prefs.getString(key);
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
print(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildSettingsString(String key, TextStyle style) {
|
||||||
|
return FutureBuilder(
|
||||||
|
future: getSettingsString(key),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
return Text(snapshot.data as String, style: style);
|
||||||
|
} else {
|
||||||
|
return (const Center(child: CircularProgressIndicator()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DashboardState extends State<Dashboard> with RestorationMixin {
|
||||||
|
final RestorableInt _currentIndex = RestorableInt(0);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final drawerElements = ListView(
|
||||||
|
children: [
|
||||||
|
UserAccountsDrawerHeader(
|
||||||
|
accountName: buildSettingsString('name', const TextStyle()),
|
||||||
|
accountEmail: buildSettingsString('user', const TextStyle()),
|
||||||
|
currentAccountPicture: const CircularProgressIndicator(
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: const Text("Einstellungen"),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => Settings()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
leading: const Icon(CupertinoIcons.settings),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: const Text("Abmelden"),
|
||||||
|
onTap: () async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
prefs.setString('api_key', "");
|
||||||
|
Navigator.pushReplacement(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => Login()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
leading: const Icon(Icons.exit_to_app_outlined),
|
||||||
|
),
|
||||||
|
AboutListTile(
|
||||||
|
child: const Text("Info"),
|
||||||
|
icon: const Icon(CupertinoIcons.info),
|
||||||
|
applicationVersion: "0.6.5-alpha",
|
||||||
|
applicationIcon: Image.asset("assets/images/meincantor_r.png",
|
||||||
|
height: 64, width: 64),
|
||||||
|
applicationName: "MeinCantor",
|
||||||
|
aboutBoxChildren: const [
|
||||||
|
Text(
|
||||||
|
"MeinCantor ist die Schulplatform für Schüler des Georg-Cantor-Gymnasiums in Halle (Saale)."),
|
||||||
|
Divider(),
|
||||||
|
Text("Copyright © 2021 Denys Konovalov")
|
||||||
|
],
|
||||||
|
// applicationIcon: Image.,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
var bottomNavBarItems = [
|
||||||
|
const BottomNavigationBarItem(
|
||||||
|
icon: Icon(CupertinoIcons.home),
|
||||||
|
label: "Startseite",
|
||||||
|
),
|
||||||
|
const BottomNavigationBarItem(
|
||||||
|
icon: Icon(CupertinoIcons.rectangle_grid_1x2),
|
||||||
|
label: "Vertretungsplan"),
|
||||||
|
];
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("GCG.MeinCantor"),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: _DashboardBottomNavView(
|
||||||
|
key: UniqueKey(), item: bottomNavBarItems[_currentIndex.value]),
|
||||||
|
drawer: Drawer(
|
||||||
|
child: drawerElements,
|
||||||
|
),
|
||||||
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
|
showUnselectedLabels: false,
|
||||||
|
items: bottomNavBarItems,
|
||||||
|
currentIndex: _currentIndex.value,
|
||||||
|
onTap: (index) {
|
||||||
|
setState(() {
|
||||||
|
_currentIndex.value = index;
|
||||||
|
});
|
||||||
|
//print(index);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get restorationId => widget.restorationId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
||||||
|
registerForRestoration(_currentIndex, 'bottom_navigation_tab_index');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DashboardBottomNavView extends StatelessWidget {
|
||||||
|
const _DashboardBottomNavView({Key? key, required this.item})
|
||||||
|
: super(key: key);
|
||||||
|
final BottomNavigationBarItem item;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (item.label == "Startseite") {
|
||||||
|
double _timeOfDayToDouble(TimeOfDay tod) => tod.hour + tod.minute / 60.0;
|
||||||
|
var lessonCount;
|
||||||
|
if (_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 7, minute: 30))) {
|
||||||
|
lessonCount = 1;
|
||||||
|
} else if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 7, minute: 30)) &&
|
||||||
|
_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 8, minute: 20))) {
|
||||||
|
lessonCount = 2;
|
||||||
|
} else if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 8, minute: 20)) &&
|
||||||
|
_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 9, minute: 25))) {
|
||||||
|
lessonCount = 3;
|
||||||
|
} else if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 9, minute: 25)) &&
|
||||||
|
_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 10, minute: 15))) {
|
||||||
|
lessonCount = 4;
|
||||||
|
} else if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 10, minute: 15)) &&
|
||||||
|
_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 11, minute: 30))) {
|
||||||
|
lessonCount = 5;
|
||||||
|
} else if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 11, minute: 30)) &&
|
||||||
|
_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 12, minute: 20))) {
|
||||||
|
lessonCount = 6;
|
||||||
|
} else if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 12, minute: 20)) &&
|
||||||
|
_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 13, minute: 30))) {
|
||||||
|
lessonCount = 7;
|
||||||
|
} else if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 13, minute: 30)) &&
|
||||||
|
_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 14, minute: 20))) {
|
||||||
|
lessonCount = 8;
|
||||||
|
} else if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 14, minute: 20)) &&
|
||||||
|
_timeOfDayToDouble(TimeOfDay.now()) <=
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: 15, minute: 10))) {
|
||||||
|
lessonCount = 9;
|
||||||
|
} else {
|
||||||
|
lessonCount = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Widget timetable;
|
||||||
|
if (_timeOfDayToDouble(TimeOfDay.now()) >
|
||||||
|
_timeOfDayToDouble(const TimeOfDay(hour: , minute: 55))) {
|
||||||
|
timetable = buildClassTimetable();
|
||||||
|
} else {
|
||||||
|
timetable = buildTodayClassTimetable();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
print(lessonCount);
|
||||||
|
var view = SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(20, 30, 20, 5),
|
||||||
|
child: Text(
|
||||||
|
'Hallo,',
|
||||||
|
style: GoogleFonts.robotoSlab(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(20, 5, 20, 20),
|
||||||
|
child: buildSettingsString(
|
||||||
|
"name",
|
||||||
|
GoogleFonts.robotoSlab(
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(20, 10, 0, 10),
|
||||||
|
child: Text(
|
||||||
|
'Deine nächste Unterrichtsstunde:',
|
||||||
|
style: GoogleFonts.robotoSlab(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w100,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(20, 20, 20, 10),
|
||||||
|
child: buildTodayClassTimetableLesson(lessonCount),
|
||||||
|
),
|
||||||
|
Row(mainAxisSize: MainAxisSize.max, children: [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(20, 20, 20, 10),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => const SZ()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Card(
|
||||||
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(20, 20, 10, 10),
|
||||||
|
child: Icon(
|
||||||
|
CupertinoIcons.news,
|
||||||
|
color: Color(0xFFFFBC3B),
|
||||||
|
size: 48,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: const [
|
||||||
|
Align(
|
||||||
|
alignment: Alignment(0, 0),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
|
||||||
|
child: Text(
|
||||||
|
'Schülerzeitung',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => const SB()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Card(
|
||||||
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(20, 20, 10, 10),
|
||||||
|
child: Icon(
|
||||||
|
CupertinoIcons.book,
|
||||||
|
color: Color(0xFFFFBC3B),
|
||||||
|
size: 48,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
|
||||||
|
child: Text(
|
||||||
|
'Schulbibliothek',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => const SC()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Card(
|
||||||
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(20, 20, 10, 10),
|
||||||
|
child: Icon(
|
||||||
|
CupertinoIcons.device_laptop,
|
||||||
|
color: Color(0xFFFFBC3B),
|
||||||
|
size: 48,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
|
||||||
|
child: Text(
|
||||||
|
'Schulcomputer',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => const RoomOverview()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Card(
|
||||||
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(20, 20, 10, 10),
|
||||||
|
child: Icon(
|
||||||
|
CupertinoIcons.house_alt,
|
||||||
|
color: Color(0xFFFFBC3B),
|
||||||
|
size: 48,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: const [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
|
||||||
|
child: Text(
|
||||||
|
'Raumübersicht',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
return view;
|
||||||
|
} else if (item.label == "Vertretungsplan") {
|
||||||
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
|
double widgetWidth = constraints.maxWidth;
|
||||||
|
// double widgetHeight = constraints.maxHeight;
|
||||||
|
var factor;
|
||||||
|
|
||||||
|
if (widgetWidth <= 600) {
|
||||||
|
factor = 1;
|
||||||
|
} else if (widgetWidth <= 1400) {
|
||||||
|
factor = 2;
|
||||||
|
} else if (widgetWidth <= 2000) {
|
||||||
|
factor = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print(screenType);
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
// minHeight: 500, //minimum height
|
||||||
|
// minWidth: 300, // minimum width
|
||||||
|
//maximum height set to 100% of vertical height
|
||||||
|
maxWidth: MediaQuery.of(context).size.width / factor,
|
||||||
|
//maximum width set to 100% of width
|
||||||
|
),
|
||||||
|
child: DefaultTabController(
|
||||||
|
initialIndex: 0,
|
||||||
|
length: 2,
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
elevation: 0,
|
||||||
|
title: const TabBar(
|
||||||
|
tabs: <Widget>[
|
||||||
|
Tab(
|
||||||
|
text: "Heute",
|
||||||
|
icon: Icon(CupertinoIcons.calendar_today),
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
text: "Neuster Plan",
|
||||||
|
icon: Icon(CupertinoIcons.calendar),
|
||||||
|
),
|
||||||
|
/*Tab(
|
||||||
|
text: "Archiv",
|
||||||
|
icon: Icon(CupertinoIcons.archivebox),
|
||||||
|
),*/
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: TabBarView(
|
||||||
|
children: <Widget>[
|
||||||
|
buildTodayClassTimetable(),
|
||||||
|
buildClassTimetable(),
|
||||||
|
/*
|
||||||
|
Center(
|
||||||
|
child: Text("It's sunny here"),
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return const Text("Such page does not exist.");
|
||||||
|
}
|
||||||
|
// return materialCard(item.label);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// ignore_for_file: directives_ordering
|
||||||
// ignore_for_file: lines_longer_than_80_chars
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
|
||||||
import 'package:fluttertoast/fluttertoast_web.dart';
|
import 'package:fluttertoast/fluttertoast_web.dart';
|
||||||
|
@ -2,15 +2,15 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
|
||||||
import 'networking.dart';
|
import 'networking.dart';
|
||||||
import 'Dashboard.dart';
|
import 'dashboard.dart';
|
||||||
|
|
||||||
Future<bool> checkKey() async {
|
Future<bool> checkKey() async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
String? api_key = await prefs.getString('api_key');
|
String? apiKey = prefs.getString('api_key');
|
||||||
return api_key != null && api_key.isNotEmpty;
|
return apiKey != null && apiKey.isNotEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Login extends StatelessWidget {
|
class Login extends StatelessWidget {
|
||||||
@ -37,12 +37,12 @@ class Login extends StatelessWidget {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text("Anmelden"),
|
title: const Text("Anmelden"),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
|
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth:
|
maxWidth:
|
||||||
@ -53,23 +53,27 @@ class Login extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Image.asset("assets/images/meincantor_r.png",
|
Image.asset("assets/images/meincantor_r.png",
|
||||||
height: 192, width: 192),
|
height: 192, width: 192),
|
||||||
Divider(),
|
const Divider(),
|
||||||
AutofillGroup(
|
AutofillGroup(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
autofillHints: [AutofillHints.username],
|
autofillHints: const [
|
||||||
decoration: InputDecoration(
|
AutofillHints.username
|
||||||
|
],
|
||||||
|
decoration: const InputDecoration(
|
||||||
icon: Icon(CupertinoIcons.person),
|
icon: Icon(CupertinoIcons.person),
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
labelText: 'Benutzername',
|
labelText: 'Benutzername',
|
||||||
),
|
),
|
||||||
controller: userController,
|
controller: userController,
|
||||||
),
|
),
|
||||||
Divider(),
|
const Divider(),
|
||||||
TextField(
|
TextField(
|
||||||
autofillHints: [AutofillHints.password],
|
autofillHints: const [
|
||||||
decoration: InputDecoration(
|
AutofillHints.password
|
||||||
|
],
|
||||||
|
decoration: const InputDecoration(
|
||||||
icon: Icon(CupertinoIcons.lock),
|
icon: Icon(CupertinoIcons.lock),
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
labelText: 'Passwort',
|
labelText: 'Passwort',
|
||||||
@ -79,9 +83,9 @@ class Login extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
Divider(),
|
const Divider(),
|
||||||
TextField(
|
TextField(
|
||||||
decoration: InputDecoration(
|
decoration: const InputDecoration(
|
||||||
icon: Icon(CupertinoIcons.lock),
|
icon: Icon(CupertinoIcons.lock),
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
labelText: '2F2-Code (OTP) [falls aktiviert]',
|
labelText: '2F2-Code (OTP) [falls aktiviert]',
|
||||||
@ -89,37 +93,55 @@ class Login extends StatelessWidget {
|
|||||||
obscureText: true,
|
obscureText: true,
|
||||||
controller: otpController,
|
controller: otpController,
|
||||||
),
|
),
|
||||||
Divider(),
|
const Divider(),
|
||||||
TextField(
|
TextField(
|
||||||
decoration: InputDecoration(
|
decoration: const InputDecoration(
|
||||||
icon: Icon(CupertinoIcons.device_laptop),
|
icon: Icon(CupertinoIcons.device_laptop),
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
labelText: 'Gerätebezeichnung',
|
labelText: 'Gerätebezeichnung',
|
||||||
),
|
),
|
||||||
controller: devIdController,
|
controller: devIdController,
|
||||||
),
|
),
|
||||||
Divider(),
|
const Divider(),
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
SharedPreferences prefs =
|
SharedPreferences prefs =
|
||||||
await SharedPreferences.getInstance();
|
await SharedPreferences.getInstance();
|
||||||
String api_key = await getToken(
|
Response loginResponse = await getToken(
|
||||||
userController.text,
|
userController.text,
|
||||||
passwordController.text,
|
passwordController.text,
|
||||||
otpController.text,
|
otpController.text,
|
||||||
devIdController.text);
|
devIdController.text);
|
||||||
print('Set new API key to $api_key');
|
if (loginResponse.statusCode == 200) {
|
||||||
await prefs.setString('api_key', api_key);
|
String apiKey = jsonDecode(utf8.decode(
|
||||||
dynamic userinfo = jsonDecode(
|
loginResponse.bodyBytes))['token'];
|
||||||
await getUserInfo(
|
print('Set new API key to $apiKey');
|
||||||
userController.text,
|
await prefs.setString('api_key', apiKey);
|
||||||
passwordController.text,
|
dynamic userinfo = jsonDecode(
|
||||||
otpController.text,
|
await getUserInfo(
|
||||||
devIdController.text));
|
userController.text,
|
||||||
await prefs.setString(
|
passwordController.text,
|
||||||
'user', userinfo['preferred_username']);
|
otpController.text,
|
||||||
await prefs.setString(
|
devIdController.text));
|
||||||
'name', userinfo['name']);
|
await prefs.setString('user',
|
||||||
|
userinfo['preferred_username']);
|
||||||
|
await prefs.setString(
|
||||||
|
'name', userinfo['name']);
|
||||||
|
await prefs.setString(
|
||||||
|
'class_num',
|
||||||
|
userinfo['groups'][0]
|
||||||
|
.replaceAll("_", "/"));
|
||||||
|
} else if (loginResponse.statusCode ==
|
||||||
|
401) {
|
||||||
|
String text = loginResponse.body;
|
||||||
|
final snackBar = SnackBar(
|
||||||
|
content: Text('Fehler: $text'));
|
||||||
|
|
||||||
|
// Find the ScaffoldMessenger in the widget tree
|
||||||
|
// and use it to show a SnackBar.
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(snackBar);
|
||||||
|
}
|
||||||
if (prefs.getString('api_key') != null &&
|
if (prefs.getString('api_key') != null &&
|
||||||
prefs
|
prefs
|
||||||
.getString('api_key')!
|
.getString('api_key')!
|
||||||
@ -127,18 +149,15 @@ class Login extends StatelessWidget {
|
|||||||
Navigator.pushReplacement(
|
Navigator.pushReplacement(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => Dashboard()),
|
builder: (context) =>
|
||||||
|
const Dashboard()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text("Anmelden"))
|
child: const Text("Anmelden"))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)))));
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,13 +1,15 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'Dashboard.dart';
|
import 'dashboard.dart';
|
||||||
import 'Login.dart';
|
import 'login.dart';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
void main() => runApp(App());
|
void main() => runApp(const App());
|
||||||
|
|
||||||
class App extends StatelessWidget {
|
class App extends StatelessWidget {
|
||||||
|
const App({Key? key}) : super(key: key);
|
||||||
|
|
||||||
MaterialColor generateMaterialColor(Color color) {
|
MaterialColor generateMaterialColor(Color color) {
|
||||||
return MaterialColor(color.value, {
|
return MaterialColor(color.value, {
|
||||||
50: tintColor(color, 0.5),
|
50: tintColor(color, 0.5),
|
||||||
@ -38,47 +40,40 @@ class App extends StatelessWidget {
|
|||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
primaryColor: Palette.primary,
|
primaryColor: Palette.primary,
|
||||||
colorScheme: ColorScheme.fromSwatch(
|
colorScheme: ColorScheme.fromSwatch(
|
||||||
primarySwatch: generateMaterialColor(Palette.accent),
|
primarySwatch: generateMaterialColor(Palette.primary),
|
||||||
).copyWith(
|
).copyWith(
|
||||||
secondary: generateMaterialColor(Palette.accent),
|
secondary: generateMaterialColor(Palette.accent),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
darkTheme: ThemeData.from(colorScheme: ColorScheme.dark(primary: Palette.accent)),
|
darkTheme: ThemeData.from(
|
||||||
|
colorScheme: const ColorScheme.dark(primary: Palette.accent)),
|
||||||
title: "GCG.MeinCantor",
|
title: "GCG.MeinCantor",
|
||||||
home: buildHomePage(),
|
home: buildHomePage(),
|
||||||
/*
|
|
||||||
routes: <String, WidgetBuilder>{
|
|
||||||
"/": (_) => Dashboard(),
|
|
||||||
"/login": (_) => Login()
|
|
||||||
},
|
|
||||||
|
|
||||||
*/
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> apiKeyEmpty() async {
|
Future<bool> apiKeyEmpty() async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
String? api_key = await prefs.getString("api_key");
|
String? apiKey = prefs.getString("api_key");
|
||||||
return api_key == null || api_key.isEmpty;
|
return apiKey == null || apiKey.isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildHomePage() {
|
Widget buildHomePage() {
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: apiKeyEmpty(),
|
future: apiKeyEmpty(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if(snapshot.data == true) {
|
if (snapshot.data == true) {
|
||||||
return Login();
|
return Login();
|
||||||
} else if(snapshot.data == false) {
|
} else if (snapshot.data == false) {
|
||||||
return Dashboard();
|
return const Dashboard();
|
||||||
} else {
|
} else {
|
||||||
return Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Palette {
|
class Palette {
|
||||||
static const Color primary = Color(0xFF1A1A37);
|
static const Color primary = Color(0xFF1A1A37);
|
||||||
static const Color accent = Color(0xFFFFBC3B);
|
static const Color accent = Color(0xFFFFBC3B);
|
||||||
}
|
}
|
@ -1,39 +1,21 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'main.dart';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'timetable.dart';
|
||||||
import 'Timetable.dart';
|
import 'login.dart';
|
||||||
import 'Login.dart';
|
import 'main.dart';
|
||||||
|
|
||||||
Future<String> getToken(
|
Future<http.Response> getToken(
|
||||||
String user, String password, String otp, String devId) async {
|
String user, String password, String otp, String devId) async {
|
||||||
var uri = Uri.https("mein.cantorgymnasium.de", "/login");
|
var uri = Uri.https("mein.cantorgymnasium.de", "/login");
|
||||||
String body =
|
String body =
|
||||||
'{"user":"$user", "password": "$password", "otp": "$otp", "devid": "$devId"}';
|
'{"user":"$user", "password": "$password", "otp": "$otp", "devid": "$devId"}';
|
||||||
print(uri);
|
print(uri);
|
||||||
final response = await http.post(uri, body: body);
|
final response = await http.post(uri, body: body);
|
||||||
|
return (response);
|
||||||
if (response.statusCode == 200) {
|
|
||||||
return jsonDecode(utf8.decode(response.bodyBytes))['token'];
|
|
||||||
} else if(response.statusCode == 401) {
|
|
||||||
var body = response.body;
|
|
||||||
Fluttertoast.showToast(
|
|
||||||
msg: "Fehler: $body",
|
|
||||||
toastLength: Toast.LENGTH_SHORT,
|
|
||||||
gravity: ToastGravity.CENTER,
|
|
||||||
timeInSecForIosWeb: 1,
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
textColor: Colors.white,
|
|
||||||
fontSize: 16.0
|
|
||||||
);
|
|
||||||
throw Exception('Failed to log in');
|
|
||||||
} else {
|
|
||||||
throw Exception('Undefined error');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getUserInfo(
|
Future<String> getUserInfo(
|
||||||
@ -53,18 +35,36 @@ Future<String> getUserInfo(
|
|||||||
|
|
||||||
Future<http.Response> fetchClassTimetable() async {
|
Future<http.Response> fetchClassTimetable() async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
var class_num;
|
String classNum;
|
||||||
print(prefs.getString('class_num'));
|
print(prefs.getString('class_num'));
|
||||||
if (prefs.getString('class_num') != null) {
|
if (prefs.getString('class_num') != null) {
|
||||||
class_num = prefs.getString('class_num')!;
|
classNum = prefs.getString('class_num')!.replaceAll("/", "_");
|
||||||
} else {
|
} else {
|
||||||
class_num = '07_1';
|
classNum = '05_1';
|
||||||
}
|
}
|
||||||
var api_key = prefs.getString('api_key');
|
var apiKey = prefs.getString('api_key');
|
||||||
var uri = Uri.https("mein.cantorgymnasium.de", "/api/timetable/$class_num");
|
var uri = Uri.https("mein.cantorgymnasium.de", "/api/timetable/$classNum");
|
||||||
var headers = {"x-api-key": "$api_key"};
|
var headers = {"x-api-key": "$apiKey"};
|
||||||
print(uri);
|
print(uri);
|
||||||
final response = http.get(uri, headers: headers);
|
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)); } );
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,15 +79,148 @@ Widget buildClassTimetable() {
|
|||||||
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)))
|
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)))
|
||||||
.view;
|
.view;
|
||||||
return timetableView;
|
return timetableView;
|
||||||
}
|
} else if (statusCode == 400) {
|
||||||
else if(statusCode == 400) {
|
Navigator.pushReplacement(
|
||||||
Navigator.push(context, MaterialPageRoute(builder: (context) => Login()));
|
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'));
|
return Center(child: Text('Error $statusCode'));
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
return Text('$snapshot.error');
|
return Text('$snapshot.error');
|
||||||
} else {
|
} else {
|
||||||
return Center(child: CircularProgressIndicator());
|
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.")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Center(child: Text('Error $statusCode'));
|
||||||
|
} else if (snapshot.hasError) {
|
||||||
|
return Text('$snapshot.error');
|
||||||
|
} else {
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -95,21 +228,11 @@ Widget buildClassTimetable() {
|
|||||||
|
|
||||||
Future<http.Response> fetchClassesList() async {
|
Future<http.Response> fetchClassesList() async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
/*
|
var apiKey = prefs.getString('api_key');
|
||||||
var class_num;
|
|
||||||
print(prefs.getString('class_num'));
|
|
||||||
if(prefs.getString('class_num') != null){
|
|
||||||
class_num = prefs.getString('class_num')!;
|
|
||||||
} else {
|
|
||||||
class_num = '07_1';
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// await prefs.setString('api_key', "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJHZW9yZy1DYW50b3ItR3ltbmFzaXVtIEhhbGxlKFNhYWxlKSIsInVzZXIiOiJkZW55cy5rb25vdmFsb3ZAcG0ubWUiLCJyb2xlcyI6WyJTdHVkZW50IiwiQWRtaW4iXSwiYmxhY2tsaXN0IjpbIi9jbGFzc2VzIl0sIndoaXRlbGlzdCI6WyIvaGVsbG8vc2Vuc2l0aXZlIl0sImppZCI6IkFwcERldiBBbHBoYSBkdW1teSBrZXlAMDIvMDgvMjAyMSAxOTowODowOSIsImV4cCI6MTY1OTQ2NzI4OX0.a7Q83PK3ybeV7Bui-_rX1o6IZx1cNa6vsvUGG-kfqtc");
|
|
||||||
var api_key = prefs.getString('api_key');
|
|
||||||
var uri = Uri.https("mein.cantorgymnasium.de", "/api/classes");
|
var uri = Uri.https("mein.cantorgymnasium.de", "/api/classes");
|
||||||
var headers = {"x-api-key": "$api_key"};
|
var headers = {"x-api-key": "$apiKey"};
|
||||||
print(uri);
|
print(uri);
|
||||||
final response = http.get(uri, headers: headers);
|
final response = http.get(uri, headers: headers).onError((error, stackTrace) { return(http.Response("", 404)); } );
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,20 +243,30 @@ Widget buildClassesChooser() {
|
|||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
int statusCode = snapshot.data!.statusCode;
|
int statusCode = snapshot.data!.statusCode;
|
||||||
if (statusCode == 200) {
|
if (statusCode == 200) {
|
||||||
// List<Widget> children = [];
|
|
||||||
//ClassTimetable.fromJson(jsonDecode(utf8.decode(snapshot.data!.bodyBytes))).timetable.forEach((element) {
|
|
||||||
//});
|
|
||||||
List<String> items = [];
|
List<String> items = [];
|
||||||
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)).forEach((value) {
|
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)).forEach((value) {
|
||||||
items.add(value..toString());
|
items.add(value..toString());
|
||||||
});
|
});
|
||||||
return ClassesChooser(items: items);
|
return ClassesChooser(items: items);
|
||||||
|
} 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")),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return Text('$statusCode');
|
return Text('$statusCode');
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
return Text('$snapshot.error');
|
return Text('$snapshot.error');
|
||||||
} else {
|
} else {
|
||||||
return Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -150,37 +283,38 @@ class ClassesChooser extends StatefulWidget {
|
|||||||
class _ClassesChooserState extends State<ClassesChooser> {
|
class _ClassesChooserState extends State<ClassesChooser> {
|
||||||
final List<String> items;
|
final List<String> items;
|
||||||
//final String dropdownValue;
|
//final String dropdownValue;
|
||||||
var dropdownValue;
|
String? dropdownValue;
|
||||||
_ClassesChooserState(this.items);
|
_ClassesChooserState(this.items);
|
||||||
|
|
||||||
|
@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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// var dropdown_items =
|
|
||||||
return DropdownButtonFormField<String>(
|
return DropdownButtonFormField<String>(
|
||||||
// value: dropdownValue,
|
value: dropdownValue,
|
||||||
/*icon: const Icon(Icons.arrow_downward),
|
decoration: const InputDecoration(
|
||||||
iconSize: 24,
|
|
||||||
elevation: 16,*/
|
|
||||||
// style: const TextStyle(color: Color(0xFFFFBC3B)),
|
|
||||||
/*underline: Container(
|
|
||||||
height: 2,
|
|
||||||
color: Color(0xFFFFBC3B),
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
decoration: InputDecoration(
|
|
||||||
icon: Icon(CupertinoIcons.number),
|
icon: Icon(CupertinoIcons.number),
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
labelText: 'Klasse (05_1, 07_3, 10_2...)',
|
labelText: 'Klasse (05/1, 07/3, 10/2...)',
|
||||||
),
|
),
|
||||||
// icon: Icon(CupertinoIcons.number),
|
|
||||||
|
|
||||||
onChanged: (String? newValue) {
|
onChanged: (String? newValue) {
|
||||||
setState(() async {
|
setState(() async {
|
||||||
dropdownValue = newValue!;
|
dropdownValue = newValue!;
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
String class_num = newValue;
|
String classNum = newValue;
|
||||||
print('Set new class to $class_num');
|
print('Set new class to $classNum');
|
||||||
await prefs.setString('class_num', class_num);
|
await prefs.setString('class_num', classNum);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
items: items.map<DropdownMenuItem<String>>((String value) {
|
items: items.map<DropdownMenuItem<String>>((String value) {
|
||||||
|
18
lib/raumuebersicht.dart
Normal file
18
lib/raumuebersicht.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class RoomOverview extends StatelessWidget {
|
||||||
|
const RoomOverview ({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("Raumübersicht"),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: Text("Derzeit nichts hier..."),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
18
lib/schuelerzeitung.dart
Normal file
18
lib/schuelerzeitung.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SZ extends StatelessWidget {
|
||||||
|
const SZ({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("Schülerzeitung"),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: Text("Derzeit nichts hier..."),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
18
lib/schulbibliothek.dart
Normal file
18
lib/schulbibliothek.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SB extends StatelessWidget {
|
||||||
|
const SB ({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("Schulbibliothek"),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: Text("Derzeit nichts hier..."),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
18
lib/schulcomputer.dart
Normal file
18
lib/schulcomputer.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SC extends StatelessWidget {
|
||||||
|
const SC ({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("Schulcomputer"),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: Text("Derzeit nichts hier..."),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
65
lib/settings.dart
Normal file
65
lib/settings.dart
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'networking.dart';
|
||||||
|
|
||||||
|
class Settings extends StatelessWidget {
|
||||||
|
const Settings({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("Einstellungen"),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
|
||||||
|
children: [
|
||||||
|
const ListTile(
|
||||||
|
leading: Icon(CupertinoIcons.rectangle_grid_1x2),
|
||||||
|
title: Text("Plan")),
|
||||||
|
/*
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||||
|
child: TextField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
icon: Icon(CupertinoIcons.lock),
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'API Key (POST /login)',
|
||||||
|
),
|
||||||
|
onSubmitted: (String value) async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
String api_key = value;
|
||||||
|
print('Set new API key to $api_key');
|
||||||
|
await prefs.setString('api_key', api_key);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
const Divider(),
|
||||||
|
buildClassesChooser(),
|
||||||
|
const Divider(),
|
||||||
|
const ListTile(
|
||||||
|
leading: Icon(Icons.code), title: Text("Entwickleroptionen")),
|
||||||
|
const Divider(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||||
|
child: TextField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
icon: Icon(CupertinoIcons.lock),
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'API Key (POST /login)',
|
||||||
|
),
|
||||||
|
onSubmitted: (String value) async {
|
||||||
|
SharedPreferences prefs =
|
||||||
|
await SharedPreferences.getInstance();
|
||||||
|
String apiKey = value;
|
||||||
|
print('Set new API key to $apiKey');
|
||||||
|
await prefs.setString('api_key', apiKey);
|
||||||
|
})),
|
||||||
|
const Divider(),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
261
lib/timetable.dart
Normal file
261
lib/timetable.dart
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
|
class ClassTimetableBuilder {
|
||||||
|
final ListView view;
|
||||||
|
ClassTimetableBuilder({required this.view});
|
||||||
|
factory ClassTimetableBuilder.buildView(Map<String, dynamic> json) {
|
||||||
|
return ClassTimetableBuilder(
|
||||||
|
view: ListView(
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
children: LessonsListBuilder.buildList(json).lessons));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LessonsListBuilder {
|
||||||
|
final List<Widget> lessons;
|
||||||
|
LessonsListBuilder({required this.lessons});
|
||||||
|
factory LessonsListBuilder.buildList(Map<String, dynamic> json, {int count: 0}) {
|
||||||
|
List<Widget> children = [];
|
||||||
|
ClassTimetable.fromJson(json).timetable.forEach((element) {
|
||||||
|
List<Widget> cardChildren = [];
|
||||||
|
print(element.count.toString() + " " + count.toString());
|
||||||
|
if (element.count.toString() == count.toString() || count == 0) {
|
||||||
|
print("teeee");
|
||||||
|
cardChildren.add(ListTile(
|
||||||
|
title: Text(element.count.toString() + '.' + ' ' + element.name,
|
||||||
|
style: TextStyle(color: element.fontColor)),
|
||||||
|
subtitle: Row(children: [
|
||||||
|
Icon(CupertinoIcons.person, color: element.fontColor),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Text(element.teacher, style: TextStyle(color: element.fontColor)),
|
||||||
|
const Spacer(),
|
||||||
|
Icon(CupertinoIcons.home, color: element.fontColor),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Text(element.room, style: TextStyle(color: element.fontColor))
|
||||||
|
]),
|
||||||
|
leading: Icon(CupertinoIcons.time, color: element.fontColor)));
|
||||||
|
if (element.info != '') {
|
||||||
|
cardChildren.add(ListTile(
|
||||||
|
title: Text(element.info,
|
||||||
|
style: TextStyle(color: element.fontColor))));
|
||||||
|
}
|
||||||
|
Card card = Card(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(15.0),
|
||||||
|
),
|
||||||
|
color: element.color,
|
||||||
|
child: Column(
|
||||||
|
children: cardChildren,
|
||||||
|
));
|
||||||
|
children.add(card);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return LessonsListBuilder(lessons: children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassTimetable {
|
||||||
|
final List timetable;
|
||||||
|
ClassTimetable({required this.timetable});
|
||||||
|
factory ClassTimetable.fromJson(Map<String, dynamic> json) {
|
||||||
|
print(json);
|
||||||
|
List<TimetableLesson> lessons = [];
|
||||||
|
json['courses'].forEach((value) {
|
||||||
|
var name;
|
||||||
|
var teacher;
|
||||||
|
var room;
|
||||||
|
dynamic teachers = {
|
||||||
|
'Poli': 'Herr Polity',
|
||||||
|
'Zura': 'Frau Zuralski',
|
||||||
|
'Enzi': 'Frau Enzian',
|
||||||
|
'Bütt': 'Frau Büttner',
|
||||||
|
'Brod': 'Herr Brode',
|
||||||
|
'Rink': 'Frau Rinke',
|
||||||
|
'Schk': 'Frau Schmidt',
|
||||||
|
'Rudo': 'Frau Rudolph',
|
||||||
|
'Kipp': 'Frau Kipping',
|
||||||
|
'Bach': 'Frau Bachran',
|
||||||
|
'Bad': 'Herr Bader',
|
||||||
|
'Prei': 'Frau Preiß',
|
||||||
|
'Scha': 'Frau Schapitz',
|
||||||
|
' ': '',
|
||||||
|
'Link': 'Herr Linke',
|
||||||
|
'Stei': 'Herr Stein',
|
||||||
|
'Tupp': 'Frau Tuppack',
|
||||||
|
'Hoff': 'Frau Hoffman',
|
||||||
|
'Knol': 'Frau Knoll',
|
||||||
|
'Bet': 'Frau Bethin',
|
||||||
|
'Schu': 'Frau Schulz',
|
||||||
|
'Seid': 'Frau Seidel',
|
||||||
|
'Krug': 'Frau Krug',
|
||||||
|
'Laer': 'Frau Langer',
|
||||||
|
'Youn': 'Frau Younso',
|
||||||
|
'Härt': 'Frau Härtig',
|
||||||
|
'Bros': 'Frau Brosig',
|
||||||
|
'Ber': 'Frau Bernhardt',
|
||||||
|
'Stüb': 'Frau Stüber',
|
||||||
|
'Bor': 'Frau Borchert',
|
||||||
|
'Dubb': 'Frau Dubberstein',
|
||||||
|
'Tren': 'Frau Trentsch',
|
||||||
|
'Meit': 'Herr Meitzner',
|
||||||
|
'Stol': 'Frau Stolpe',
|
||||||
|
'Jac': 'Frau Jacob',
|
||||||
|
'Jüne': 'Herr Jünemann',
|
||||||
|
'Bert': 'Frau Berthelmann',
|
||||||
|
'Felk': 'Frau Felke',
|
||||||
|
'Kimm': 'Herr Kimmel',
|
||||||
|
'PM1': 'Pädagosische(r) Mitarbeiter(in) 1',
|
||||||
|
'Schet': 'Herr Schetler',
|
||||||
|
'Mani': 'Herr Manigk',
|
||||||
|
'Segg': 'Frau Seggern',
|
||||||
|
'Opel': 'Frau Opel-Fritzler',
|
||||||
|
'Möll': 'Frau Möller',
|
||||||
|
'Laen': 'Herr Langen',
|
||||||
|
'Plin': 'Herr Plinke',
|
||||||
|
'Koch': 'Herr Koch',
|
||||||
|
'Gors': 'Herr Gorsler',
|
||||||
|
'Krau': 'Herr Krause',
|
||||||
|
'Henk': 'Frau Henke',
|
||||||
|
'Wolf': 'Herr Wolf'
|
||||||
|
};
|
||||||
|
if (value['Fa'].runtimeType != String) {
|
||||||
|
name = value['Fa']['#text'];
|
||||||
|
} else {
|
||||||
|
name = value['Fa'];
|
||||||
|
}
|
||||||
|
if (value['Le'].runtimeType != String) {
|
||||||
|
teacher = value['Le']['#text'];
|
||||||
|
} else {
|
||||||
|
teacher = value['Le'];
|
||||||
|
}
|
||||||
|
print(value['Ra']);
|
||||||
|
if (value['Ra'].runtimeType != String && value['Ra'].runtimeType != int) {
|
||||||
|
if (value['Ra']['#text'] == ' ') {
|
||||||
|
room = '';
|
||||||
|
} else if (value['Ra']['#text'] == null) {
|
||||||
|
room = '';
|
||||||
|
} else {
|
||||||
|
room = value['Ra']['#text'];
|
||||||
|
}
|
||||||
|
} else if (value['Ra'] == ' ') {
|
||||||
|
room = '';
|
||||||
|
} else {
|
||||||
|
room = value['Ra'];
|
||||||
|
}
|
||||||
|
Color fontColor;
|
||||||
|
if (name == '---') {
|
||||||
|
fontColor = Colors.red;
|
||||||
|
} else {
|
||||||
|
fontColor = Colors.white;
|
||||||
|
}
|
||||||
|
var info;
|
||||||
|
if (value['If'].runtimeType != String) {
|
||||||
|
info = '';
|
||||||
|
} else {
|
||||||
|
info = value['If'];
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic colors = {
|
||||||
|
'Bio': Colors.green,
|
||||||
|
'Mat': Colors.indigo,
|
||||||
|
'matL1': Colors.indigo,
|
||||||
|
'matL2': Colors.indigo,
|
||||||
|
'matL3': Colors.indigo,
|
||||||
|
'Deu': Colors.red,
|
||||||
|
'deu1': Colors.red,
|
||||||
|
'deu2': Colors.red,
|
||||||
|
'deu3': Colors.red,
|
||||||
|
'Kun': Colors.deepPurple,
|
||||||
|
'kun1': Colors.deepPurple,
|
||||||
|
'kun2': Colors.deepPurple,
|
||||||
|
'kun3': Colors.deepPurple,
|
||||||
|
'Geo': Colors.brown,
|
||||||
|
'Lat': Colors.teal,
|
||||||
|
'lat1': Colors.teal,
|
||||||
|
'lat2': Colors.teal,
|
||||||
|
'lat3': Colors.teal,
|
||||||
|
'Che': Colors.lightGreen,
|
||||||
|
'Eng': Colors.amber,
|
||||||
|
'eng1': Colors.amber,
|
||||||
|
'eng2': Colors.amber,
|
||||||
|
'eng3': Colors.amber,
|
||||||
|
'Phy': Colors.cyan,
|
||||||
|
'phy1': Colors.cyan,
|
||||||
|
'phy2': Colors.cyan,
|
||||||
|
'phy3': Colors.cyan,
|
||||||
|
'Inf': Colors.tealAccent[400],
|
||||||
|
'Mus': Colors.deepOrange,
|
||||||
|
'mus1': Colors.deepOrange,
|
||||||
|
'mus2': Colors.deepOrange,
|
||||||
|
'mus3': Colors.deepOrange,
|
||||||
|
'Lme': Colors.amber[700],
|
||||||
|
'Ges': Colors.grey,
|
||||||
|
'ges1': Colors.grey,
|
||||||
|
'ges2': Colors.grey,
|
||||||
|
'ges3': Colors.grey,
|
||||||
|
'Spa': Colors.redAccent,
|
||||||
|
'Frz': Colors.amberAccent[700],
|
||||||
|
'frz1': Colors.amberAccent[700],
|
||||||
|
'---': Colors.white
|
||||||
|
};
|
||||||
|
|
||||||
|
dynamic names = {
|
||||||
|
'Bio': 'Biologie',
|
||||||
|
'Mat': 'Mathematik',
|
||||||
|
'matL1': 'Mathematik Leistungskurs 1',
|
||||||
|
'Kun': 'Kunst',
|
||||||
|
'Mus': 'Musik',
|
||||||
|
'Geo': 'Geographie',
|
||||||
|
'Ges': 'Geschichte',
|
||||||
|
'Che': 'Chemie',
|
||||||
|
'Lat': 'Latein',
|
||||||
|
'Inf': 'Informatik',
|
||||||
|
'Eng': 'Englisch',
|
||||||
|
'Frz': 'Französisch',
|
||||||
|
'frz1': 'Französisch 1',
|
||||||
|
'Phy': 'Physik',
|
||||||
|
'---': '---',
|
||||||
|
'Spo': 'Sport',
|
||||||
|
'Deu': 'Deutsch',
|
||||||
|
'deu1': 'Deutsch 1',
|
||||||
|
'deu2': 'Deutsch 2',
|
||||||
|
'deu3': 'Deutsch 3',
|
||||||
|
'Lme': 'Lernmethoden',
|
||||||
|
'Eth': 'Ethik',
|
||||||
|
'EvR': 'Evangelische Religion',
|
||||||
|
'Soz': 'Sozialkunde',
|
||||||
|
'Ast': 'Astronomie',
|
||||||
|
'Spa': 'Spanisch',
|
||||||
|
'FK': 'Fachkurs',
|
||||||
|
'JIA': 'Junior-Ingenieur-Akademie',
|
||||||
|
'WoU': 'Wahlobligatorischer Unterricht'
|
||||||
|
};
|
||||||
|
|
||||||
|
lessons.add(TimetableLesson(
|
||||||
|
value['St'],
|
||||||
|
names[name] ?? name.toString(),
|
||||||
|
teachers[teacher] ?? teacher.toString(),
|
||||||
|
room.toString(),
|
||||||
|
value['If'].toString(),
|
||||||
|
colors[name] ?? Colors.grey[700],
|
||||||
|
fontColor,
|
||||||
|
info));
|
||||||
|
});
|
||||||
|
|
||||||
|
return ClassTimetable(timetable: lessons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimetableLesson {
|
||||||
|
final int count;
|
||||||
|
final String name;
|
||||||
|
final String teacher;
|
||||||
|
final String room;
|
||||||
|
final String comment;
|
||||||
|
final Color color;
|
||||||
|
final Color fontColor;
|
||||||
|
final String info;
|
||||||
|
const TimetableLesson(this.count, this.name, this.teacher, this.room,
|
||||||
|
this.comment, this.color, this.fontColor, this.info);
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
||||||
#define GENERATED_PLUGIN_REGISTRANT_
|
#define GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.0.0+1
|
version: 0.6.5-alpha
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
||||||
#define GENERATED_PLUGIN_REGISTRANT_
|
#define GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user