HopSpotFrontend/lib/pages/add_user_credentials_page.dart

301 lines
11 KiB
Dart

import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'package:pvt15/api/backend_api.dart';
import 'package:pvt15/models/user_model.dart';
import 'package:pvt15/pages/navigation_controller_page.dart';
import 'package:pvt15/providers/user_provider.dart';
class AddUserCredentialPage extends StatefulWidget {
final GoogleSignInAccount user;
const AddUserCredentialPage({super.key, required this.user});
@override
State<AddUserCredentialPage> createState() => _AddUserCredentialPageState();
}
class _AddUserCredentialPageState extends State<AddUserCredentialPage> {
final _formKey = GlobalKey<FormState>();
final _usernameController = TextEditingController();
String? _usernameError;
bool _isCheckingUsername = false;
Future<void> _validateUsername(String? value) async {
if (value == null || value.isEmpty) {
setState(() {
_usernameError = 'Vänligen ange ditt användarnamn';
});
return;
}
setState(() {
_isCheckingUsername = true; // Visa t.ex. en laddningsindikator
_usernameError = null; // Återställ tidigare fel
});
bool isTaken = await isUsernameTaken(value);
setState(() {
_isCheckingUsername = false; // Dölj laddningsindikatorn
if (isTaken) {
_usernameError = 'Användarnamnet är upptaget';
} else {
_usernameError = null; // Användarnamnet är ledigt
}
});
// Efter validering, trigga om valideringen för att visa eventuellt felmeddelande
_formKey.currentState?.validate();
}
Future<http.Response> saveUsername(String username) async {
final response = await authHttpRequest(
context: context,
url: 'https://group-1-15.pvt.dsv.su.se/api/users/username/$username',
method: 'PATCH',
);
return response;
}
String capitalize(String s) {
if (s.isEmpty) return s;
return s[0].toUpperCase() + s.substring(1).toLowerCase();
}
void handleSaveUsername(String username) async {
String capitalizedUsername = capitalize(username);
final http.Response response = await saveUsername(capitalizedUsername);
if (response.statusCode == 201) {
final userProvider = Provider.of<UserProvider>(context, listen: false);
final String profilePicUrl = widget.user.photoUrl ?? '';
userProvider.setUser(
AppUser(
googleID: widget.user.id,
name: '${widget.user.displayName}',
username: capitalizedUsername,
email: widget.user.email,
profilePicUrl: profilePicUrl,
),
);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NavigationControllerPage(user: widget.user),
settings: RouteSettings(name: '/gameCategory'),
),
);
} else {
print(
'Fel vid sparande av användaruppgifter. Statuskod: ${response.statusCode}',
);
}
}
Future<bool> isUsernameTaken(String username) async {
final response = await authHttpRequest(
context: context,
url: 'https://group-1-15.pvt.dsv.su.se/api/users/username/$username',
method: 'GET',
);
if (response.statusCode == 200) {
return true;
} else if (response.statusCode == 404) {
print('Hittade ingen användare');
return false;
} else {
print(
'Fel vid anrop till backend: ${response.statusCode} Body: ${response.body}',
);
throw Exception(
'Fel vid anrop till backend: ${response.statusCode} Body: ${response.body}',
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xFF7A28A5), Color(0xFFF9377B)],
),
),
child: Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Välkommen till',
style: TextStyle(fontSize: 32.0, color: Colors.white),
),
SizedBox(height: 20),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Hop',
textAlign: TextAlign.center,
style: TextStyle(
color: const Color(0xFFFF5394),
fontSize: 60,
fontFamily: 'Poppins',
fontWeight: FontWeight.w700,
height: 0.27,
letterSpacing: 0.50,
shadows: const [
Shadow(
offset: Offset(0, 6),
blurRadius: 8,
color: Color(0x3F000000),
),
],
),
),
const SizedBox(width: 0.50),
Text(
'Spot',
style: TextStyle(
color: const Color(0xFFFFC83B),
fontSize: 60,
fontFamily: 'Poppins',
fontWeight: FontWeight.w700,
height: 0.27,
letterSpacing: 0.50,
shadows: const [
Shadow(
offset: Offset(0, 6),
blurRadius: 8,
color: Color(0x3F000000),
),
],
),
),
],
),
SizedBox(height: 200),
Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Color(0x99FED3FF),
borderRadius: BorderRadius.circular(32.0),
boxShadow: const [
BoxShadow(
color: Color(0x3F000000),
blurRadius: 9,
offset: Offset(0, 0),
spreadRadius: 0,
),
],
),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32.0),
),
child: TextFormField(
controller: _usernameController,
decoration: InputDecoration(
labelText: 'Ange ditt användarnamn',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0),
borderSide: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0),
borderSide: BorderSide.none,
),
labelStyle: TextStyle(color: Colors.black),
fillColor: Colors.white,
filled: true,
errorText: _usernameError,
suffixIcon:
_isCheckingUsername
? CircularProgressIndicator()
: null,
floatingLabelBehavior:
FloatingLabelBehavior.never,
),
style: TextStyle(
color: Colors.black,
fontFamily: 'Poppins',
),
validator: (value) {
if (value == null || value.trim().isEmpty) {
return 'Användarnamn krävs!';
}
if (_usernameError != null) {
return _usernameError;
}
return null;
},
),
),
],
),
),
),
SizedBox(height: 200.0),
ElevatedButton(
onPressed: () async {
setState(() {
_usernameError = null;
_isCheckingUsername = true;
});
if (_formKey.currentState!.validate()) {
String username = _usernameController.text.trim();
await _validateUsername(username);
if (_usernameError == null &&
_formKey.currentState!.validate()) {
handleSaveUsername(username);
}
}
setState(() {
_isCheckingUsername = false;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF50D89B),
minimumSize: const Size(200, 0),
padding: const EdgeInsets.symmetric(vertical: 16.0),
textStyle: const TextStyle(
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.black,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(32.0),
),
shadowColor: Color(0x3F000000),
elevation: 9,
),
child: Text('Spara', style: TextStyle(color: Colors.white)),
),
],
),
),
),
),
);
}
}