Project

General

Profile


home_page.dart history_page.dart feeding_page.dart config_page.dart

connection_page.dart


import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'home_page.dart';

class ConnectionPage extends StatefulWidget {
  const ConnectionPage({super.key});

  @override
  State<ConnectionPage> createState() => _ConnectionPageState();
}

class _ConnectionPageState extends State<ConnectionPage> {
  final TextEditingController _idController = TextEditingController();
  bool _isLoading = false;

  Future<void> _conectarPecera() async {
    String idIngresado = _idController.text.trim().toUpperCase();

    if (idIngresado.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text("Por favor ingresa el ID que sale en la pantalla LCD"),
          backgroundColor: Colors.orange,
        )
      );
      return;
    }

    setState(() => _isLoading = true);

    try {
      String? token = await FirebaseMessaging.instance.getToken();

      if (token != null) {
        await FirebaseFirestore.instance
            .collection('acuarios')
            .doc(idIngresado)
            .collection('data')
            .doc('tokens')
            .set({
              'token_celular': token,
              'ultima_conexion': DateTime.now().toString(),
              'dispositivo': 'Android App'
            });

        print("Celular registrado en pecera $idIngresado");
      }

      setState(() => _isLoading = false);

      if (mounted) {
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (context) => SaveNemoHomePage(aquariumId: idIngresado),
          ),
        );
      }

    } catch (e) {
      setState(() => _isLoading = false);
      print("Error: $e");
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("Error de conexión: $e"), backgroundColor: Colors.red)
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF001B2E), // Fondo Azul Profundo
      body: Center(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(30.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                height: 160, 
                width: 160,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  border: Border.all(color: const Color(0xFFFF5400), width: 4), 
                  color: Colors.white.withOpacity(0.1),
                  // Descomenta la siguiente línea cuando tengas tu imagen en assets
                  image: const DecorationImage(image: AssetImage('assets/images/SaveNemo.png'), fit: BoxFit.cover),
                ),
                // Icono temporal por si la imagen falla o no está
                child: const Icon(Icons.qr_code_scanner, size: 80, color: Colors.white24), 
              ),

              const SizedBox(height: 40),

              const Text(
                "Vincular Acuario",
                style: TextStyle(
                  color: Colors.white, 
                  fontSize: 28, 
                  fontWeight: FontWeight.bold,
                  letterSpacing: 1.2
                ),
              ),

              const SizedBox(height: 15),

              const Text(
                "Ingresa el código ID que aparece en\nla pantalla LCD de tu Raspberry Pi",
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.white60, fontSize: 16, height: 1.5),
              ),

              const SizedBox(height: 50),

              // Texto ID
              TextField(
                controller: _idController,
                textAlign: TextAlign.center,
                style: const TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, letterSpacing: 3),
                textCapitalization: TextCapitalization.characters, 
                decoration: InputDecoration(
                  hintText: "EJ: NEMO-1234",
                  hintStyle: TextStyle(color: Colors.white.withOpacity(0.3), fontSize: 20, letterSpacing: 1),
                  filled: true,
                  fillColor: Colors.white.withOpacity(0.08),
                  contentPadding: const EdgeInsets.symmetric(vertical: 20),
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(15),
                    borderSide: BorderSide.none
                  ),
                  prefixIcon: const Icon(Icons.tag, color: Color(0xFFFF5400), size: 30),
                ),
              ),

              const SizedBox(height: 40),

              // Boton Conectar
              SizedBox(
                width: double.infinity,
                height: 60,
                child: ElevatedButton(
                  onPressed: _isLoading ? null : _conectarPecera,
                  style: ElevatedButton.styleFrom(
                    backgroundColor: const Color(0xFFFF5400),
                    foregroundColor: Colors.white,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(15),
                    ),
                    elevation: 10,
                    shadowColor: const Color(0xFFFF5400).withOpacity(0.5),
                  ),
                  child: _isLoading 
                    ? const SizedBox(
                        height: 30, width: 30, 
                        child: CircularProgressIndicator(color: Colors.white, strokeWidth: 3)
                      )
                    : const Text(
                        "CONECTAR", 
                        style: TextStyle(fontSize: 20, fontWeight: FontWeight.w900, letterSpacing: 2)
                      ),
                ),
              ),

              const SizedBox(height: 20),

              // Texto pequeño de ayuda
              Text(
                "Asegúrate de que tu Raspberry Pi esté encendida",
                style: TextStyle(color: Colors.white.withOpacity(0.3), fontSize: 12),
              )
            ],
          ),
        ),
      ),
    );
  }
}