==0.7.5==

- added A LOT, TLTD
Settings menu, updated homepage tiles, added color settings...
- TODO:
  - update README
  - update license & copyright info
  - cleanup code
  - merge code parts to server side
  - complete settings
  - fix 11/12
  - add caching
  - muuuuuuuch more...
This commit is contained in:
Denys Konovalov 2021-11-06 11:01:44 +01:00
parent bae624dd67
commit 6ad143195a
19 changed files with 1213 additions and 317 deletions

@ -44,7 +44,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "de.cantorgymnasium.meincantor"
minSdkVersion 16
minSdkVersion 18
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

@ -0,0 +1,23 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class AppearanceSettings extends StatelessWidget {
const AppearanceSettings({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Aussehen"),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
children: [
],
));
}
}

@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../login.dart';
class DevSettings extends StatelessWidget {
const DevSettings({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Entwickler-Einstellungen"),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: TextField(
decoration: const InputDecoration(
icon: Icon(MdiIcons.keyOutline),
border: OutlineInputBorder(),
labelText: 'MeinCantor API-Schlüssel',
),
onSubmitted: (String value) async {
SharedPreferences prefs =
await SharedPreferences.getInstance();
String apiKey = value;
await prefs.setString('api_key', apiKey);
final snackBar = SnackBar(
content: Text('Neuer API-Schlüssel gesetzt: $apiKey'));
// Find the ScaffoldMessenger in the widget tree
// and use it to show a SnackBar.
ScaffoldMessenger.of(context)
.showSnackBar(snackBar);
})),
const Divider(),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: OutlinedButton(
onPressed: () async {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Login()),
);
},
child: const Text("Benutzerdaten neu laden"),
)
)
],
));
}
}

@ -0,0 +1,75 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:MeinCantor/const.dart';
class InfoSettings extends StatelessWidget {
const InfoSettings({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Informationen"),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
children: [
const ListTile(
leading: Icon(Icons.info_outlined),
title: Text("Version"),
subtitle: Text(version)
),
ListTile(
leading: const Icon(Icons.settings_backup_restore_outlined),
title: const Text("Änderungsverlauf"),
onTap: () {
showModalBottomSheet<void>(
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Container(
height: 400,
//color: Colors.amber,
child: Column(
//mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
AppBar(
title: const Text("Änderungsverlauf"),
),
const Padding(
padding: EdgeInsets.all(10),
child: Text(""),
),
/*ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
)*/
],
),
);
},
);
},
),
ListTile(
leading: const Icon(Icons.copyright_outlined),
title: const Text("Lizenzen"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LicensePage(
applicationIcon: Image.asset("assets/images/meincantor_r.png",
height: 64, width: 64),
applicationVersion: version,
)),
);
},
),
],
));
}
}

