Pagina registro

 avatar
user_1600140
dart
20 days ago
23 kB
4
Indexable
Never
import 'dart:io';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:lottie/lottie.dart';
import 'package:proteus_conductor/authentication/login_screen.dart';
import 'package:proteus_conductor/methods/common_methods.dart';
import 'package:proteus_conductor/pages/dashboard.dart';
import 'package:proteus_conductor/widgets/loading_dialog.dart';

class SignUpScreen extends StatefulWidget {
  const SignUpScreen({Key? key}) : super(key: key);

  @override
  State<SignUpScreen> createState() => _SignUpScreenState();
}

class _SignUpScreenState extends State<SignUpScreen> {
  TextEditingController userNameTextEditingController = TextEditingController();
  TextEditingController userPhoneTextEditingController = TextEditingController();
  TextEditingController emailTextEditingController = TextEditingController();
  bool showUpperCaseWarning = true;
  TextEditingController passwordTextEditingController = TextEditingController();
  TextEditingController confirmPasswordTextEditingController = TextEditingController();
  TextEditingController vehicleModelTextEditingController = TextEditingController();
  TextEditingController vehicleColorTextEditingController = TextEditingController();
  TextEditingController vehicleNumberTextEditingController = TextEditingController();
  CommonMethods cMethods = CommonMethods();
  XFile? imageFile;
  String urlOfUploadedImage = "";

  bool isPasswordVisible = false;
  Color selectedColor = Colors.blue;

  checkIfNetworkIsAvailable() {
    cMethods.checkConnectivity(context);
    signUpFormValidation();
  }

  signUpFormValidation() {
    if (imageFile == null) {
      cMethods.displaySnackBar("Por favor primero escoge una fotografía", context);
      return;
    }

    if (userNameTextEditingController.text.trim().length < 3) {
      cMethods.displaySnackBar("Tu nombre debe tener al menos 4 caracteres.", context);
    } else if (userPhoneTextEditingController.text.trim().length < 7) {
      cMethods.displaySnackBar("Tu número de celular debe tener al menos 8 dígitos.", context);
    } else if (!emailTextEditingController.text.contains("@")) {
      cMethods.displaySnackBar("Por favor, ingresa un correo electrónico válido.", context);
    } else if (passwordTextEditingController.text.trim().length < 8) {
      cMethods.displaySnackBar("Tu contraseña debe tener al menos 8 caracteres.", context);
    } else if (vehicleModelTextEditingController.text.trim().isEmpty) {
      cMethods.displaySnackBar("Por favor bríndanos el año de tu carro", context);
    } else if (vehicleColorTextEditingController.text.trim().isEmpty) {
      cMethods.displaySnackBar("¿Cuál es el color de tu vehículo?.", context);
    } else if (vehicleNumberTextEditingController.text.isEmpty) {
      cMethods.displaySnackBar("Bríndanos tu número de placa.", context);
    } else {
      uploadImageToStorage();
    }
  }

  uploadImageToStorage() async {
    if (imageFile == null) {
      cMethods.displaySnackBar("Por favor primero escoge una fotografía", context);
      return;
    }

    String imageIDName = DateTime.now().millisecondsSinceEpoch.toString();
    String fileExtension = imageFile!.path.split('.').last;

    Reference referenceImage = FirebaseStorage.instance.ref().child("Imagenes").child("$imageIDName.$fileExtension");

    UploadTask uploadTask = referenceImage.putFile(File(imageFile!.path));
    TaskSnapshot snapshot = await uploadTask;
    urlOfUploadedImage = await snapshot.ref.getDownloadURL();

    setState(() {
      urlOfUploadedImage;
    });

    registerNewDriver();
  }

  registerNewDriver() async {
    BuildContext originalContext = context;

    showDialog(
      context: originalContext,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return LoadingDialog(messageText: "Conectando con el servidor...");
      },
    );

    await Future.delayed(const Duration(seconds: 2));

