summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2023-03-30 00:05:43 -0600
committerIván Ávalos <avalos@disroot.org>2023-03-30 00:05:43 -0600
commit1a796abe772e6d2de69b6c2d7f0944cd0c19289d (patch)
treecec89a7e97964b95363bee5811505b092a6f42f5
parent63fe9170e34c4f163567ddae078b8e6c1ca44ad9 (diff)
downloadpmsna1-1a796abe772e6d2de69b6c2d7f0944cd0c19289d.tar.gz
pmsna1-1a796abe772e6d2de69b6c2d7f0944cd0c19289d.tar.bz2
pmsna1-1a796abe772e6d2de69b6c2d7f0944cd0c19289d.zip
Progress for 4th practice, event creation and reading
-rw-r--r--lib/database/helper.dart3
-rw-r--r--lib/main.dart2
-rw-r--r--lib/providers/events_provider.dart28
-rw-r--r--lib/routes.dart2
-rw-r--r--lib/screens/events_screen.dart69
-rw-r--r--lib/screens/new_event_screen.dart144
-rw-r--r--lib/widgets/event_item.dart42
-rw-r--r--lib/widgets/event_list.dart35
8 files changed, 304 insertions, 21 deletions
diff --git a/lib/database/helper.dart b/lib/database/helper.dart
index 5992e7f..da2d199 100644
--- a/lib/database/helper.dart
+++ b/lib/database/helper.dart
@@ -25,6 +25,9 @@ class DatabaseHelper {
onUpgrade: ((db, oldVersion, newVersion) {
_onCreate(db, newVersion);
}),
+ onOpen: (db) {
+ _onCreate(db, 0);
+ },
);
return _database!;
}
diff --git a/lib/main.dart b/lib/main.dart
index 0b10f9b..a174aaa 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,5 +1,6 @@
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
+import 'package:pmsna1/providers/events_provider.dart';
import 'package:pmsna1/providers/flags_provider.dart';
import 'package:pmsna1/providers/theme_provider.dart';
import 'package:pmsna1/routes.dart';
@@ -34,6 +35,7 @@ class _MainContentState extends State<MainContent> {
providers: [
ChangeNotifierProvider(create: (_) => ThemeProvider()),
ChangeNotifierProvider(create: (_) => FlagsProvider()),
+ ChangeNotifierProvider(create: (_) => EventsProvider()),
],
child: const PMSNA1(),
);
diff --git a/lib/providers/events_provider.dart b/lib/providers/events_provider.dart
new file mode 100644
index 0000000..eee9853
--- /dev/null
+++ b/lib/providers/events_provider.dart
@@ -0,0 +1,28 @@
+import 'package:flutter/foundation.dart';
+import 'package:pmsna1/database/helper.dart';
+import 'package:pmsna1/models/event.dart';
+
+class EventsProvider with ChangeNotifier {
+ DatabaseHelper helper = DatabaseHelper();
+ List<Event> _events = [];
+
+ EventsProvider() {
+ fetchDB();
+ }
+
+ List<Event> get events {
+ return _events;
+ }
+
+ set events(List<Event> events) {
+ _events = events;
+ notifyListeners();
+ }
+
+ void fetchDB() {
+ print('fetching events from DB');
+ helper.getAllEvent().then((e) {
+ events = e;
+ });
+ }
+}
diff --git a/lib/routes.dart b/lib/routes.dart
index 1d4284b..766273b 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:pmsna1/screens/dashboard_screen.dart';
import 'package:pmsna1/screens/events_screen.dart';
+import 'package:pmsna1/screens/new_event_screen.dart';
import 'package:pmsna1/screens/new_post_screen.dart';
import 'package:pmsna1/screens/onboarding_screen.dart';
import 'package:pmsna1/screens/popular_screen.dart';
@@ -17,5 +18,6 @@ Map<String, WidgetBuilder> getApplicationRoutes() {
'/new': (BuildContext context) => const NewPostScreen(),
'/events': (BuildContext context) => const EventsScreen(),
'/popular': (BuildContext context) => const PopularScreen(),
+ '/newevent': (BuildContext context) => const NewEventScreen(),
};
}
diff --git a/lib/screens/events_screen.dart b/lib/screens/events_screen.dart
index 60d1b26..0b78fbe 100644
--- a/lib/screens/events_screen.dart
+++ b/lib/screens/events_screen.dart
@@ -1,6 +1,10 @@
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
+import '../widgets/event_list.dart';
+
+enum Vista { calendario, lista }
+
class EventsScreen extends StatefulWidget {
const EventsScreen({super.key});
@@ -9,6 +13,7 @@ class EventsScreen extends StatefulWidget {
}
class _EventsScreenState extends State<EventsScreen> {
+ Vista vista = Vista.calendario;
DateTime _selectedDay = DateTime.now();
DateTime _focusedDay = DateTime.now();
CalendarFormat _calendarFormat = CalendarFormat.month;
@@ -18,29 +23,51 @@ class _EventsScreenState extends State<EventsScreen> {
return Scaffold(
appBar: AppBar(
title: const Text('Eventos'),
- actions: const [],
+ actions: [
+ SegmentedButton<Vista>(
+ showSelectedIcon: false,
+ segments: const [
+ ButtonSegment<Vista>(
+ value: Vista.calendario,
+ icon: Icon(Icons.calendar_month),
+ ),
+ ButtonSegment<Vista>(
+ value: Vista.lista,
+ icon: Icon(Icons.list),
+ ),
+ ],
+ selected: <Vista>{vista},
+ onSelectionChanged: (p0) {
+ setState(() {
+ vista = p0.first;
+ });
+ },
+ )
+ ],
),
body: Container(
- child: TableCalendar(
- firstDay: DateTime.fromMicrosecondsSinceEpoch(0),
- lastDay: DateTime.utc(9000, 12, 31),
- focusedDay: _focusedDay,
- selectedDayPredicate: (day) {
- return isSameDay(_selectedDay, day);
- },
- onDaySelected: (selectedDay, focusedDay) {
- setState(() {
- _selectedDay = selectedDay;
- _focusedDay = focusedDay;
- });
- },
- calendarFormat: _calendarFormat,
- onFormatChanged: (format) {
- setState(() {
- _calendarFormat = format;
- });
- },
- )),
+ child: vista == Vista.calendario
+ ? TableCalendar(
+ firstDay: DateTime.fromMicrosecondsSinceEpoch(0),
+ lastDay: DateTime.utc(9000, 12, 31),
+ focusedDay: _focusedDay,
+ selectedDayPredicate: (day) {
+ return isSameDay(_selectedDay, day);
+ },
+ onDaySelected: (selectedDay, focusedDay) {
+ setState(() {
+ _selectedDay = selectedDay;
+ _focusedDay = focusedDay;
+ });
+ },
+ calendarFormat: _calendarFormat,
+ onFormatChanged: (format) {
+ setState(() {
+ _calendarFormat = format;
+ });
+ },
+ )
+ : const EventList()),
floatingActionButton: FloatingActionButton.extended(
label: const Text('Nuevo'),
icon: const Icon(Icons.add),
diff --git a/lib/screens/new_event_screen.dart b/lib/screens/new_event_screen.dart
new file mode 100644
index 0000000..3c49ee6
--- /dev/null
+++ b/lib/screens/new_event_screen.dart
@@ -0,0 +1,144 @@
+import 'package:flutter/material.dart';
+import 'package:pmsna1/providers/events_provider.dart';
+import 'package:provider/provider.dart';
+
+import '../database/helper.dart';
+import '../models/event.dart';
+
+class NewEventScreen extends StatefulWidget {
+ const NewEventScreen({super.key});
+
+ @override
+ State<NewEventScreen> createState() => _NewEventScreenState();
+}
+
+class _NewEventScreenState extends State<NewEventScreen> {
+ Event? event;
+ DateTime? selectedDate;
+ DatabaseHelper helper = DatabaseHelper();
+
+ final _descController = TextEditingController();
+ final _formKey = GlobalKey<FormState>();
+
+ final padding = 12.0;
+ Widget get spacer => SizedBox(height: padding, width: padding);
+
+ @override
+ Widget build(BuildContext context) {
+ event = ModalRoute.of(context)?.settings.arguments as Event?;
+ if (event != null) {
+ _descController.text = event!.description;
+ setState(() {
+ selectedDate = event!.date;
+ });
+ }
+
+ EventsProvider provider = Provider.of<EventsProvider>(context);
+
+ return Scaffold(
+ appBar: AppBar(
+ title: Text(event == null ? 'Nuevo evento' : 'Editar evento'),
+ actions: [
+ IconButton(
+ icon: const Icon(Icons.save),
+ tooltip: event == null ? 'Crear' : 'Editar',
+ onPressed: () {
+ if (_formKey.currentState?.validate() == false) {
+ return;
+ }
+ if (selectedDate == null) {
+ return;
+ }
+
+ if (event == null) {
+ helper.insert('events', {
+ 'description': _descController.text,
+ 'date': selectedDate!.toIso8601String(),
+ 'completed': false, // TODO: implement checkbox
+ }).then((value) {
+ SnackBar bar = SnackBar(
+ content: Text(
+ value > 0 ? 'Evento insertado' : 'Ocurrió un error',
+ ),
+ );
+
+ ScaffoldMessenger.of(context).showSnackBar(bar);
+ Navigator.of(context).pop();
+ provider.fetchDB();
+ });
+ } else {
+ helper
+ .update(
+ 'events',
+ {
+ 'description': _descController.text,
+ 'date': selectedDate!.toIso8601String(),
+ 'completed': false,
+ },
+ 'id',
+ event!.id,
+ )
+ .then((value) {
+ SnackBar bar = SnackBar(
+ content: Text(
+ value > 0 ? 'Evento modificado' : 'Ocurrió un error',
+ ),
+ );
+
+ ScaffoldMessenger.of(context).showSnackBar(bar);
+ Navigator.of(context).pop();
+ provider.fetchDB();
+ });
+ }
+ },
+ )
+ ],
+ ),
+ body: Padding(
+ padding: const EdgeInsets.all(12.0),
+ child: Form(
+ key: _formKey,
+ child: Column(
+ children: [
+ TextFormField(
+ controller: _descController,
+ textAlignVertical: TextAlignVertical.top,
+ decoration: const InputDecoration(
+ border: OutlineInputBorder(),
+ labelText: 'Descripción',
+ ),
+ validator: (value) {
+ if (value != null && value.isNotEmpty) {
+ return null;
+ }
+ return 'Este campo no debe estar vacío';
+ },
+ ),
+ spacer,
+ OutlinedButton(
+ child: Text(selectedDate != null
+ ? selectedDate!.toIso8601String()
+ : 'Seleccionar fecha'),
+ onPressed: () {
+ showDatePicker(
+ initialDate: DateTime.now(),
+ firstDate: DateTime.now(),
+ lastDate: DateTime.utc(9000, 12, 31),
+ currentDate: DateTime.now(),
+ initialEntryMode: DatePickerEntryMode.calendar,
+ context: context,
+ ).then((DateTime? date) {
+ if (date == null) return;
+ setState(() {
+ selectedDate = date;
+ });
+ });
+ },
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/event_item.dart b/lib/widgets/event_item.dart
new file mode 100644
index 0000000..e00d328
--- /dev/null
+++ b/lib/widgets/event_item.dart
@@ -0,0 +1,42 @@
+import 'package:flutter/material.dart';
+
+import '../models/event.dart';
+
+class EventItem extends StatelessWidget {
+ final Event event;
+
+ const EventItem({super.key, required this.event});
+
+ final padding = 16.0;
+ final spacer = const SizedBox(
+ height: 12.0,
+ width: 12.0,
+ );
+
+ @override
+ Widget build(BuildContext context) {
+ final txtDate = Text(
+ event.date.toIso8601String(),
+ style: Theme.of(context).typography.englishLike.labelMedium,
+ );
+ final txtDesc = Text(
+ event.description,
+ style: Theme.of(context).typography.englishLike.bodyLarge,
+ );
+
+ return Card(
+ child: Padding(
+ padding: EdgeInsets.all(padding),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ txtDesc,
+ spacer,
+ txtDate,
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/event_list.dart b/lib/widgets/event_list.dart
new file mode 100644
index 0000000..437525c
--- /dev/null
+++ b/lib/widgets/event_list.dart
@@ -0,0 +1,35 @@
+import 'package:flutter/material.dart';
+import 'package:pmsna1/database/helper.dart';
+import 'package:pmsna1/providers/events_provider.dart';
+import 'package:provider/provider.dart';
+
+import '../models/event.dart';
+import 'event_item.dart';
+
+class EventList extends StatefulWidget {
+ const EventList({super.key});
+
+ @override
+ State<EventList> createState() => _EventListState();
+}
+
+class _EventListState extends State<EventList> {
+ late DatabaseHelper helper;
+
+ @override
+ void initState() {
+ super.initState();
+ helper = DatabaseHelper();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ EventsProvider provider = context.watch<EventsProvider>();
+ List<Event> events = provider.events;
+ return ListView.builder(
+ itemCount: events.length,
+ itemBuilder: (BuildContext context, int index) =>
+ EventItem(event: events[index]),
+ );
+ }
+}