// 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 'dart:async'; import 'package:flutter/material.dart'; import 'package:smilet/LoginPage.dart'; import 'package:http/http.dart' as http; import 'package:smilet/User.dart'; bool addSuccess = false; bool usernameTaken = false; class CreateLoginPage extends StatefulWidget { final int regNumber; final String schoolCode; final Map schoolDetails; const CreateLoginPage( {super.key, required this.regNumber, required this.schoolCode, required this.schoolDetails}); @override _CreateLoginPageState createState() => _CreateLoginPageState(); } class _CreateLoginPageState extends State { String username = ""; String password = ""; TextEditingController usernameController = TextEditingController(); TextEditingController passwordController = TextEditingController(); final _formKey = GlobalKey(); // Registrera och lägg till användaren i databasen // Returnerar true om tillägget lyckades Future addUser(User user) async { var response = await http.get(Uri.parse( "http://group-15-3.pvt.dsv.su.se/user/add?id=${user.getId()}&username=${user.getUsername()}&password=${user.getPassword()}&schoolCode=${user.getSchoolCode()}")); if (response.statusCode == 200) { // Användare lades till return true; } else { return false; } } // Kolla om ett username är taget // Returnerar true om det är taget Future checkUsername(String username) async { debugPrint( 'https://group-15-3.pvt.dsv.su.se/user/exists?username=$username'); var response = await http.get(Uri.parse( 'https://group-15-3.pvt.dsv.su.se/user/exists?username=$username')); debugPrint(response.statusCode.toString()); debugPrint(response.body); if (response.statusCode == 409) { // If the server did return a 409 Conflict response, // then the username is already taken return true; } else { return false; } } @override Widget build(BuildContext context) { final textHeadStyle = TextStyle(fontSize: 25.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( children: [ Padding( padding: const EdgeInsets.only(top: 32), child: Text('Anmälningsnummer: ${widget.regNumber}', textAlign: TextAlign.center), ), Padding( padding: const EdgeInsets.only(bottom: 5.0), child: Text('Skolkod: ${widget.schoolCode}', textAlign: TextAlign.center), ), Padding( padding: const EdgeInsets.only(bottom: 100.0), child: Text( 'Skola: ${widget.schoolDetails["school"].toString().toUpperCase()}\nInstitution: ${widget.schoolDetails["institution"].toString().toUpperCase()}', textAlign: TextAlign.center, style: TextStyle(fontSize: 12, color: Colors.grey), ), ), Padding( padding: const EdgeInsets.only(bottom: 20.0), child: Text( 'Skapa inloggningssuppgifter', textAlign: TextAlign.center, style: textHeadStyle, ), ), Padding( padding: const EdgeInsets.all(8.0), child: Container( alignment: Alignment.center, child: SizedBox( width: 300, height: 100, child: TextFormField( onChanged: checkUsername, controller: usernameController, keyboardType: TextInputType.text, decoration: const InputDecoration( errorMaxLines: 2, border: OutlineInputBorder(), labelText: 'Användarnamn', hintText: 'Ange användarnamn', ), onSaved: (String? value) {}, // Kolla användarnamnets giltighet validator: (String? value) { return (value != null && validateUsernameStructure(value)) ? null : 'Ogiltigt användarnamn! Måste vara minst fyra tecken och max 15 tecken'; }, ), ), ), ), Container( alignment: Alignment.center, child: SizedBox( width: 300, height: 150, child: TextFormField( controller: passwordController, obscureText: true, decoration: const InputDecoration( errorMaxLines: 5, border: OutlineInputBorder(), labelText: 'Lösenord', hintText: 'Ange lösenord', ), onSaved: (String? value) {}, // Kolla lösenordets giltighet validator: (String? value) { return (value != null && validatePasswordStructure(value)) ? null : 'Ogiltigt lösenord! \nMåste innehålla minst en stor bokstav [A-Z], en siffra [0-9], ett specialtecken(!%&) och vara minst 8 tecken långt'; }, ), ), ), Padding( padding: const EdgeInsets.all(10.0), child: ElevatedButton( style: TextButton.styleFrom( backgroundColor: Color.fromARGB(255, 10, 179, 74), ), onPressed: () async { // Göm tangentbord FocusManager.instance.primaryFocus?.unfocus(); username = usernameController.text; password = passwordController.text; if (_formKey.currentState!.validate()) { // Kolla om användarnamnet är upptaget if (await checkUsername(username)) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( duration: Duration(seconds: 1), content: Text( 'Användarnamn "$username" upptaget!')), ); } else { // Registrera användare User user = User( id: widget.regNumber, username: username, password: password, schoolCode: widget.schoolCode); if (await addUser(user)) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( duration: Duration(seconds: 1), content: Text('Användare registrerad!')), ); Navigator.push( context, MaterialPageRoute( builder: (context) => LoginPage())); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( duration: Duration(seconds: 1), content: Text( "Fel: användare kunde ej registreras!")), ); } } } }, child: const Text('Skapa konto', style: TextStyle(color: Colors.white))), ), ], ), ))); } // Hjälpmetod för att validera att användarnamnets struktur är giltig bool validateUsernameStructure(String value) { return (value.length > 3 && value.length < 15); } // Hjälpmetod för att validera att lösenordets struktur är giltig bool validatePasswordStructure(String value) { String pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{8,}$'; RegExp regExp = RegExp(pattern); return regExp.hasMatch(value); } }