Skip to content

Commit

Permalink
fix #62
Browse files Browse the repository at this point in the history
  • Loading branch information
pbarbenheim committed Jan 8, 2025
1 parent 3b703db commit 6fc9375
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 82 deletions.
3 changes: 3 additions & 0 deletions l10n.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
arb-dir: lib/l10n
template-arb-file: app_de.arb
output-localization-file: app_localizations.dart
66 changes: 66 additions & 0 deletions lib/app.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'dart:io';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:path/path.dart' as path;
import 'package:window_size/window_size.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

import 'repository/repository.dart';
import 'ui/routes.dart';

class JulogApp extends ConsumerStatefulWidget {
const JulogApp({super.key});

@override
ConsumerState<ConsumerStatefulWidget> createState() => _JulogAppState();
}

class _JulogAppState extends ConsumerState<JulogApp> {
// ignore: unused_field
late final AppLifecycleListener _lifecycleListener;

@override
void initState() {
_lifecycleListener = AppLifecycleListener(
onDetach: _handleShutdown,
onExitRequested: _handleShutdown,
);
super.initState();
}

@override
Widget build(BuildContext context) {
final router = ref.watch(routerProvider);
final filename =
ref.watch(repositoryProvider.select((value) => value?.filename));
final file = filename != null ? path.basename(filename) : null;
final String title;
if (file == null) {
title = "julog";
} else {
title = "$file - julog";
}
if (Platform.isLinux || Platform.isMacOS || Platform.isLinux) {
setWindowTitle(title);
}
return MaterialApp.router(
routerConfig: router,
title: title,
supportedLocales: const [Locale("de")],
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
);
}

Future<AppExitResponse> _handleShutdown() async {
ref.read(repositoryProvider.notifier).dispose();
return AppExitResponse.exit;
}
}
5 changes: 5 additions & 0 deletions lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"@@locale": "de",
"itemDetailDetail": "Detail",
"itemDetailEmptyHint": "Klicke ein Listenelement links an, um dir die Details anzusehen."
}
61 changes: 1 addition & 60 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import 'dart:io';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:path/path.dart' as path;
import 'package:window_size/window_size.dart';

import 'app.dart';
import 'repository/repository.dart';
import 'ui/routes.dart';

void main(List<String> args) async {
WidgetsFlutterBinding.ensureInitialized();
Expand All @@ -33,56 +27,3 @@ void main(List<String> args) async {
child: const JulogApp(),
));
}

class JulogApp extends ConsumerStatefulWidget {
const JulogApp({super.key});

@override
ConsumerState<ConsumerStatefulWidget> createState() => _JulogAppState();
}

class _JulogAppState extends ConsumerState<JulogApp> {
// ignore: unused_field
late final AppLifecycleListener _lifecycleListener;

@override
void initState() {
_lifecycleListener = AppLifecycleListener(
onDetach: _handleShutdown,
onExitRequested: _handleShutdown,
);
super.initState();
}

@override
Widget build(BuildContext context) {
final router = ref.watch(routerProvider);
final filename =
ref.watch(repositoryProvider.select((value) => value?.filename));
final file = filename != null ? path.basename(filename) : null;
final String title;
if (file == null) {
title = "julog";
} else {
title = "$file - julog";
}
if (Platform.isLinux || Platform.isMacOS || Platform.isLinux) {
setWindowTitle(title);
}
return MaterialApp.router(
routerConfig: router,
title: title,
supportedLocales: const [Locale("de")],
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
);
}

Future<AppExitResponse> _handleShutdown() async {
ref.read(repositoryProvider.notifier).dispose();
return AppExitResponse.exit;
}
}
26 changes: 20 additions & 6 deletions lib/ui/frame.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

abstract class Item extends StatelessWidget {
final String title;
final String? subtitle;
late final String? Function(BuildContext context) getSubtitle;

const Item({super.key, required this.title, this.subtitle});
Item(
{super.key,
required this.title,
String? subtitle,
String? Function(BuildContext context)? getSubtitle}) {
assert(subtitle == null || getSubtitle == null);

if (getSubtitle != null) {
this.getSubtitle = getSubtitle;
} else {
this.getSubtitle = (context) => subtitle;
}
}
}

