basic session create and delete

This commit is contained in:
Joshua Burman 2024-12-26 01:20:55 -05:00
parent 029f037f90
commit cd8da31f4b
6 changed files with 251 additions and 33 deletions

View File

@ -7,21 +7,12 @@ part 'sessions_dao.g.dart';
class SessionsDao extends DatabaseAccessor<AppDatabase> with _$SessionsDaoMixin { class SessionsDao extends DatabaseAccessor<AppDatabase> with _$SessionsDaoMixin {
SessionsDao(super.db); SessionsDao(super.db);
Future<List<Session>> all() async { Future<Session> find(int id) => (select(sessions)..where((session) => session.id.equals(id) )).getSingle();
return await select(sessions).get(); Future<List<Session>> all() => select(sessions).get();
} Stream<List<Session>> watch() => select(sessions).watch();
Future createOrUpdate(SessionsCompanion session) => into(sessions).insertOnConflictUpdate(session);
// Future<List<Session>> remove
// Future<List<Session>> all() => select(sessions).get();
// Stream<List<Session>> watch() => select(sessions).watch();
// Future insert(Session session) => into(sessions).insert(session);
// Future replace(Session session) => update(sessions).replace(session); // Future replace(Session session) => update(sessions).replace(session);
Future remove(Session session) => delete(sessions).delete(session); Future remove(Session session) => delete(sessions).delete(session);
Future<Session> find(int id) async {
return await (select(sessions)..where((session) => session.id.equals(id) )).getSingle();
}
} }

View File