    showDialog(
      context: originalContext,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return LoadingDialog(messageText: "Registrando usuario...");
      },
    );

    await Future.delayed(const Duration(seconds: 3));

    try {
      final UserCredential userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
        email: emailTextEditingController.text.trim(),
        password: passwordTextEditingController.text.trim(),
      );

      if (!originalContext.mounted) return;
      Navigator.pop(originalContext);

      DatabaseReference usersRef = FirebaseDatabase.instance.ref().child("Conductores").child(userCredential.user!.uid);

      Map driverCarInfo = {
        "Color Del Vehículo": vehicleColorTextEditingController.text.trim(),
        "Modelo Del Carro": vehicleModelTextEditingController.text.trim(),
        "Número De Placa": vehicleNumberTextEditingController.text.trim(),
      };

      Map driverDataMap = {
        "Foto": urlOfUploadedImage,
        "Detalles Del Vehículo": driverCarInfo,
        "Nombre": userNameTextEditingController.text.trim(),
        "email": emailTextEditingController.text.trim(),
        "Celular": userPhoneTextEditingController.text.trim(),
        "id": userCredential.user!.uid,
        "Estado De Bloqueo": "no",
      };
      usersRef.set(driverDataMap);

      showDialog(
        context: originalContext,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return LoadingDialog(messageText: "Cargando, por favor espera...");
        },
      );

      await Future.delayed(const Duration(seconds: 3));

      Navigator.push(originalContext, MaterialPageRoute(builder: (c) => const Dashboard()));
    } catch (error) {
      if (!originalContext.mounted) return;
      Navigator.pop(originalContext);
      cMethods.displaySnackBar(error.toString(), originalContext);
    }
  }

  void _selectYear(BuildContext context) async {
    int selectedYear = DateTime.now().year;

    await showCupertinoDialog<int>(
      context: context,
      builder: (BuildContext context) {
        return CupertinoAlertDialog(
          title: const Text('Escoge el año de tu carro.'),
          content: SizedBox(
            height: 200,
            child: CupertinoPicker(
              itemExtent: 40,
              children: List.generate(2024 - 2007 + 1, (index) {
                return Center(
                  child: Text(
                    (2007 + index).toString(),
                    style: const TextStyle(fontSize: 18),
                  ),
                );
              }),
              onSelectedItemChanged: (int index) {
                selectedYear = 2007 + index;
              },
            ),
          ),
          actions: [
            CupertinoDialogAction(
              onPressed: () {
                Navigator.of(context).pop(selectedYear);
              },
              child: const Text('<< ACEPTAR >> '),
            ),
          ],
        );
      },
    );

    setState(() {
      vehicleModelTextEditingController.text = selectedYear.toString();
    });
  }

  void _selectColor(BuildContext context) async {
    String selectedColor = vehicleColorTextEditingController.text;

    await showCupertinoDialog<String>(
      context: context,
      builder: (BuildContext context) {
        return CupertinoAlertDialog(
          title: const Text('Selecciona el color de tu vehículo.'),
          content: SizedBox(
            height: 200,
            child: CupertinoPicker(
              itemExtent: 40,
              children: [
                buildColoredText("Blanco", Colors.white),
                buildColoredText("Celeste", Colors.lightBlueAccent),
                buildColoredText("Azul", Colors.blue),
                buildColoredText("Turquesa", Colors.cyan),
                buildColoredText("Verde", Colors.green),
                buildColoredText("Amarillo", Colors.yellow),
                buildColoredText("Naranja", Colors.orange),
                buildColoredText("Rojo", Colors.red),
                buildColoredText("Morado", Colors.purple),
                buildColoredText("Café/Marrón", Colors.brown),
                buildColoredText("Gris", Colors.grey),
                buildColoredText("Negro", Colors.black),
              ],
              onSelectedItemChanged: (int index) {
                // Puedes asignar el color correspondiente aquí
                switch (index) {
                  case 0:
                    selectedColor = "Blanco";
                    break;
                  case 1:
                    selectedColor = "Celeste";
                    break;
                  case 2:
                    selectedColor = "Azul";
                    break;
                  case 3:
                    selectedColor = "Turquesa";
                    break;
                  case 4:
                    selectedColor = "Verde";
                    break;
                  case 5:
                    selectedColor = "Amarillo";
                    break;
                  case 6:
                    selectedColor = "Naranja";
                    break;
                  case 7:
                    selectedColor = "Rojo";
                    break;
                  case 8:
                    selectedColor = "Morado";
                    break;
                  case 9:
                    selectedColor = "Café/Marrón";
                    break;
                  case 10:
                    selectedColor = "Gris";
                    break;
                  case 11:
                    selectedColor = "Negro";
                    break;
                }
              },
            ),
          ),
          actions: [
            CupertinoDialogAction(
              onPressed: () {
                Navigator.of(context).pop(selectedColor);
              },
              child: const Text('<< ACEPTAR >> '),
            ),
          ],
        );
      },
    );

    setState(() {
      vehicleColorTextEditingController.text = selectedColor;
    });
  }

  Widget buildColoredText(String text, Color color) {
    return Container(
      color: color,
      child: Center(
        child: Text(
          text,
          style: const TextStyle(fontSize: 18),
        ),
      ),
    );
  }

  chooseImageFromGallery() async {
    final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery);
    if (pickedFile != null) {
      setState(() {
        imageFile = pickedFile;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(10),
          child: Column(
            children: [
              Lottie.asset(
                'assets/animaciones/ondas_azules.json',
                height: 300,
                width: double.infinity,
                repeat: true,
                reverse: false,
              ),
              const SizedBox(height: 40),
              GestureDetector(
                onTap: chooseImageFromGallery,
                child: Container(
                  width: 180,
                  height: 180,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: Colors.grey,
                    image: imageFile == null
                        ? null
                        : DecorationImage(
                      fit: BoxFit.fitHeight,
                      image: Image.file(
                        File(imageFile!.path),
                      ).image,
                    ),
                  ),
                  child: imageFile == null
                      ? Lottie.asset(
                    'assets/animaciones/varias_personas.json',
                    width: 150,
                    height: 100,
                    fit: BoxFit.cover,
                  )
                      : null,
                ),
              ),
              const SizedBox(height: 10),
              const Text(
                "Escoge Una Fotografía Tuya",
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 10),
              const Text(
                "Crea Tu Cuenta De Conductor/a",
                style: TextStyle(
                  fontSize: 22,
                  fontWeight: FontWeight.bold,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(10),
                child: Column(
                  children: [
                    TextField(
                      controller: userNameTextEditingController,
                      keyboardType: TextInputType.text,
                      inputFormatters: [
                        FilteringTextInputFormatter.allow(RegExp('[a-zA-Z]')),
                      ],
                      decoration: const InputDecoration(
                        labelText: "Nombre Del Conductor*:",
                        labelStyle: TextStyle(
                          fontSize: 14,
                        ),
                        hintText: "Ingresa tu nombre de usuario",
                      ),
                      style: const TextStyle(
                        color: Colors.grey,
                        fontSize: 15,
                      ),
                    ),
                    const SizedBox(height: 2),
                    TextField(
                      controller: emailTextEditingController,
                      keyboardType: TextInputType.emailAddress,
                      inputFormatters: [
                        FilteringTextInputFormatter.allow(RegExp('[a-z0-9@.]')),
                        TextInputFormatter.withFunction((oldValue, newValue) {
                          return newValue.copyWith(
                              text: newValue.text.toLowerCase());
                        }),
                      ],
                      decoration: const InputDecoration(
                        labelText: "Correo Del Conductor*:",
                        labelStyle: TextStyle(
                          fontSize: 14,
                        ),
                        hintText: "Ingresa tu correo electrónico",
                      ),
                      style: const TextStyle(
                        color: Colors.grey,
                        fontSize: 15,
                      ),
                    ),
                    const SizedBox(height: 2),
                    TextField(
                      controller: userPhoneTextEditingController,
                      keyboardType: TextInputType.number,
                      inputFormatters: [
                        FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
                        LengthLimitingTextInputFormatter(8),
                      ],
                      decoration: const InputDecoration(
                        labelText: "Número De Celular*:",
                        labelStyle: TextStyle(
                          fontSize: 14,
                        ),
                        hintText: "Tu número de celular (sin espacios, ni guiones).",
                      ),
                      style: const TextStyle(
                        color: Colors.grey,
                        fontSize: 15,
                      ),
                    ),
                    const SizedBox(height: 2),
                    TextField(
                      controller: passwordTextEditingController,
                      obscureText: !isPasswordVisible,
                      keyboardType: TextInputType.text,
                      decoration: InputDecoration(
                        labelText: "Contraseña*:",
                        labelStyle: const TextStyle(
                          fontSize: 14,
                        ),
                        hintText: "Crea tu contraseña con 8 caracteres o más",
                        suffixIcon: IconButton(
                          icon: Icon(
                            isPasswordVisible
                                ? Icons.visibility
                                : Icons.visibility_off,
                          ),
                          onPressed: () {
                            setState(() {
                              isPasswordVisible = !isPasswordVisible;
                            });
                          },
                        ),
                      ),
                      style: const TextStyle(
                        color: Colors.grey,
                        fontSize: 15,
                      ),
                      onChanged: (password) {
                        setState(() {
                          showUpperCaseWarning =
                              password.contains(RegExp(r'[A-Z]'));
                        });
                      },
                    ),
                    if (showUpperCaseWarning)
                      const Padding(
                        padding: EdgeInsets.only(top: 4),
                        child: Text(
                          "¡Aviso! La contraseña debe contener al menos una letra mayúscula.",
                          style: TextStyle(
                            color: Colors.red,
                            fontSize: 12,
                          ),
                        ),
                      ),
                    const SizedBox(height: 2),
                    TextField(
                      controller: confirmPasswordTextEditingController,
                      obscureText: true,
                      keyboardType: TextInputType.text,
                      decoration: const InputDecoration(
                        labelText: "Confirma Tu Contraseña*:",
                        labelStyle: TextStyle(
                          fontSize: 14,
                        ),
                        hintText: "Confirma tu contraseña",
                      ),
                      style: const TextStyle(
                        color: Colors.grey,
                        fontSize: 15,
                      ),
                    ),
                    const SizedBox(height: 2),
                    GestureDetector(
                      onTap: () {
                        _selectYear(context);
                      },
                      child: AbsorbPointer(
                        child: TextField(
                          controller: vehicleModelTextEditingController,
                          keyboardType: TextInputType.number,
                          decoration: const InputDecoration(
                            labelText: "Modelo Del Vehículo*:",
                            labelStyle: TextStyle(
                              fontSize: 14,
                            ),
                            hintText: "Escoge el año de tu carro",
                          ),
                          style: const TextStyle(
                            color: Colors.grey,
                            fontSize: 15,
                          ),
                        ),
                      ),
                    ),
                    const SizedBox(height: 2),
                    GestureDetector(
                      onTap: () {
                        _selectColor(context);
                      },
                      child: AbsorbPointer(
                        child: TextField(
                          controller: vehicleColorTextEditingController,
                          keyboardType: TextInputType.text,
                          decoration: const InputDecoration(
                            labelText: "Color Del Vehículo*:",
                            labelStyle: TextStyle(
                              fontSize: 14,
                            ),
                            hintText: "Escoge el color de tu carro",
                          ),
                          style: const TextStyle(
                            color: Colors.grey,
                            fontSize: 15,
                          ),
                        ),
                      ),
                    ),
                    const SizedBox(height: 2),
                    TextField(
                      controller: vehicleNumberTextEditingController,
                      keyboardType: TextInputType.text,
                      inputFormatters: [
                        FilteringTextInputFormatter.allow(RegExp('[a-zA-Z0-9]')),
                        LengthLimitingTextInputFormatter(10),
                      ],
                      decoration: const InputDecoration(
                        labelText: "Número De Placa*:",
                        labelStyle: TextStyle(
                          fontSize: 14,
                        ),
                        hintText: "Ingresa el número de placa de tu vehículo",
                      ),
                      style: const TextStyle(
                        color: Colors.grey,
                        fontSize: 15,
                      ),
                    ),
                    const SizedBox(height: 10),
                    ElevatedButton(
                      onPressed: () {
                        checkIfNetworkIsAvailable();
                      },
                      child: const Text("CREAR CUENTA"),
                    ),
                    const SizedBox(height: 10),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Text(
                          "¿Ya tienes una cuenta? ",
                          style: TextStyle(fontSize: 16),
                        ),
                        GestureDetector(
                          onTap: () {
                            Navigator.push(
                                context,
                                MaterialPageRoute(
                                    builder: (c) => const LoginScreen()));
                          },
                          child: const Text(
                            "Ingresa Aquí",
                            style: TextStyle(
                              fontSize: 16,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Leave a Comment