initial commit

This commit is contained in:
2024-04-23 10:01:29 +02:00
parent e18472e116
commit 18bbdce261
9 changed files with 980 additions and 116 deletions
+172
View File
@@ -0,0 +1,172 @@
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:workinghours/data/publicHolidays.dart';
class Booking {
DateTime bookingDay;
DateTime come1;
DateTime leave1;
DateTime come2;
DateTime leave2;
DateTime come3;
DateTime leave3;
DateTime come4;
DateTime leave4;
DateTime come5;
DateTime leave5;
String code;
String information;
String holiday = '';
String dayLeft = '';
String dayRight = '';
String pause = '';
String durationIs = '';
String durationShould = '';
String diff = '';
String currentDiff = '';
String decimal = '';
Booking({
required this.bookingDay,
required this.come1,
required this.leave1,
required this.come2,
required this.leave2,
required this.come3,
required this.leave3,
required this.come4,
required this.leave4,
required this.come5,
required this.leave5,
required this.code,
required this.information,
}) {
PublicHolidays h = PublicHolidays(year: bookingDay.year);
holiday = h.holiday(bookingDay);
dayLeft = DateFormat('EEEE - dd').format(bookingDay);
dayRight = DateFormat('dd - EEEE').format(bookingDay);
pause = '';
durationIs = '';
durationShould = '';
diff = '';
currentDiff = '';
decimal = '';
}
// factory Booking.fromJson(Map<String, dynamic> json) {
// return Movie(
// movieID: int.parse(json['movieID']),
// movieTitle: json['movieTitle'] as String,
// overview: json['overview'] as String,
// releaseDate: DateTime.parse(json['releaseDate']),
// state: int.parse(json['state']),
// resolution: json['resolution'] as String,
// );
// }
}
class BookingDataSource extends DataGridSource {
/// Creates the employee data source class with required details.
BookingDataSource(this.booking) {
buildDataGridRow();
}
void buildDataGridRow() {
_bookingDataGridRows = booking
.map<DataGridRow>((e) => DataGridRow(cells: [
DataGridCell<String>(columnName: 'dayLeft', value: e.dayLeft),
DataGridCell<String>(columnName: 'holiday', value: e.holiday),
DataGridCell<String>(
columnName: 'come1',
value: e.come1.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.come1)),
DataGridCell<String>(
columnName: 'leave1',
value: e.leave1.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.leave1)),
DataGridCell<String>(
columnName: 'come2',
value: e.come2.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.come2)),
DataGridCell<String>(
columnName: 'leave2',
value: e.leave2.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.leave2)),
DataGridCell<String>(
columnName: 'come3',
value: e.come3.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.come3)),
DataGridCell<String>(
columnName: 'leave3',
value: e.leave3.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.leave3)),
DataGridCell<String>(
columnName: 'come4',
value: e.come4.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.come4)),
DataGridCell<String>(
columnName: 'leave4',
value: e.leave4.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.leave4)),
DataGridCell<String>(
columnName: 'come5',
value: e.come5.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.come5)),
DataGridCell<String>(
columnName: 'leave5',
value: e.leave5.year == 1900
? '99:99'
: DateFormat('hh:mm').format(e.leave5)),
DataGridCell<String>(columnName: 'pause', value: e.pause),
DataGridCell<String>(columnName: 'code', value: e.code),
DataGridCell<String>(
columnName: 'durationIs', value: e.durationIs),
DataGridCell<String>(
columnName: 'durationShould', value: e.durationShould),
DataGridCell<String>(columnName: 'diff', value: e.diff),
DataGridCell<String>(
columnName: 'information', value: e.information),
DataGridCell<String>(
columnName: 'currentDiff', value: e.currentDiff),
DataGridCell<String>(columnName: 'decimal', value: e.decimal),
DataGridCell<String>(columnName: 'dayRight', value: e.dayRight),
]))
.toList();
}
List<Booking> booking = [];
List<DataGridRow> _bookingDataGridRows = [];
@override
List<DataGridRow> get rows => _bookingDataGridRows;
@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((e) {
return Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8.0),
child: Text(e.value.toString() == '99:99' ? '' : e.value.toString()),
);
}).toList());
}
void updateDataGrid() {
notifyListeners();
}
}
+135
View File
@@ -0,0 +1,135 @@
import 'package:jiffy/jiffy.dart';
class PublicHolidays {
PublicHolidays({
required this.year,
}) {
holidayList[neujahr()] = 'Neujahr';
holidayList[heilige3koenige()] = 'Heilige 3 Könige';
holidayList[karfreitag()] = 'Karfreitag';
holidayList[ostersonntag()] = 'Ostersonntag';
holidayList[ostermontag()] = 'OsterMontag';
holidayList[staatsfeiertag1()] = 'Staatsfeiertag';
holidayList[christihimmelfahrt()] = 'Christi Himmelfahrt';
holidayList[pfingstsonntag()] = 'Pfingstsonntag';
holidayList[pfingstmontag()] = 'Pfingstmontag';
holidayList[fronleichnam()] = 'Fronleichnam';
holidayList[mariahimmelfahrt()] = 'Maria Himmelfahrt';
holidayList[staatsfeiertag()] = 'Staatsfeiertag';
holidayList[allerheiligen()] = 'Allerheiligen';
holidayList[ersteradvent()] = '1. Advent';
holidayList[mariaempfaengnis()] = 'Maria Emphängnis';
holidayList[ersterweihnachtstag()] = '1. Weihnachtstag';
holidayList[zweiterweihnachtstag()] = '2. Weihnachtstag';
holidayList[silvester()] = 'Silvester';
}
Map<DateTime, String> holidayList = {};
int year = 0;
Map<DateTime, String> entries() {
return holidayList;
}
String holiday(DateTime bookingDate) {
if (holidayList.containsKey(bookingDate)) {
return holidayList[bookingDate]!;
}
return '';
}
DateTime neujahr() {
return DateTime(year, 1, 1);
}
DateTime heilige3koenige() {
return DateTime(year, 1, 6);
}
DateTime karfreitag() {
DateTime d =
Jiffy.parseFromDateTime(ostersonntag()).subtract(days: 2).dateTime;
return DateTime(d.year, d.month, d.day);
}
DateTime ostersonntag() {
int a = year % 19;
int b = (year ~/ 100).toInt();
int c = year % 100;
int e = b % 4;
int f = ((b + 8) ~/ 25).toInt();
int g = ((b - f + 1) ~/ 3).toInt();
int h = (19 * a + b - (b ~/ 4) - g + 15) % 30;
int k = c % 4;
int l = (32 + 2 * e + 2 * (c ~/ 4) - h - k) % 7;
int m = (a + 11 * h + 22 * l) ~/ 451;
int month = (h + l - 7 * m + 114) ~/ 31;
int day = (h + l - 7 * m + 114) % 31 + 1;
return DateTime(year, month, day);
}
DateTime ostermontag() {
DateTime d = Jiffy.parseFromDateTime(ostersonntag()).add(days: 1).dateTime;
return DateTime(d.year, d.month, d.day);
}
DateTime staatsfeiertag1() {
return DateTime(year, 5, 1);
}
DateTime christihimmelfahrt() {
DateTime d = Jiffy.parseFromDateTime(ostersonntag()).add(days: 39).dateTime;
return DateTime(d.year, d.month, d.day);
}
DateTime pfingstsonntag() {
DateTime d = Jiffy.parseFromDateTime(ostersonntag()).add(days: 49).dateTime;
return DateTime(d.year, d.month, d.day);
}
DateTime pfingstmontag() {
DateTime d = Jiffy.parseFromDateTime(ostersonntag()).add(days: 50).dateTime;
return DateTime(d.year, d.month, d.day);
}
DateTime fronleichnam() {
DateTime d = Jiffy.parseFromDateTime(ostersonntag()).add(days: 60).dateTime;
return DateTime(d.year, d.month, d.day);
}
DateTime mariahimmelfahrt() {
return DateTime(year, 8, 15);
}
DateTime staatsfeiertag() {
return DateTime(year, 10, 26);
}
DateTime allerheiligen() {
return DateTime(year, 11, 1);
}
DateTime ersteradvent() {
DateTime d = DateTime(year, 11, 27);
DateTime d1 = Jiffy.parseFromDateTime(d).add(days: 7 - d.weekday).dateTime;
return DateTime(d1.year, d1.month, d1.day);
}
DateTime mariaempfaengnis() {
return DateTime(year, 12, 8);
}
DateTime ersterweihnachtstag() {
return DateTime(year, 12, 25);
}
DateTime zweiterweihnachtstag() {
return DateTime(year, 12, 26);
}
DateTime silvester() {
return DateTime(year, 12, 31);
}
}
+50 -111
View File
@@ -1,125 +1,64 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:workinghours/widgets/tabsScreen.dart';
final theme = ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
brightness: Brightness.dark,
seedColor: const Color.fromARGB(255, 131, 57, 0),
),
textTheme: GoogleFonts.latoTextTheme(),
);
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences prefs = await SharedPreferences.getInstance();
String? dbProtocol = prefs.getString('dbProtocol');
String? dbHost = prefs.getString('dbHost');
String? dbPath = prefs.getString('dbPath');
String? dbUser = prefs.getString('dbUser');
String? dbPassword = prefs.getString('dbPassword');
// if (dbProtocol == null) {
//prefs.setString('dbProtocol', 'http');
prefs.setString('dbProtocol', 'https');
// }
// if (dbHost == null) {
//prefs.setString('dbHost', '192.168.0.70');
prefs.setString('dbHost', 'api.windesign.at');
// }
// if (dbProtocol == null) {
// prefs.setString('dbProtocol', 'https');
// }
// if (dbHost == null) {
// prefs.setString('dbHost', 'api.windesign.at');
// }
if (dbPath == null) {
prefs.setString('dbPath', '/workinghours.php');
}
if (dbUser == null) {
prefs.setString('dbUser', '');
}
if (dbPassword == null) {
prefs.setString('dbPassword', '');
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// TRY THIS: Try running your application with "flutter run". You'll see
// the application has a purple toolbar. Then, without quitting the app,
// try changing the seedColor in the colorScheme below to Colors.green
// and then invoke "hot reload" (save your changes or press the "hot
// reload" button in a Flutter-supported IDE, or press "r" if you used
// the command line to start the app).
//
// Notice that the counter didn't reset back to zero; the application
// state is not lost during the reload. To reset the state, use hot
// restart instead.
//
// This works for code too, not just values: Most code changes can be
// tested with just a hot reload.
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// TRY THIS: Try changing the color here to a specific color (to
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
// change color while the other colors stay the same.
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
//
// TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
// action in the IDE, or press "p" in the console), to see the
// wireframe for each widget.
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
// theme: theme,
title: 'Multimedia',
home: const TabsScreen(),
);
}
}
+268
View File
@@ -0,0 +1,268 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:syncfusion_flutter_core/theme.dart';
import 'package:jiffy/jiffy.dart';
import 'package:workinghours/data/publicHolidays.dart';
import 'package:workinghours/data/booking.dart';
class MonthlyScreen extends StatefulWidget {
const MonthlyScreen({
super.key,
});
@override
State<StatefulWidget> createState() => _MonthlyScreenState();
}
class _MonthlyScreenState extends State<MonthlyScreen> {
final DataGridController _dataGridController = DataGridController();
late BookingDataSource bookingDataSource;
List<GridColumn> _columns = [];
Future<List<Booking>> generateBookingList() async {
// SharedPreferences prefs = await SharedPreferences.getInstance();
// String? dbProtocol = prefs.getString('dbProtocol');
// String? dbHost = prefs.getString('dbHost');
// String? dbPath = prefs.getString('dbPath');
// Uri url = Uri(
// scheme: dbProtocol,
// host: dbHost,
// path: dbPath,
// queryParameters: {
// 'module': 'movie',
// 'function': 'getList',
// },
// );
// final response = await http.get(url);
// bool? error;
// String? errorMessage;
// Map<String, dynamic> movies = json.decode(response.body);
// error = movies['error'];
// errorMessage = movies['errmsg'];
// var list = movies['data'];
// List<Movie> _movies =
// await list.map<Movie>((json) => Movie.fromJson(json)).toList();
// movieDataSource = MovieDataSource(_movies);
// return _movies;
List<Booking> _booking = [];
for (int i = 1; i < 31; i++) {
_booking.add(Booking(
bookingDay: DateTime(2024, 1, i),
come1: DateTime(2024, 1, i, 8, 3, 0),
leave1: DateTime(2024, 1, i, 16, 27, 0),
come2: DateTime(1900, 1, 1),
leave2: DateTime(1900, 1, 1),
come3: DateTime(1900, 1, 1),
leave3: DateTime(1900, 1, 1),
come4: DateTime(1900, 1, 1),
leave4: DateTime(1900, 1, 1),
come5: DateTime(1900, 1, 1),
leave5: DateTime(1900, 1, 1),
code: '',
information: '',
));
}
bookingDataSource = BookingDataSource(_booking);
return _booking;
}
List<GridColumn> getColumns() {
return <GridColumn>[
GridColumn(
columnName: 'dayLeft',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: const Text('dayLeft'))),
GridColumn(
columnName: 'holiday',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: const Text('holiday'))),
GridColumn(
columnName: 'come1',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('come1'))),
GridColumn(
columnName: 'leave1',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('leave1'))),
GridColumn(
columnName: 'come2',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('come2'))),
GridColumn(
columnName: 'leave2',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('leave2'))),
GridColumn(
columnName: 'come3',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('come3'))),
GridColumn(
columnName: 'leave3',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('leave3'))),
GridColumn(
columnName: 'come4',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('come4'))),
GridColumn(
columnName: 'leave4',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('leave4'))),
GridColumn(
columnName: 'come5',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('come5'))),
GridColumn(
columnName: 'leave5',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('leave5'))),
GridColumn(
columnName: 'pause',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('pause'))),
GridColumn(
columnName: 'code',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('code'))),
GridColumn(
columnName: 'durationIs',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('durationIs'))),
GridColumn(
columnName: 'durationShould',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('durationShould'))),
GridColumn(
columnName: 'diff',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('diff'))),
GridColumn(
columnName: 'information',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('information'))),
GridColumn(
columnName: 'currentDiff',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('currentDiff'))),
GridColumn(
columnName: 'decimal',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('decimal'))),
GridColumn(
columnName: 'dayRight',
columnWidthMode: ColumnWidthMode.auto,
label: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: const Text('dayRight'))),
];
}
@override
void initState() {
super.initState();
_columns = getColumns();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<Object>(
future: generateBookingList(),
builder: (context, data) {
return data.hasData
? SfDataGridTheme(
data: const SfDataGridThemeData(
headerColor: Color(0xff009889),
),
child: SfDataGrid(
source: bookingDataSource,
selectionMode: SelectionMode.single,
navigationMode: GridNavigationMode.row,
columns: _columns,
controller: _dataGridController,
columnWidthMode: ColumnWidthMode.auto,
),
)
: const Center(
child: CircularProgressIndicator(
strokeWidth: 2,
value: 0.8,
),
);
},
),
);
}
}
+64
View File
@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:workinghours/widgets/monthly/monthlyScreen.dart';
import 'package:workinghours/widgets/yearly/yearlyScreen.dart';
class TabsScreen extends StatefulWidget {
const TabsScreen({super.key});
@override
State<TabsScreen> createState() {
return _TabsScreenState();
}
}
class _TabsScreenState extends State<TabsScreen> {
@override
void initState() {
super.initState();
}
int _selectedPageIndex = 0;
void _selectPage(int index) {
setState(() {
_selectedPageIndex = index;
});
}
@override
Widget build(BuildContext context) {
Widget activePage = const MonthlyScreen();
var activePageTitle = 'Monthly';
if (_selectedPageIndex == 1) {
activePage = const YearlyScreen();
activePageTitle = 'Yearly';
}
return Scaffold(
appBar: AppBar(
title: Text(activePageTitle),
),
body: activePage,
bottomNavigationBar: BottomNavigationBar(
onTap: _selectPage,
currentIndex: _selectedPageIndex,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
// icon: Icon(Icons.tv_outlined),
label: 'Monthly',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
// icon: Icon(Icons.movie),
label: 'Yearly',
),
],
selectedIconTheme: const IconThemeData(opacity: 0.0, size: 0),
unselectedIconTheme: const IconThemeData(opacity: 0.0, size: 0),
),
);
}
}
+21
View File
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
class YearlyScreen extends StatefulWidget {
const YearlyScreen({
super.key,
});
@override
State<StatefulWidget> createState() => _YearlyScreenState();
}
class _YearlyScreenState extends State<YearlyScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('bla'),
),
);
}
}