@ -6,6 +6,7 @@ import 'package:sendtrain/screens/activities_screen.dart';
import 'package:sendtrain/screens/sessions_screen.dart'; import 'package:sendtrain/screens/sessions_screen.dart';
// ignore: unused_import // ignore: unused_import
import 'package:sendtrain/database/seed.dart'; import 'package:sendtrain/database/seed.dart';
import 'package:sendtrain/widgets/session_creator.dart';
class SendTrain extends StatelessWidget { class SendTrain extends StatelessWidget {
const SendTrain({super.key}); const SendTrain({super.key});
@ -83,7 +84,12 @@ class _AppState extends State<App> {
]), ]),
floatingActionButton: FloatingActionButton.extended( floatingActionButton: FloatingActionButton.extended(
onPressed: () { onPressed: () {
// Add your onPressed code here! showAdaptiveDialog(
barrierColor: Colors.black.withOpacity(0.5),
builder: (BuildContext context) => SessionCreator(),
barrierDismissible: true,
barrierLabel: '',
context: context);
}, },
label: const Text('New Session'), label: const Text('New Session'),
icon: const Icon(Icons.add_chart), icon: const Icon(Icons.add_chart),

View File

@ -1,4 +1,5 @@
// import 'package:drift/drift.dart' hide Column; // import 'package:drift/drift.dart' hide Column;
import 'package:drift/drift.dart' hide Column;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/daos/sessions_dao.dart'; import 'package:sendtrain/daos/sessions_dao.dart';
@ -6,24 +7,30 @@ import 'package:sendtrain/database/database.dart';
import '../widgets/session_card.dart'; import '../widgets/session_card.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
class SessionsScreen extends StatelessWidget { class SessionsScreen extends StatefulWidget {
const SessionsScreen({super.key}); const SessionsScreen({super.key});
@override
State<SessionsScreen> createState() => _SessionsScreenState();
}
class _SessionsScreenState extends State<SessionsScreen> {
Widget getSessionCard(session) { Widget getSessionCard(session) {
if (session != null) { if (session != null) {
return SessionCard(session: session); return SessionCard(session: session);
} else { } else {
return Padding( return Padding(
padding: EdgeInsets.all(15), padding: EdgeInsets.all(15),
child: Icon(Icons.do_not_disturb_alt_outlined) child: Icon(Icons.do_not_disturb_alt_outlined));
);
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<List<Session>>( SessionsDao dao = SessionsDao(Provider.of<AppDatabase>(context));
future: SessionsDao(Provider.of<AppDatabase>(context)).all(),
return StreamBuilder<List<Session>>(
stream: dao.watch(),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data!.isNotEmpty) { if (snapshot.hasData && snapshot.data!.isNotEmpty) {
final sessions = snapshot.data!; final sessions = snapshot.data!;
@ -35,8 +42,20 @@ class SessionsScreen extends StatelessWidget {
final current = sessions.firstWhereOrNull( final current = sessions.firstWhereOrNull(
(session) => session.status == SessionStatus.started); (session) => session.status == SessionStatus.started);
if (current == null && upcoming != null) {
dao.createOrUpdate(SessionsCompanion(
id: Value(upcoming.id),
title: Value(upcoming.title),
content: Value(upcoming.content),
status: Value(SessionStatus.started),
address: Value(upcoming.address),
date: Value(upcoming.date)
));
}
List<Widget> previousSessions = List.generate(pending.length, List<Widget> previousSessions = List.generate(pending.length,
(i) => SessionCard(type: 1, session: pending.elementAt(i))); (i) => SessionCard(type: 1, session: pending.elementAt(i)));
Widget upcomingSession = getSessionCard(upcoming); Widget upcomingSession = getSessionCard(upcoming);
Widget currentSession = getSessionCard(current); Widget currentSession = getSessionCard(current);

View File

@ -8,13 +8,21 @@ import 'package:sendtrain/database/database.dart' hide ActivityAction;
import 'package:sendtrain/extensions/string_extensions.dart'; import 'package:sendtrain/extensions/string_extensions.dart';
import 'package:sendtrain/widgets/session_view.dart'; import 'package:sendtrain/widgets/session_view.dart';
class SessionCard extends StatelessWidget { class SessionCard extends StatefulWidget {
final int type; final int type;
final Session session; final Session session;
const SessionCard({super.key, this.type = 0, required this.session}); const SessionCard({super.key, this.type = 0, required this.session});
@override
State<SessionCard> createState() => _SessionCardState();
}
class _SessionCardState extends State<SessionCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final int type = widget.type;
final Session session = widget.session;
initializeDateFormatting('en'); initializeDateFormatting('en');
final DateFormat dateFormat = DateFormat('yyyy-MM-dd'); final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
@ -102,12 +110,13 @@ class SessionCard extends StatelessWidget {
TextButton( TextButton(
onPressed: () => { onPressed: () => {
SessionsDao(Provider.of<AppDatabase>( SessionsDao(Provider.of<AppDatabase>(
context, listen: false)) context,
.remove(session).then((result) { listen: false))
// ignore: invalid_use_of_protected_member .remove(session)
(context as Element).reassemble(); .then((result) {
}), setState(() {});
Navigator.pop(context, 'OK') }),
Navigator.pop(context, 'OK')
}, },
child: const Text('OK'), child: const Text('OK'),
), ),

View File

@ -0,0 +1,187 @@
import 'package:drift/drift.dart' hide Column;
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:sendtrain/daos/sessions_dao.dart';
import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/widgets/session_view.dart';
class SessionCreator extends StatefulWidget {
const SessionCreator({super.key, this.data, this.session});
final Session? session;
final Map<String, dynamic>? data;
@override
State<SessionCreator> createState() => _SessionCreatorState();
}
class _SessionCreatorState extends State<SessionCreator> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final Map<String, TextEditingController> sessionCreateController = {
'name': TextEditingController(),
'content': TextEditingController(),
'status': TextEditingController(),
'date': TextEditingController(),
};
Future createSession(context) {
return SessionsDao(Provider.of<AppDatabase>(context, listen: false))
.createOrUpdate(SessionsCompanion(
title: Value(sessionCreateController['name']!.text),
content: Value(sessionCreateController['content']!.text),
status: Value(SessionStatus.pending),
date:
Value(DateTime.parse(sessionCreateController['date']!.text))));
}
@override
Widget build(BuildContext context) {
sessionCreateController['date']!.text =
DateFormat('yyyy-MM-dd').format(DateTime.now());
return SimpleDialog(
title: Text('Create Session', textAlign: TextAlign.center),
titlePadding: EdgeInsets.only(top: 17.5, bottom: 10),
contentPadding: EdgeInsets.only(left: 30, right: 30, bottom: 15),
children: [
Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10, bottom: 10),
child: TextFormField(
controller: sessionCreateController['name'],
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter session name',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
if (value.length <= 3 || value.length > 42) {
return 'Please enter between 3 and 42 characters';
}
return null;
},
)),
Padding(
padding: EdgeInsets.only(top: 10, bottom: 10),
child: TextFormField(
controller: sessionCreateController['content'],
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter session description',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
if (value.length <= 3 || value.length > 256) {
return 'Please enter between 3 and 256 characters';
}
return null;
},
)),
Padding(
padding: EdgeInsets.only(top: 7.5, bottom: 7.5),
child: TextFormField(
readOnly: true,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter a date for the session',
),
controller: sessionCreateController['date'],
onTap: () {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime.now()
.subtract(Duration(days: 365)),
lastDate:
DateTime.now().add(Duration(days: 365)))
.then((date) {
sessionCreateController['date']?.text =
DateFormat('yyyy-MM-dd').format(date!);
});
})),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => {
if (_formKey.currentState!.validate())
{
createSession(_formKey.currentContext)
.then((id) => {
SessionsDao(
Provider.of<AppDatabase>(
context,
listen: false))
.find(id)
.then(
(session) =>
showGeneralDialog(
barrierColor: Colors
.black
.withOpacity(0.5),
transitionDuration:
const Duration(
milliseconds:
220),
transitionBuilder:
(BuildContext
context,
Animation<
double>
animation,
Animation<
double>
secondaryAnimation,
Widget
child) {
Animation<Offset> custom = Tween<
Offset>(
begin:
const Offset(
0.0,
1.0),
end: const Offset(
0.0,
0.0))
.animate(
animation);
return SlideTransition(
position:
custom,
child: Dialog.fullscreen(
child: SessionView(
session:
session)));
},
barrierDismissible:
true,
barrierLabel: '',
context: context,
pageBuilder: (context,
animation1,
animation2) {
return Container();
}).whenComplete(() => Navigator.pop(context, 'Submit')),
)
})
}
},
child: Text('Submit'))
])
],
))
]);
}
}