@ -0,0 +1,177 @@
import 'dart:convert';
import 'package:MeinCantor/main.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cyclop/cyclop.dart';
import 'package:MeinCantor/networking.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../color_presets.dart';
import 'package:MeinCantor/subject_presets.dart';
import '../../teacher_presets.dart';
class PlanSettings extends StatefulWidget {
const PlanSettings({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _PlanSettingsState();
}
Future<Color> buildPlanColors(lesson) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey("color$lesson")) {
prefs.setInt("color$lesson", colors[lesson].value ?? Colors.grey.value);
}
await fetchLessonList();
Color colorDeu = Color(prefs.getInt("color$lesson")!);
return colorDeu;
}
Future<List<dynamic>> buildLessonsList() async {
await fetchLessonList();
SharedPreferences prefs = await SharedPreferences.getInstance();
String lessonsJson = prefs.getString("lessons")!;
List<dynamic> lessons = jsonDecode(lessonsJson);
return lessons;
}
class _PlanSettingsState extends State<PlanSettings> {
Set<Color> swatches = {...Colors.primaries, ...Colors.accents, Palette.accent, Palette.primary};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Plan"),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
children: [
const ListTile(
title: Text("Kurse/Fächer"),
leading: Icon(Icons.list_alt_outlined),
),
FutureBuilder(
future: buildLessonsList(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Widget> children = [];
for (var element in (snapshot.data as List<dynamic>)) {
String subject = element['subject'];
String teacher = element['teacher'];
children.add(FutureBuilder(
future: buildPlanColors(subject),
builder: (context, snapshot) {
if (snapshot.hasData) {
Color color = snapshot.data as Color;
return ListTile(
leading: ColorButton(
key: const Key('c1'),
color: color,
config: const ColorPickerConfig(
enableEyePicker: false),
onSwatchesChanged: (Set<Color> value) {
swatches = value;
},
size: 32,
swatches: swatches,
onColorChanged: (Color value) async {
setState(() {
color = value;
});
SharedPreferences prefs = await SharedPreferences
.getInstance();
prefs.setInt(
"color$subject", value.value);
}
),
title: Text(names[subject] ?? ""),
subtitle: Text(teachers[teacher] ?? ""),
);
} else {
return (const LinearProgressIndicator());
}
}
),
);
}
return Column(
children: children,
);
} else {
return (const Center(
child: CircularProgressIndicator()));
}
}
),
/*FutureBuilder(
future: buildPlanColors("Mat"),
builder: (context, snapshot) {
if (snapshot.hasData) {
Color color = snapshot.data as Color;
return ListTile(
leading: ColorButton(
key: const Key('c1'),
color: color,
//boxShape: BoxShape.circle, // default : circle
config: const ColorPickerConfig(enableEyePicker: false),
onSwatchesChanged: (Set<Color> value) {
swatches = value;
},
size: 32,
swatches: swatches,
onColorChanged: (Color value) async {
setState(() {
color = value;
});
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setInt("colorMat", value.value);
}
),
title: const Text("Mathematik"),
);
} else {
return (const Center(child: CircularProgressIndicator()));
}
}
),
FutureBuilder(
future: buildPlanColors("Bio"),
builder: (context, snapshot) {
if (snapshot.hasData) {
Color color = snapshot.data as Color;
return ListTile(
leading: ColorButton(
key: const Key('c1'),
color: color,
//boxShape: BoxShape.circle, // default : circle
config: const ColorPickerConfig(enableEyePicker: false),
onSwatchesChanged: (Set<Color> value) {
swatches = value;
},
size: 32,
swatches: swatches,
onColorChanged: (Color value) async {
setState(() {
color = value;
});
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setInt("colorBio", value.value);
}
),
title: const Text("Biologie"),
);
} else {
return (const Center(child: CircularProgressIndicator()));
}
}
),*/
],
)
);
}
}

@ -0,0 +1,23 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ServiceSettings extends StatelessWidget {
const ServiceSettings({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Dienste"),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
children: [
],
));
}
}

@ -0,0 +1,68 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:MeinCantor/networking.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<String> getSettingsString(String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? value = prefs.getString(key);
if (value == null || value.isEmpty) {
value = "";
}
return value;
}
class UserSettings extends StatelessWidget {
const UserSettings({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
//TextEditingController nameController = TextEditingController(text: "Denys Konovalov");
return Scaffold(
appBar: AppBar(
title: const Text("Benutzereinstellungen"),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Container(
width: 128.0,
height: 128.0,
decoration: const BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.scaleDown,
image: AssetImage("assets/images/meincantor_r.png")
)
)
),
),
FutureBuilder(
future: getSettingsString("name"),
builder: (context, snapshot) {
if (snapshot.hasData) {
return TextField(
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Name',
),
readOnly: true,
controller: TextEditingController(text: snapshot.data as String),
);
} else {
return (const Center(child: CircularProgressIndicator()));
}
}
),
Padding(
padding: const EdgeInsets.fromLTRB(5, 20, 5, 5),
child: buildClassesChooser()
),
],
));
}
}

100
lib/Settings/dashboard.dart Normal file

