==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.
|
||||
//
|
||||
|
||||
// ignore_for_file: directives_ordering
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
import 'package:fluttertoast/fluttertoast_web.dart';
|
||||
|
@ -2,15 +2,15 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'networking.dart';
|
||||
import 'Dashboard.dart';
|
||||
import 'dashboard.dart';
|
||||
|
||||
Future<bool> checkKey() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String? api_key = await prefs.getString('api_key');
|
||||
return api_key != null && api_key.isNotEmpty;
|
||||
String? apiKey = prefs.getString('api_key');
|
||||
return apiKey != null && apiKey.isNotEmpty;
|
||||
}
|
||||
|
||||
class Login extends StatelessWidget {
|
||||
@ -37,12 +37,12 @@ class Login extends StatelessWidget {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("Anmelden"),
|
||||
title: const Text("Anmelden"),
|
||||
),
|
||||
body: Center(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
|
||||
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
|
||||
child: Container(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth:
|
||||
@ -53,23 +53,27 @@ class Login extends StatelessWidget {
|
||||
children: [
|
||||
Image.asset("assets/images/meincantor_r.png",
|
||||
height: 192, width: 192),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
AutofillGroup(
|
||||
child: Column(
|
||||
children: [
|
||||
TextField(
|
||||
autofillHints: [AutofillHints.username],
|
||||
decoration: InputDecoration(
|
||||
autofillHints: const [
|
||||
AutofillHints.username
|
||||
],
|
||||
decoration: const InputDecoration(
|
||||
icon: Icon(CupertinoIcons.person),
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Benutzername',
|
||||
),
|
||||
controller: userController,
|
||||
),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
TextField(
|
||||
autofillHints: [AutofillHints.password],
|
||||
decoration: InputDecoration(
|
||||
autofillHints: const [
|
||||
AutofillHints.password
|
||||
],
|
||||
decoration: const InputDecoration(
|
||||
icon: Icon(CupertinoIcons.lock),
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Passwort',
|
||||
@ -79,9 +83,9 @@ class Login extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
)),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
decoration: const InputDecoration(
|
||||
icon: Icon(CupertinoIcons.lock),
|
||||
border: OutlineInputBorder(),
|
||||
labelText: '2F2-Code (OTP) [falls aktiviert]',
|
||||
@ -89,37 +93,55 @@ class Login extends StatelessWidget {
|
||||
obscureText: true,
|
||||
controller: otpController,
|
||||
),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
decoration: const InputDecoration(
|
||||
icon: Icon(CupertinoIcons.device_laptop),
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Gerätebezeichnung',
|
||||
),
|
||||
controller: devIdController,
|
||||
),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
OutlinedButton(
|
||||
onPressed: () async {
|
||||
SharedPreferences prefs =
|
||||
await SharedPreferences.getInstance();
|
||||
String api_key = await getToken(
|
||||
Response loginResponse = await getToken(
|
||||
userController.text,
|
||||
passwordController.text,
|
||||
otpController.text,
|
||||
devIdController.text);
|
||||
print('Set new API key to $api_key');
|
||||
await prefs.setString('api_key', api_key);
|
||||
dynamic userinfo = jsonDecode(
|
||||
await getUserInfo(
|
||||
userController.text,
|
||||
passwordController.text,
|
||||
otpController.text,
|
||||
devIdController.text));
|
||||
await prefs.setString(
|
||||
'user', userinfo['preferred_username']);
|
||||
await prefs.setString(
|
||||
'name', userinfo['name']);
|
||||
if (loginResponse.statusCode == 200) {
|
||||
String apiKey = jsonDecode(utf8.decode(
|
||||
loginResponse.bodyBytes))['token'];
|
||||
print('Set new API key to $apiKey');
|
||||
await prefs.setString('api_key', apiKey);
|
||||
dynamic userinfo = jsonDecode(
|
||||
await getUserInfo(
|
||||
userController.text,
|
||||
passwordController.text,
|
||||
otpController.text,
|
||||
devIdController.text));
|
||||
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 &&
|
||||
prefs
|
||||
.getString('api_key')!
|
||||
@ -127,18 +149,15 @@ class Login extends StatelessWidget {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
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/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'Dashboard.dart';
|
||||
import 'Login.dart';
|
||||
import 'dashboard.dart';
|
||||
import 'login.dart';
|
||||
import 'dart:math';
|
||||
|
||||
void main() => runApp(App());
|
||||
void main() => runApp(const App());
|
||||
|
||||
class App extends StatelessWidget {
|
||||
const App({Key? key}) : super(key: key);
|
||||
|
||||
MaterialColor generateMaterialColor(Color color) {
|
||||
return MaterialColor(color.value, {
|
||||
50: tintColor(color, 0.5),
|
||||
@ -38,47 +40,40 @@ class App extends StatelessWidget {
|
||||
theme: ThemeData(
|
||||
primaryColor: Palette.primary,
|
||||
colorScheme: ColorScheme.fromSwatch(
|
||||
primarySwatch: generateMaterialColor(Palette.accent),
|
||||
primarySwatch: generateMaterialColor(Palette.primary),
|
||||
).copyWith(
|
||||
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",
|
||||
home: buildHomePage(),
|
||||
/*
|
||||
routes: <String, WidgetBuilder>{
|
||||
"/": (_) => Dashboard(),
|
||||
"/login": (_) => Login()
|
||||
},
|
||||
|
||||
*/
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> apiKeyEmpty() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String? api_key = await prefs.getString("api_key");
|
||||
return api_key == null || api_key.isEmpty;
|
||||
String? apiKey = prefs.getString("api_key");
|
||||
return apiKey == null || apiKey.isEmpty;
|
||||
}
|
||||
|
||||
Widget buildHomePage() {
|
||||
return FutureBuilder(
|
||||
future: apiKeyEmpty(),
|
||||
builder: (context, snapshot) {
|
||||
if(snapshot.data == true) {
|
||||
return Login();
|
||||
} else if(snapshot.data == false) {
|
||||
return Dashboard();
|
||||
} else {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
}
|
||||
}
|
||||
);
|
||||
future: apiKeyEmpty(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.data == true) {
|
||||
return Login();
|
||||
} else if (snapshot.data == false) {
|
||||
return const Dashboard();
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class Palette {
|
||||
static const Color primary = Color(0xFF1A1A37);
|
||||
static const Color accent = Color(0xFFFFBC3B);
|
||||
static const Color primary = Color(0xFF1A1A37);
|
||||
static const Color accent = Color(0xFFFFBC3B);
|
||||
}
|
@ -1,39 +1,21 @@
|
||||
import 'dart:convert';
|
||||
import 'main.dart';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'Timetable.dart';
|
||||
import 'Login.dart';
|
||||
import 'timetable.dart';
|
||||
import 'login.dart';
|
||||
import 'main.dart';
|
||||
|
||||
Future<String> getToken(
|
||||
Future<http.Response> getToken(
|
||||
String user, String password, String otp, String devId) async {
|
||||
var uri = Uri.https("mein.cantorgymnasium.de", "/login");
|
||||
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 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');
|
||||
}
|
||||
return (response);
|
||||
}
|
||||
|
||||
Future<String> getUserInfo(
|
||||
@ -53,18 +35,36 @@ Future<String> getUserInfo(
|
||||
|
||||
Future<http.Response> fetchClassTimetable() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
var class_num;
|
||||
String classNum;
|
||||
print(prefs.getString('class_num'));
|
||||
if (prefs.getString('class_num') != null) {
|
||||
class_num = prefs.getString('class_num')!;
|
||||
classNum = prefs.getString('class_num')!.replaceAll("/", "_");
|
||||
} else {
|
||||
class_num = '07_1';
|
||||
classNum = '05_1';
|
||||
}
|
||||
var api_key = prefs.getString('api_key');
|
||||
var uri = Uri.https("mein.cantorgymnasium.de", "/api/timetable/$class_num");
|
||||
var headers = {"x-api-key": "$api_key"};
|
||||
var apiKey = prefs.getString('api_key');
|
||||
var uri = Uri.https("mein.cantorgymnasium.de", "/api/timetable/$classNum");
|
||||
var headers = {"x-api-key": "$apiKey"};
|
||||
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;
|
||||
}
|
||||
|
||||
@ -79,15 +79,148 @@ Widget buildClassTimetable() {
|
||||
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)))
|
||||
.view;
|
||||
return timetableView;
|
||||
}
|
||||
else if(statusCode == 400) {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => Login()));
|
||||
} 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.")),
|
||||
);
|
||||
}
|
||||
return Center(child: Text('Error $statusCode'));
|
||||
} else if (snapshot.hasError) {
|
||||
return Text('$snapshot.error');
|
||||
} 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 {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
/*
|
||||
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 apiKey = prefs.getString('api_key');
|
||||
var uri = Uri.https("mein.cantorgymnasium.de", "/api/classes");
|
||||
var headers = {"x-api-key": "$api_key"};
|
||||
var headers = {"x-api-key": "$apiKey"};
|
||||
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;
|
||||
}
|
||||
|
||||
@ -120,20 +243,30 @@ Widget buildClassesChooser() {
|
||||
if (snapshot.hasData) {
|
||||
int statusCode = snapshot.data!.statusCode;
|
||||
if (statusCode == 200) {
|
||||
// List<Widget> children = [];
|
||||
//ClassTimetable.fromJson(jsonDecode(utf8.decode(snapshot.data!.bodyBytes))).timetable.forEach((element) {
|
||||
//});
|
||||
List<String> items = [];
|
||||
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)).forEach((value) {
|
||||
items.add(value..toString());
|
||||
});
|
||||
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');
|
||||
} else if (snapshot.hasError) {
|
||||
return Text('$snapshot.error');
|
||||
} else {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
},
|
||||
);
|
||||
@ -150,37 +283,38 @@ class ClassesChooser extends StatefulWidget {
|
||||
class _ClassesChooserState extends State<ClassesChooser> {
|
||||
final List<String> items;
|
||||
//final String dropdownValue;
|
||||
var dropdownValue;
|
||||
String? dropdownValue;
|
||||
_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
|
||||
Widget build(BuildContext context) {
|
||||
// var dropdown_items =
|
||||
return DropdownButtonFormField<String>(
|
||||
// value: dropdownValue,
|
||||
/*icon: const Icon(Icons.arrow_downward),
|
||||
iconSize: 24,
|
||||
elevation: 16,*/
|
||||
// style: const TextStyle(color: Color(0xFFFFBC3B)),
|
||||
/*underline: Container(
|
||||
height: 2,
|
||||
color: Color(0xFFFFBC3B),
|
||||
)
|
||||
*/
|
||||
decoration: InputDecoration(
|
||||
value: dropdownValue,
|
||||
decoration: const InputDecoration(
|
||||
icon: Icon(CupertinoIcons.number),
|
||||
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) {
|
||||
setState(() async {
|
||||
dropdownValue = newValue!;
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String class_num = newValue;
|
||||
print('Set new class to $class_num');
|
||||
await prefs.setString('class_num', class_num);
|
||||
String classNum = newValue;
|
||||
print('Set new class to $classNum');
|
||||
await prefs.setString('class_num', classNum);
|
||||
});
|
||||
},
|
||||
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.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Generated file. Do not edit.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef 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.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.0.0+1
|
||||
version: 0.6.5-alpha
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Generated file. Do not edit.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Generated file. Do not edit.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
||||
#define GENERATED_PLUGIN_REGISTRANT_
|
||||
|
||||
|
Reference in New Issue
Block a user