class ItemList<T extends Item> extends StatelessWidget {
Expand All @@ -26,7 +39,7 @@ class ItemList<T extends Item> extends StatelessWidget {
children: items
.map((item) => ListTile(
title: Text(item.title),
subtitle: Text(item.subtitle ?? ""),
subtitle: Text(item.getSubtitle(context) ?? ""),
onTap: () => onChanged(item),
selected: item == selected,
))
Expand All @@ -44,13 +57,14 @@ class ItemDetail<T extends Item> extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(item?.title ?? "Details"),
title:
Text(item?.title ?? AppLocalizations.of(context)!.itemDetailDetail),
actions: actions,
),
body: Center(
child: item ??
const Text(
"Klicke ein Listenelement links an, um dir die Details anzusehen.",
Text(
AppLocalizations.of(context)!.itemDetailEmptyHint,
),
),
);
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/screens/dashboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class DashboardScreen extends ConsumerWidget {
),
body: Center(
child: Text(
"Herzlich Willkommen im Dienstbuch der Jugendfeuerwehr. Die geöffnete Datei ist ${filename ?? "FEHLER"}. Viel Spaß",
"Herzlich Willkommen im Dienstbuch der Jugendfeuerwehr. Die geöffnete Datei ist ${filename ?? "FEHLER"}. Viel Spaß\n\nHier: ${Localizations.localeOf(context).languageCode}",
softWrap: true,
),
),
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/widgets/betreuer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class BetreuerItem extends Item {
final String name;
final int id;
final Geschlecht geschlecht;
const BetreuerItem({
BetreuerItem({
required this.geschlecht,
super.key,
required this.name,
Expand Down
35 changes: 26 additions & 9 deletions lib/ui/widgets/dienstbuch.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart';

import '../../repository/repository.dart';
Expand All @@ -19,7 +20,13 @@ class EintragItem extends Item {
required this.beginn,
required this.thema,
required this.getEintrag,
}) : super(title: thema, subtitle: beginn.toString());
}) : super(
title: thema,
getSubtitle: (context) =>
Intl(Localizations.localeOf(context).toLanguageTag())
.date('dd.MM.yy')
.format(beginn),
);

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -61,14 +68,20 @@ class EintragItem extends Item {
),
Row(
children: [
const Text("Beginn:"),
Text(e.beginn.toString()),
const Text("Beginn: "),
DateTimeValue(
dateTime: e.beginn,
withTime: true,
)
],
),
Row(
children: [
const Text("Ende:"),
Text(e.ende.toString()),
const Text("Ende: "),
DateTimeValue(
dateTime: e.ende,
withTime: true,
)
],
),
Row(
Expand Down Expand Up @@ -128,11 +141,15 @@ class SignaturTile extends StatelessWidget {
final Signatur signatur;
const SignaturTile({super.key, required this.signatur});

Widget _getTile(bool? verified) {
Widget _getTile(BuildContext context, bool? verified) {
final (name, comment, _) = Repository.userIdToComponents(signatur.userId);
return ListTile(
title: Text("gez. $name, $comment"),
subtitle: Text(signatur.signedAt.toString()),
subtitle: DateTimeValue(
dateTime: signatur.signedAt,
withTime: true,
prefix: "am ",
),
leading: verified == null
? const Icon(Icons.question_mark)
: (verified
Expand All @@ -148,9 +165,9 @@ class SignaturTile extends StatelessWidget {
initialData: null,
builder: (context, snapshot) {
if (snapshot.hasData) {
return _getTile(snapshot.data!);
return _getTile(context, snapshot.data!);
}
return _getTile(null);
return _getTile(context, null);
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/widgets/identities.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class SignIdentityItem extends Item {
final String? comment;
final String email;
final String userId;
const SignIdentityItem({
SignIdentityItem({
super.key,
required this.name,
this.comment,
Expand Down
22 changes: 18 additions & 4 deletions lib/ui/widgets/jugendliche.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class JugendlicheItem extends Item {
final String name;
final WidgetRef ref;

const JugendlicheItem({
JugendlicheItem({
super.key,
required this.id,
required this.name,
Expand All @@ -29,9 +29,23 @@ class JugendlicheItem extends Item {
Text("Name: ${ju.name}"),
Text("Geschlecht: ${ju.geschlecht}"),
Text("Passnummer: ${ju.passnummer ?? '-'}"),
Text("Geburtstag: ${ju.geburtstag}"),
Text("Eintrittsdatum: ${ju.eintrittsdatum}"),
Text("Austrittsdatum: ${ju.austrittsdatum ?? '-'}"),
DateTimeValue(
dateTime: ju.geburtstag,
withTime: false,
prefix: "Geburtstag: ",
),
DateTimeValue(
dateTime: ju.eintrittsdatum,
withTime: false,
prefix: "Eintrittsdatum: ",
),
ju.austrittsdatum != null
? DateTimeValue(
dateTime: ju.austrittsdatum!,
withTime: false,
prefix: "Austrittsdatum: ",
)
: const Text("Austrittsdatum: -"),
Text("Austrittsgrund: ${ju.austrittsgrund ?? '-'}"),
],
);
Expand Down
24 changes: 24 additions & 0 deletions lib/ui/widgets/util.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:omni_datetime_picker/omni_datetime_picker.dart';

import '../../pubspec.g.dart';
Expand Down Expand Up @@ -107,3 +108,26 @@ class DateTimeField extends StatelessWidget {
);
}
}

class DateTimeValue extends StatelessWidget {
final DateTime dateTime;
final bool withTime;
final String? prefix;
final String? suffix;
const DateTimeValue({
super.key,
required this.dateTime,
this.withTime = true,
this.prefix,
this.suffix,
});

@override
Widget build(BuildContext context) {
return Text((prefix ?? "") +
Intl(Localizations.localeOf(context).toLanguageTag())
.date(withTime ? "dd.MM.yy HH:mm" : "dd.MM.yy")
.format(dateTime) +
(suffix ?? ""));
}
}
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ flutter:
# the material Icons class.
uses-material-design: true

generate: true

# To add assets to your application, add an assets section, like this:
assets:
- assets/icon/icon.png
Expand Down

0 comments on commit 6fc9375

Please sign in to comment.