@ -0,0 +1,100 @@
import 'package:MeinCantor/Settings/Pages/appearance_settings.dart';
import 'package:MeinCantor/Settings/Pages/service_settings.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'Pages/dev_settings.dart';
import 'Pages/info_settings.dart';
import 'Pages/plan_settings.dart';
import 'Pages/user_settings.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(5, 5, 5, 5),
children: [
ListTile(
leading: const Icon(MdiIcons.accountSettingsOutline, color: Colors.cyan),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
title: const Text("Benutzer"),
subtitle: const Text("Profilbild, Klasse & mehr"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const UserSettings()),
);
},
),
ListTile(
leading: const Icon(MdiIcons.timetable, color: Colors.orangeAccent),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
title: const Text("Plan"),
subtitle: const Text("Kurse/Fächer, Farben & mehr"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const PlanSettings()),
);
},
),
ListTile(
leading: const Icon(Icons.color_lens_outlined, color: Colors.pinkAccent),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
title: const Text("Aussehen"),
subtitle: const Text("Widgets, Design & mehr"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const AppearanceSettings()),
);
},
),
ListTile(
leading: const Icon(MdiIcons.server, color: Colors.lightGreen),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
title: const Text("Dienste"),
subtitle: const Text("Konten, Plattformen & mehr"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const ServiceSettings()),
);
},
),
ListTile(
leading: const Icon(Icons.developer_mode_outlined, color: Colors.deepOrangeAccent),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
title: const Text("Entwickleroptionen"),
subtitle: const Text("API, Benutzerdaten & mehr"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const DevSettings()),
);
},
),
ListTile(
leading: const Icon(Icons.info_outlined, color: Colors.greenAccent),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
title: const Text("Informationen"),
subtitle: const Text("Version, Lizenzen & mehr"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const InfoSettings()),
);
},
),
],
));
}
}

45
lib/color_presets.dart Normal file

@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
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
};