View File

@ -3,27 +3,34 @@ import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart'; import 'package:intl/date_symbol_data_local.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/daos/activities_dao.dart';
import 'package:sendtrain/daos/sessions_dao.dart';
import 'package:sendtrain/daos/activities_dao.dart';
import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/extensions/string_extensions.dart'; import 'package:sendtrain/extensions/string_extensions.dart';
import 'package:sendtrain/widgets/session_view_achievements.dart'; import 'package:sendtrain/widgets/session_view_achievements.dart';
import 'package:sendtrain/widgets/session_view_activities.dart'; import 'package:sendtrain/widgets/session_view_activities.dart';
import 'package:sendtrain/widgets/session_view_media.dart'; import 'package:sendtrain/widgets/session_view_media.dart';
class SessionView extends StatelessWidget { class SessionView extends StatefulWidget {
const SessionView({super.key, required this.session}); const SessionView({super.key, required this.session});
final Session session; final Session session;
@override
State<SessionView> createState() => _SessionViewState();
}
class _SessionViewState extends State<SessionView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Session session = widget.session;
initializeDateFormatting('en'); initializeDateFormatting('en');
final DateFormat dateFormat = DateFormat('yyyy-MM-dd'); final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
return FutureBuilder<List<Activity>>( return FutureBuilder<List<Activity>>(
future: ActivitiesDao(Provider.of<AppDatabase>(context)).sessionActivities(session.id), future: ActivitiesDao(Provider.of<AppDatabase>(context))
.sessionActivities(session.id),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
final activities = snapshot.data!; final activities = snapshot.data!;
@ -89,8 +96,7 @@ class SessionView extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold), fontSize: 20, fontWeight: FontWeight.bold),
'Activites:')), 'Activites:')),
SessionViewActivities( SessionViewActivities(activities: activities),
activities: activities),
], ],
)); ));
} else { } else {