smilet/lib/Aktivitet/NewActivity.dart

316 lines
12 KiB
Dart

// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, file_names, use_build_context_synchronously, library_private_types_in_public_api
import 'package:flutter/material.dart';
import 'package:smilet/LoginPage.dart';
import 'package:smilet/MainMenu/Meny.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:smilet/User.dart';
Future<bool> addActivity(
String title, String place, String dateTime, User user) async {
var response = await http.get(Uri.parse(
"http://group-15-3.pvt.dsv.su.se/activity/add?title=$title&place=$place&dateTime=$dateTime&creatorUser=${user.getUsername()}&schoolCode=${user.getSchoolCode()}"));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return true;
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
return false;
}
}
class NewActivity extends StatefulWidget {
final String? restorationId;
final User user;
const NewActivity({super.key, required this.user, this.restorationId});
@override
_NewActivityState createState() => _NewActivityState();
}
class _NewActivityState extends State<NewActivity> with RestorationMixin {
@override
String? get restorationId => widget.restorationId;
final RestorableDateTime _selectedDate = RestorableDateTime(DateTime.now());
late final RestorableRouteFuture<DateTime?> _restorableDatePickerRouteFuture =
RestorableRouteFuture<DateTime?>(
onComplete: _selectDate,
onPresent: (NavigatorState navigator, Object? arguments) {
return navigator.restorablePush(
_datePickerRoute,
arguments: _selectedDate.value.millisecondsSinceEpoch,
);
},
);
@pragma('vm:entry-point')
static Route<DateTime> _datePickerRoute(
BuildContext context,
Object? arguments,
) {
return DialogRoute<DateTime>(
context: context,
builder: (BuildContext context) {
return DatePickerDialog(
restorationId: 'date_picker_dialog',
initialEntryMode: DatePickerEntryMode.calendarOnly,
initialDate: DateTime.fromMillisecondsSinceEpoch(arguments! as int),
firstDate: DateTime.now(),
lastDate: DateTime(2025),
);
},
);
}
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_selectedDate, 'selected_date');
registerForRestoration(
_restorableDatePickerRouteFuture, 'date_picker_route_future');
}
void _selectDate(DateTime? newSelectedDate) {
if (newSelectedDate != null) {
setState(() {
_selectedDate.value = newSelectedDate;
dateController.text = _selectedDate.value.toString().substring(0, 10);
});
}
}
TextEditingController titleController = TextEditingController();
TextEditingController placeController = TextEditingController();
TextEditingController timeController = TextEditingController();
TextEditingController dateController = TextEditingController();
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
final textHeadStyle =
TextStyle(fontSize: 40.0, fontWeight: FontWeight.bold);
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Image.asset(
'assets/images/ml_logo.png',
height: 40,
),
),
// Form för att kunna använda TextFormField
body: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 50),
Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Text('Ny aktivitet',
textAlign: TextAlign.center, style: textHeadStyle),
),
SizedBox(height: 20),
Container(
alignment: Alignment.center,
child: SizedBox(
width: 300,
height: 80,
child: TextFormField(
maxLength: 16,
controller: titleController,
keyboardType: TextInputType.text,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Namn på aktivitet',
hintText: 'Ange namn på aktivitet',
),
onSaved: (String? value) {},
// Kolla så namnet inte är tomt
validator: (String? value) {
return (value != null && value != "")
? null
: 'Skriv in ett namn på aktiviteten';
},
),
),
),
SizedBox(height: 20),
Container(
alignment: Alignment.center,
child: SizedBox(
width: 300,
height: 80,
child: TextFormField(
maxLength: 16,
controller: placeController,
keyboardType: TextInputType.text,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Plats',
hintText: 'Ange plats',
),
onSaved: (String? value) {},
// Kolla så platsen inte är tom
validator: (String? value) {
return (value != null && value != "")
? null
: 'Skriv in en plats';
},
),
),
),
SizedBox(height: 20),
Container(
alignment: Alignment.center,
child: SizedBox(
width: 300,
height: 80,
child: TextFormField(
readOnly: true,
maxLength: 5,
controller: timeController,
onTap: () async {
FocusScope.of(context).requestFocus(FocusNode());
TimeOfDay? selectedTime24Hour = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (BuildContext context, Widget? child) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(alwaysUse24HourFormat: true),
child: child!,
);
},
);
if (selectedTime24Hour != null) {
timeController.text =
selectedTime24Hour.toString().substring(10, 15);
}
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Tid',
hintText: 'Ange tid',
),
onSaved: (String? value) {},
// Kollar tidens giltighet
validator: (String? value) {
return (value != null &&
value != "" &&
validateTimeValue(value))
? null
: 'Välj en tid som inte har passerat';
},
),
),
),
SizedBox(height: 20),
Container(
alignment: Alignment.center,
child: SizedBox(
width: 300,
height: 80,
child: TextFormField(
readOnly: true,
controller: dateController,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
_restorableDatePickerRouteFuture.present();
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Datum',
hintText: 'Ange datum',
),
onSaved: (String? value) {},
validator: (String? value) {
return (value != null && value != "")
? null
: 'Välj ett datum';
},
),
),
),
SizedBox(height: 20.0),
SizedBox(
height: 50,
width: 200,
child: ElevatedButton(
style: TextButton.styleFrom(
backgroundColor: Color.fromARGB(255, 10, 179, 74),
),
onPressed: () async {
String dateTime =
"${dateController.text} ${timeController.text}:00";
if (_formKey.currentState!.validate()) {
if (await addActivity(titleController.text,
placeController.text, dateTime, user)) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: Duration(seconds: 1),
behavior: SnackBarBehavior.floating,
backgroundColor:
Color.fromARGB(255, 12, 148, 64),
content: Text(
"Aktivitet skapad!",
style: TextStyle(color: Colors.white),
)),
);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Meny(
user: user,
schoolDetails: schoolDetails,
)));
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: Duration(seconds: 7),
behavior: SnackBarBehavior.floating,
backgroundColor:
Color.fromARGB(255, 224, 24, 24),
content: Text(
"Kunda ej lägga till aktivitiet! $dateTime",
style: TextStyle(color: Colors.white),
)),
);
}
}
},
child: const Text('Skapa',
style:
TextStyle(color: Colors.white, fontSize: 16))),
)
],
),
)));
}
bool validateTimeValue(String value) {
TimeOfDay selectedTime = TimeOfDay(
hour: int.parse(value.split(":")[0]),
minute: int.parse(value.split(":")[1]));
double timetoDouble(TimeOfDay selectedTime) =>
selectedTime.hour + selectedTime.minute / 60.0;
double timeNowDouble(TimeOfDay timeNow) =>
TimeOfDay.now().hour + TimeOfDay.now().minute / 60.0;
if (_selectedDate.value.day == DateTime.now().day &&
timetoDouble(selectedTime) < timeNowDouble(TimeOfDay.now())) {
return false;
}
return true;
}
}