@ -7,10 +7,13 @@ 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 'Settings/dashboard.dart';
// import 'settings.dart';
import 'main.dart';
import 'networking.dart';
import 'login.dart';
import 'schuelerzeitung.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
class Dashboard extends StatefulWidget {
const Dashboard({Key? key, this.restorationId}) : super(key: key);
@ -31,7 +34,7 @@ Future<String> getSettingsString(String key) async {
return value;
}
Widget buildSettingsString(String key, TextStyle style) {
Widget buildSettingsString(String key, TextStyle? style) {
return FutureBuilder(
future: getSettingsString(key),
builder: (context, snapshot) {
@ -52,9 +55,10 @@ class _DashboardState extends State<Dashboard> with RestorationMixin {
UserAccountsDrawerHeader(
accountName: buildSettingsString('name', const TextStyle()),
accountEmail: buildSettingsString('user', const TextStyle()),
currentAccountPicture: const CircularProgressIndicator(
currentAccountPicture: Image.asset("assets/images/meincantor_r.png")
/*const CircularProgressIndicator(
backgroundColor: Colors.black,
),
),*/
),
ListTile(
title: const Text("Einstellungen"),
@ -64,7 +68,7 @@ class _DashboardState extends State<Dashboard> with RestorationMixin {
MaterialPageRoute(builder: (context) => Settings()),
);
},
leading: const Icon(CupertinoIcons.settings),
leading: const Icon(Icons.settings_outlined),
),
ListTile(
title: const Text("Abmelden"),
@ -78,31 +82,20 @@ class _DashboardState extends State<Dashboard> with RestorationMixin {
},
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),
icon: Icon(MdiIcons.homeOutline),
label: "Startseite",
),
const BottomNavigationBarItem(
icon: Icon(CupertinoIcons.rectangle_grid_1x2),
icon: Icon(MdiIcons.timetable),
label: "Vertretungsplan"),
const BottomNavigationBarItem(
icon: Icon(Icons.notifications_outlined),
label: "Hinweise"
),
];
return Scaffold(
appBar: AppBar(
@ -256,13 +249,159 @@ class _DashboardBottomNavView extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(20, 20, 20, 10),
child: buildTodayClassTimetableLesson(lessonCount),
),
Row(mainAxisSize: MainAxisSize.max, children: [
Expanded(
child: Padding(
Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 10),
child: Column(
child: Wrap(
children: [
GestureDetector(
SizedBox(
child: GestureDetector(
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SZ()),
);
},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: const Padding(
padding: EdgeInsets.all(10),
child: ListTile(
title: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Icon(
MdiIcons.newspaper,
color: Palette.accent,
size: 48,
),
),
subtitle: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
child: Text(
'Schülerzeitung',
),
),
),
),
)
),
),
width: 175,
),
SizedBox(
width: 175,
child: GestureDetector(
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SB()),
);
},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: const Padding(
padding: EdgeInsets.all(10),
child: ListTile(
title: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Icon(
MdiIcons.libraryShelves,
color: Palette.accent,
size: 48,
),
),
subtitle: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
child: Text(
'Schulbibliothek',
),
),
),
),
)
),
),
),
SizedBox(
width: 175,
child: GestureDetector(
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SC()),
);
},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: const Padding(
padding: EdgeInsets.all(10),
child: ListTile(
title: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Icon(
MdiIcons.laptop,
color: Palette.accent,
size: 48,
),
),
subtitle: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
child: Text(
'Schulcomputer',
),
),
),
),
)
),
),
),
SizedBox(
width: 175,
child: GestureDetector(
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const RoomOverview()),
);
},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: const Padding(
padding: EdgeInsets.all(10),
child: ListTile(
title: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Icon(
MdiIcons.door,
color: Palette.accent,
size: 48,
),
),
subtitle: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
child: Text(
'Raumübersicht',
),
),
),
),
)
),
),
)
/*GestureDetector(
onTap: () async {
Navigator.push(
context,
@ -276,27 +415,28 @@ class _DashboardBottomNavView extends StatelessWidget {
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.max,
//mainAxisSize: MainAxisSize.max,
children: const [
Padding(
padding: EdgeInsets.fromLTRB(20, 20, 10, 10),
padding: EdgeInsets.fromLTRB(20, 20, 20, 10),
child: Icon(
CupertinoIcons.news,
color: Color(0xFFFFBC3B),
MdiIcons.newspaper,
color: Palette.accent,
size: 48,
),
)
],
),
Row(
mainAxisSize: MainAxisSize.max,
//mainAxisSize: MainAxisSize.max,
children: const [
Align(
alignment: Alignment(0, 0),
child: Padding(
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
padding: EdgeInsets.fromLTRB(15, 50, 15, 15),
child: Text(
'Schülerzeitung',
),
@ -320,35 +460,37 @@ class _DashboardBottomNavView extends StatelessWidget {
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',
),
)
],
)
],
),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: const [
Padding(
padding: EdgeInsets.fromLTRB(20, 20, 20, 10),
child: Icon(
MdiIcons.libraryShelves,
color: Color(0xFFFFBC3B),
size: 48,
),
)
],
),
Row(
mainAxisSize: MainAxisSize.max,
children: const [
Padding(
padding: EdgeInsets.fromLTRB(15, 50, 15, 15),
child: Text(
'Schulbibliothek',
),
)
],
)
],
),
)
),
),
GestureDetector(
@ -370,9 +512,9 @@ class _DashboardBottomNavView extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
children: const [
Padding(
padding: EdgeInsets.fromLTRB(20, 20, 10, 10),
padding: EdgeInsets.fromLTRB(20, 20, 20, 10),
child: Icon(
CupertinoIcons.device_laptop,
MdiIcons.laptop,
color: Color(0xFFFFBC3B),
size: 48,
),
@ -383,7 +525,7 @@ class _DashboardBottomNavView extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
children: const [
Padding(
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
padding: EdgeInsets.fromLTRB(15, 50, 15, 15),
child: Text(
'Schulcomputer',
),
@ -413,9 +555,9 @@ class _DashboardBottomNavView extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
children: const [
Padding(
padding: EdgeInsets.fromLTRB(20, 20, 10, 10),
padding: EdgeInsets.fromLTRB(20, 20, 20, 10),
child: Icon(
CupertinoIcons.house_alt,
MdiIcons.door,
color: Color(0xFFFFBC3B),
size: 48,
),
@ -426,7 +568,7 @@ class _DashboardBottomNavView extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
children: const [
Padding(
padding: EdgeInsets.fromLTRB(15, 50, 0, 15),
padding: EdgeInsets.fromLTRB(15, 50, 15, 15),
child: Text(
'Raumübersicht',
),
@ -436,14 +578,12 @@ class _DashboardBottomNavView extends StatelessWidget {
],
),
),
),
),*/
],
),
),
)
]),
],
));
);
return view;
} else if (item.label == "Vertretungsplan") {
return LayoutBuilder(builder: (context, constraints) {
@ -471,7 +611,7 @@ class _DashboardBottomNavView extends StatelessWidget {
),
child: DefaultTabController(
initialIndex: 0,
length: 2,
length: 3,
child: Scaffold(
appBar: AppBar(
elevation: 0,
@ -481,6 +621,10 @@ class _DashboardBottomNavView extends StatelessWidget {
text: "Heute",
icon: Icon(CupertinoIcons.calendar_today),
),
Tab(
text: "Morgen",
icon: Icon(CupertinoIcons.calendar_today),
),
Tab(
text: "Neuster Plan",
icon: Icon(CupertinoIcons.calendar),
@ -495,12 +639,8 @@ class _DashboardBottomNavView extends StatelessWidget {
body: TabBarView(
children: <Widget>[
buildTodayClassTimetable(),
buildTomorrowClassTimetable(),
buildClassTimetable(),
/*
Center(
child: Text("It's sunny here"),
),
*/
],
),
),
@ -509,8 +649,7 @@ class _DashboardBottomNavView extends StatelessWidget {
);
});
} else {
return const Text("Such page does not exist.");
return const Center(child: Text("Derzeit nichts hier..."));
}
// return materialCard(item.label);
}
}
}

@ -24,7 +24,7 @@ class Login extends StatelessWidget {
return LayoutBuilder(
builder: (context, constraints) {
double widgetWidth = constraints.maxWidth;
double widgetHeight = constraints.maxHeight;
//double widgetHeight = constraints.maxHeight;
var factor;
if (widgetWidth <= 600) {
@ -93,7 +93,7 @@ class Login extends StatelessWidget {
obscureText: true,
controller: otpController,
),
const Divider(),
/*const Divider(),
TextField(
decoration: const InputDecoration(
icon: Icon(CupertinoIcons.device_laptop),
@ -101,7 +101,7 @@ class Login extends StatelessWidget {
labelText: 'Gerätebezeichnung',
),
controller: devIdController,
),
),*/
const Divider(),
OutlinedButton(
onPressed: () async {
@ -146,12 +146,14 @@ class Login extends StatelessWidget {
prefs
.getString('api_key')!
.isNotEmpty) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
const Dashboard()),
);
Future.delayed(Duration.zero, () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
const Dashboard()),
);
});
}
},
child: const Text("Anmelden"))

