import 'package:bus_infotainment/singletons/live_information.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:url_launcher/url_launcher_string.dart'; class pages_Settings extends StatefulWidget { @override State createState() => _pages_SettingsState(); } class _pages_SettingsState extends State { @override Widget build(BuildContext context) { if (LiveInformation().auth.isAuthenticated()){ return Container( ); } else { return _LoginPage( onLogin: () { }, ); } } } enum _LoginType { login, signup } class _LoginPage extends StatefulWidget { _LoginType type = _LoginType.login; final Function() onLogin; _LoginPage({super.key, required this.onLogin, }); @override State<_LoginPage> createState() => _LoginPageState(); } class _LoginPageState extends State<_LoginPage> { @override Widget build(BuildContext context) { return Container( color: Color.fromRGBO(19, 19, 19, 1), padding: const EdgeInsets.symmetric(horizontal: 32), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Login form widget.type == _LoginType.login ? LoginForm( handleSubmit: (form) { print("Login form submitted"); LiveInformation().auth.createEmailSession( email: form.emailController.text, password: form.passwordController.text ).then((value) { widget.onLogin(); }); }, requestSignup: () { setState(() { widget.type = _LoginType.signup; }); }, ) : SignupForm( handleSubmit: (form) { print("Signup form submitted"); LiveInformation().auth.createUser( displayName: form.dispnameController.text, username: form.usernameController.text, email: form.emailController.text, password: form.passwordController.text ).then((value) { // login LiveInformation().auth.createEmailSession( email: form.emailController.text, password: form.passwordController.text ).then((value) { widget.onLogin(); }); }); }, requestSignin: () { setState(() { widget.type = _LoginType.login; }); }, ), ], ), ); } } class LoginForm extends StatefulWidget { final Function(LoginForm) handleSubmit; final Function() requestSignup; /* TextControllers */ final TextEditingController emailController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); LoginForm({super.key, required this.handleSubmit, required this.requestSignup}); @override State createState() => _LoginFormState(); } class _LoginFormState extends State { @override Widget build(BuildContext context) { return Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Sign In", style: GoogleFonts.montserrat( fontSize: 32, fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: -1 ) ), SizedBox(height: 20), PW_TextField( title: "Email", controller: widget.emailController, handleSubmit: (form) { print("Signup form submitted"); widget.handleSubmit(widget); } ), SizedBox(height: 20), PW_TextField( title: "Password", obscure: true, controller: widget.passwordController, handleSubmit: (form) { print("Signup form submitted"); widget.handleSubmit(widget); } ), SizedBox(height: 20), ElevatedButton( onPressed: (){ widget.handleSubmit(widget); }, // make the corner radius 4, background color match the theme, and text colour white, fill to width of parent style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4) ), minimumSize: Size(double.infinity, 48) ), child: Text( "Sign in", style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: 0.5 ) ) ), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( onPressed: (){ }, // Make border radius 4, background transparent, and text colour white style: TextButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4) ), backgroundColor: Colors.transparent ), child: Text( "Forgot password?", style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade400, letterSpacing: 0.5 ), ) ), Container( width: 1, height: 24, margin: const EdgeInsets.symmetric(horizontal: 8), color: Colors.grey.shade800, ), TextButton( onPressed: (){ widget.requestSignup(); }, // Make border radius 4, background transparent, and text colour white style: TextButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4) ), backgroundColor: Colors.transparent ), child: Text( "Sign Up", style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade400, letterSpacing: 0.5 ), ) ), ], ), ], ) ); } } class SignupForm extends StatelessWidget { final Function(SignupForm) handleSubmit; final Function() requestSignin; /* TextControllers */ final TextEditingController dispnameController = TextEditingController(); final TextEditingController usernameController = TextEditingController(); final TextEditingController emailController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); final TextEditingController confirmPasswordController = TextEditingController(); SignupForm({super.key, required this.handleSubmit, required this.requestSignin}); @override Widget build(BuildContext context) { return Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Sign Up", style: GoogleFonts.montserrat( fontSize: 32, fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: -1 ) ), SizedBox(height: 20), PW_TextField( title: "Display Name", controller: dispnameController, handleSubmit: (form) { print("Signup form submitted"); handleSubmit(this); } ), SizedBox(height: 20), PW_TextField( title: "Username", controller: usernameController, handleSubmit: (form) { print("Signup form submitted"); handleSubmit(this); } ), SizedBox(height: 20), PW_TextField( title: "Email", controller: emailController, handleSubmit: (form) { print("Signup form submitted"); handleSubmit(this); } ), SizedBox(height: 20), PW_TextField( title: "Password", obscure: true, controller: passwordController, handleSubmit: (form) { print("Signup form submitted"); handleSubmit(this); } ), SizedBox(height: 20), PW_TextField( title: "Confirm Password", obscure: true, controller: confirmPasswordController, handleSubmit: (form) { print("Signup form submitted"); handleSubmit(this); } ), SizedBox(height: 20), // Terms and conditions with hyperlink to terms and conditions, with checkbox // use TextSpan // use check box Row( children: [ Checkbox( value: false, onChanged: (value) { print("Checkbox changed to $value"); }, ), Expanded( child: RichText( // wrap text text: TextSpan( children: [ TextSpan( text: "By registering, you agree to our ", style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade400, letterSpacing: 0.5, ), ), TextSpan( text: "Terms and Conditions", style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade400, letterSpacing: 0.5, decoration: TextDecoration.underline, ), recognizer: new TapGestureRecognizer() ..onTap = () { launchUrlString("https://google.co.uk/"); }, ), ], ), ), ), ], ), SizedBox(height: 20), ElevatedButton( onPressed: (){ handleSubmit(this); }, // make the corner radius 4, background color match the theme, and text colour white, fill to width of parent style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4) ), minimumSize: Size(double.infinity, 48) ), child: Text( "Sign up", style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: 0.5 ) ) ), SizedBox(height: 20), // Already have an account? Sign in Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "Already have an account? ", style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade400, letterSpacing: 0.5, ), ), TextButton( onPressed: (){ requestSignin(); }, // Make border radius 4, background transparent, and text colour white style: TextButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4) ), backgroundColor: Colors.transparent ), child: Text( "Sign in", style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade400, letterSpacing: 0.5 ), ) ), ], ), ], ) ); } } class PW_TextField extends StatelessWidget { String title = "field"; bool obscure = false; bool longText = false; late TextEditingController controller; Function(String)? handleTapOutside; Function(String)? handleEditingComplete; Function(String)? handleChanged; Function(String)? handleSubmit; PW_TextField({super.key, this.title = "field", required this.controller, this.obscure = false, this.longText = false, this.handleSubmit, this.handleTapOutside, this.handleEditingComplete, this.handleChanged}); @override Widget build(BuildContext context) { // TODO: implement build return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade300, letterSpacing: 0.1 ) ), SizedBox(height: 4), // field with uniform padding and margin SizedBox( child: TextField( onEditingComplete: () { if (handleEditingComplete != null) { handleEditingComplete!(controller.text); } }, onChanged: (value) { if (handleChanged != null) { handleChanged!(controller.text); } }, onSubmitted: (value) { if (handleSubmit != null) { handleSubmit!(controller.text); } }, onTapOutside: (value) { if (handleTapOutside != null) { handleTapOutside!(controller.text); } }, decoration: InputDecoration( contentPadding: const EdgeInsets.all(12), isDense: true, border: OutlineInputBorder( borderRadius: BorderRadius.circular(4), ), filled: true, // fillColor: STUDIOS_DEFAULT_BACKGROUND_COLOR, hintText: title, hintStyle: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade700, letterSpacing: 0.1 ), ), // wrap text minLines: longText ? 3 : 1, maxLines: longText ? null : 1, keyboardType: TextInputType.multiline, obscureText: obscure, style: GoogleFonts.interTight( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey.shade300, letterSpacing: 0.1, ), controller: controller, ), ) ], ); } }