basic session create and delete
This commit is contained in:
parent
029f037f90
commit
cd8da31f4b
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -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),
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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'),
|
||||||
),
|
),
|
||||||
|
187
lib/widgets/session_creator.dart
Normal file
187
lib/widgets/session_creator.dart
Normal 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'))
|
||||||
|
])
|
||||||
|
],
|
||||||
|
))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user