@ -46,7 +46,7 @@ class App extends StatelessWidget {
),
),
darkTheme: ThemeData.from(
colorScheme: const ColorScheme.dark(primary: Palette.accent)),
colorScheme: const ColorScheme.dark(primary: Palette.accent, secondary: Palette.accent)),
title: "GCG.MeinCantor",
home: buildHomePage(),
);

@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/painting.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -68,6 +69,45 @@ Future<http.Response> fetchTodayClassTimetable() async {
return response;
}
Future<http.Response> fetchTomorrowClassTimetable() 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/tomorrow");
var headers = {"x-api-key": "$apiKey"};
print(uri);
final response = http.get(uri, headers: headers).onError((error, stackTrace) { return(http.Response("", 404)); } );
return response;
}
fetchLessonList() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String classNum;
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/lessons/$classNum");
var headers = {"x-api-key": "$apiKey"};
final response = await http.get(uri, headers: headers).onError((error, stackTrace) { return(http.Response("", 404)); } );
if (response.statusCode == 200) {
prefs.setString("lessons", utf8.decode(response.bodyBytes));
} else {
prefs.setString("lessons", jsonEncode([]));
}
}
Widget buildClassTimetable() {
return FutureBuilder<http.Response>(
future: fetchClassTimetable(),
@ -75,9 +115,9 @@ Widget buildClassTimetable() {
if (snapshot.hasData) {
int statusCode = snapshot.data!.statusCode;
if (statusCode == 200) {
ListView timetableView = ClassTimetableBuilder.buildView(
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)))
.view;
Widget timetableView = ClassTimetableBuilder.buildView(
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)), context)
.view.child;
return timetableView;
} else if (statusCode == 400) {
Navigator.pushReplacement(
@ -110,18 +150,93 @@ Widget buildTodayClassTimetable() {
if (snapshot.hasData) {
int statusCode = snapshot.data!.statusCode;
if (statusCode == 200) {
ListView timetableView = ClassTimetableBuilder.buildView(
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)))
.view;
Widget timetableView = ClassTimetableBuilder.buildView(
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)), context)
.view.child;
return timetableView;
} else if (statusCode == 400) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Login()));
} else if (statusCode == 500) {
var chars = Runes('Es konnte kein Vertretungsplan für heute gefunden werden. \u{1F937}');
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 Padding(
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
child: ListView(
children: [card],
)
);
} else if (statusCode == 404) {
return const Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Center(child: Text("Es konnte kein Vertretungsplan für heute gefunden werden.")),
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 buildTomorrowClassTimetable() {
return FutureBuilder<http.Response>(
future: fetchTomorrowClassTimetable(),
builder: (context, snapshot) {
if (snapshot.hasData) {
int statusCode = snapshot.data!.statusCode;
if (statusCode == 200) {
Widget timetableView = ClassTimetableBuilder.buildView(
jsonDecode(utf8.decode(snapshot.data!.bodyBytes)), context)
.view.child;
return timetableView;
} else if (statusCode == 400) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Login()));
} else if (statusCode == 500) {
var chars = Runes('Es konnte kein Vertretungsplan für morgen gefunden werden. \u{1F937}');
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 Padding(
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
child: ListView(
children: [card],
)
);
/*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),
@ -153,10 +268,25 @@ Widget buildClassTimetableLesson(int count) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Login()));
} else if (statusCode == 500) {
return const Padding(
var chars = Runes('Es konnte kein Vertretungsplan für gefunden werden. \u{1F937}');
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;
/*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),
@ -203,13 +333,34 @@ Widget buildTodayClassTimetableLesson(int count) {
return card;
}
} else if (statusCode == 400) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Login()));
Future.delayed(Duration.zero, () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Login()),
);
});
} else if (statusCode == 500) {
return const Padding(
var chars = Runes('Es konnte kein Vertretungsplan für heute gefunden werden. \u{1F937}');
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;
/*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),
@ -304,7 +455,7 @@ class _ClassesChooserState extends State<ClassesChooser> {
return DropdownButtonFormField<String>(
value: dropdownValue,
decoration: const InputDecoration(
icon: Icon(CupertinoIcons.number),
icon: Icon(Icons.people_outline),
border: OutlineInputBorder(),
labelText: 'Klasse (05/1, 07/3, 10/2...)',
),

@ -11,8 +11,64 @@ class SZ extends StatelessWidget {
title: const Text("Schülerzeitung"),
centerTitle: true,
),
body: const Center(
body: ListView(
children: [
Card(
child: Column(children: [
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
child: ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Article()),
);
},
title: const Text(
"Schülersprecherwahl 2021: Kandidatenduos im Interview",
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: const Text(
"17.09.2021, Halle(Saale) Drei Trios stellen sich dieses Jahr zur Wahl...")),
)
]),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
)
],
)
/*const Center(
child: Text("Derzeit nichts hier..."),
)*/
);
}
}
class Article extends StatelessWidget {
const Article({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
"Schülersprecherwahl 2021: Kandidatenduos im Interview"),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
children: const [
Text("""
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer
""")
],
));
}
}

@ -1,65 +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 {
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(),
],
));
}
}

33
lib/subject_presets.dart Normal file

@ -0,0 +1,33 @@
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',
'frz2': 'Französisch 2',
'frz3': 'Französisch 3',
'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'
};

55
lib/teacher_presets.dart Normal file

@ -0,0 +1,55 @@
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',
'&nbsp;': '',
'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 Schettler',
'Mani': 'Herr Manigk',
'Segg': 'Frau von 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',
'Gitt': 'Herr Gitter',
};

@ -1,17 +1,82 @@
import 'package:MeinCantor/teacher_presets.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'subject_presets.dart';
import 'color_presets.dart';
class ClassTimetableBuilder {
final ListView view;
final RefreshIndicator view;
ClassTimetableBuilder({required this.view});
factory ClassTimetableBuilder.buildView(Map<String, dynamic> json) {
factory ClassTimetableBuilder.buildView(Map<String, dynamic> json, BuildContext context) {
List<Widget> list = LessonsListBuilder.buildList(json).lessons;
String info = TimetableInfo.fromJson(json).info;
if(info.isNotEmpty) {
list.insert(0, ListTile(title: Text("Informationen"), leading: Icon(MdiIcons.information), onTap: () {
showModalBottomSheet<void>(
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
context: context,
builder: (BuildContext context) {
return Container(
height: 400,
child: ListView(
//mainAxisAlignment: MainAxisAlignment.center,
//mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text("Informationen", style: TextStyle(fontWeight: FontWeight.bold)),
leading: Icon(Icons.arrow_back),
onTap: () {
Navigator.of(context).pop();
},
),
Padding(
padding: const EdgeInsets.all(20),
child: Text(info),
),
/*ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
)*/
],
),
);
},
);
},
)
);
}
return ClassTimetableBuilder(
view: ListView(
view: RefreshIndicator(
onRefresh: () {
return Future.delayed(const Duration(seconds: 1));
},
child: ListView(
//shrinkWrap: true,
physics: const AlwaysScrollableScrollPhysics(),
children: LessonsListBuilder.buildList(json).lessons));
children: list,
),
)
);
}
}
Future<Color> buildLessonColor(String lesson) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey("color$lesson")) {
Color lessonPresetColor = colors[lesson] ?? Colors.grey[700];
prefs.setInt("color$lesson", lessonPresetColor.value);
}
Color lessonColor = Color(prefs.getInt("color$lesson")!);
return lessonColor;
}
class LessonsListBuilder {
final List<Widget> lessons;
LessonsListBuilder({required this.lessons});
@ -21,7 +86,6 @@ class LessonsListBuilder {
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)),
@ -40,14 +104,23 @@ class LessonsListBuilder {
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,
));
Widget card = FutureBuilder(
future: element.color,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
color: snapshot.data as Color,
child: Column(
children: cardChildren,
));
} else {
return (const Center(child: CircularProgressIndicator()));
}
},
);
children.add(card);
}
});
@ -55,6 +128,14 @@ class LessonsListBuilder {
}
}
class TimetableInfo {
final String info;
TimetableInfo({required this.info});
factory TimetableInfo.fromJson(Map<String, dynamic> json) {
return TimetableInfo(info: json['info']);
}
}
class ClassTimetable {
final List timetable;
ClassTimetable({required this.timetable});
@ -65,60 +146,7 @@ class ClassTimetable {
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',
'&nbsp;': '',
'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 {
@ -156,81 +184,7 @@ class ClassTimetable {
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'
};
Future<Color> lessonColor = buildLessonColor(name);
lessons.add(TimetableLesson(
value['St'],
@ -238,7 +192,7 @@ class ClassTimetable {
teachers[teacher] ?? teacher.toString(),
room.toString(),
value['If'].toString(),
colors[name] ?? Colors.grey[700],
lessonColor,
fontColor,
info));
});
@ -253,7 +207,7 @@ class TimetableLesson {
final String teacher;
final String room;
final String comment;
final Color color;
final Future<Color> color;
final Color fontColor;
final String info;
const TimetableLesson(this.count, this.name, this.teacher, this.room,

@ -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: 0.6.5-alpha
version: 0.7.5-beta1.nightly2021-11-04
environment:
sdk: ">=2.12.0 <3.0.0"
@ -38,6 +38,9 @@ dependencies:
time: ^2.0.0
flutter_launcher_icons: "^0.9.1"
fluttertoast: ^8.0.8
flutter_colorpicker: ^0.6.0
material_design_icons_flutter: 5.0.5955-rc.1
cyclop: ^0.5.2
flutter_icons:
# image_path: "assets/images/icon-128x128.png"