Project

General

Profile

Connection pagedart » History » Version 1

cristobal hernandez, 12/18/2025 01:48 AM

1 1 cristobal hernandez
---
2 1 cristobal hernandez
3 1 cristobal hernandez
| [[Interfaz|⌂]] | [[home_page.dart]] | [[history_page.dart]] | [[feeding_page.dart]] | [[config_page.dart]] | 
4 1 cristobal hernandez
5 1 cristobal hernandez
---
6 1 cristobal hernandez
7 1 cristobal hernandez
h1. connection_page.dart
8 1 cristobal hernandez
9 1 cristobal hernandez
<pre><code class="java">
10 1 cristobal hernandez
11 1 cristobal hernandez
import 'package:flutter/material.dart';
12 1 cristobal hernandez
import 'package:cloud_firestore/cloud_firestore.dart';
13 1 cristobal hernandez
import 'package:firebase_messaging/firebase_messaging.dart';
14 1 cristobal hernandez
import 'home_page.dart';
15 1 cristobal hernandez
16 1 cristobal hernandez
class ConnectionPage extends StatefulWidget {
17 1 cristobal hernandez
  const ConnectionPage({super.key});
18 1 cristobal hernandez
19 1 cristobal hernandez
  @override
20 1 cristobal hernandez
  State<ConnectionPage> createState() => _ConnectionPageState();
21 1 cristobal hernandez
}
22 1 cristobal hernandez
23 1 cristobal hernandez
class _ConnectionPageState extends State<ConnectionPage> {
24 1 cristobal hernandez
  final TextEditingController _idController = TextEditingController();
25 1 cristobal hernandez
  bool _isLoading = false;
26 1 cristobal hernandez
27 1 cristobal hernandez
  Future<void> _conectarPecera() async {
28 1 cristobal hernandez
    String idIngresado = _idController.text.trim().toUpperCase();
29 1 cristobal hernandez
    
30 1 cristobal hernandez
    if (idIngresado.isEmpty) {
31 1 cristobal hernandez
      ScaffoldMessenger.of(context).showSnackBar(
32 1 cristobal hernandez
        const SnackBar(
33 1 cristobal hernandez
          content: Text("Por favor ingresa el ID que sale en la pantalla LCD"),
34 1 cristobal hernandez
          backgroundColor: Colors.orange,
35 1 cristobal hernandez
        )
36 1 cristobal hernandez
      );
37 1 cristobal hernandez
      return;
38 1 cristobal hernandez
    }
39 1 cristobal hernandez
40 1 cristobal hernandez
    setState(() => _isLoading = true);
41 1 cristobal hernandez
42 1 cristobal hernandez
    try {
43 1 cristobal hernandez
      String? token = await FirebaseMessaging.instance.getToken();
44 1 cristobal hernandez
      
45 1 cristobal hernandez
      if (token != null) {
46 1 cristobal hernandez
        await FirebaseFirestore.instance
47 1 cristobal hernandez
            .collection('acuarios')
48 1 cristobal hernandez
            .doc(idIngresado)
49 1 cristobal hernandez
            .collection('data')
50 1 cristobal hernandez
            .doc('tokens')
51 1 cristobal hernandez
            .set({
52 1 cristobal hernandez
              'token_celular': token,
53 1 cristobal hernandez
              'ultima_conexion': DateTime.now().toString(),
54 1 cristobal hernandez
              'dispositivo': 'Android App'
55 1 cristobal hernandez
            });
56 1 cristobal hernandez
            
57 1 cristobal hernandez
        print("Celular registrado en pecera $idIngresado");
58 1 cristobal hernandez
      }
59 1 cristobal hernandez
60 1 cristobal hernandez
      setState(() => _isLoading = false);
61 1 cristobal hernandez
62 1 cristobal hernandez
      if (mounted) {
63 1 cristobal hernandez
        Navigator.pushReplacement(
64 1 cristobal hernandez
          context,
65 1 cristobal hernandez
          MaterialPageRoute(
66 1 cristobal hernandez
            builder: (context) => SaveNemoHomePage(aquariumId: idIngresado),
67 1 cristobal hernandez
          ),
68 1 cristobal hernandez
        );
69 1 cristobal hernandez
      }
70 1 cristobal hernandez
71 1 cristobal hernandez
    } catch (e) {
72 1 cristobal hernandez
      setState(() => _isLoading = false);
73 1 cristobal hernandez
      print("Error: $e");
74 1 cristobal hernandez
      ScaffoldMessenger.of(context).showSnackBar(
75 1 cristobal hernandez
        SnackBar(content: Text("Error de conexión: $e"), backgroundColor: Colors.red)
76 1 cristobal hernandez
      );
77 1 cristobal hernandez
    }
78 1 cristobal hernandez
  }
79 1 cristobal hernandez
80 1 cristobal hernandez
  @override
81 1 cristobal hernandez
  Widget build(BuildContext context) {
82 1 cristobal hernandez
    return Scaffold(
83 1 cristobal hernandez
      backgroundColor: const Color(0xFF001B2E), // Fondo Azul Profundo
84 1 cristobal hernandez
      body: Center(
85 1 cristobal hernandez
        child: SingleChildScrollView(
86 1 cristobal hernandez
          padding: const EdgeInsets.all(30.0),
87 1 cristobal hernandez
          child: Column(
88 1 cristobal hernandez
            mainAxisAlignment: MainAxisAlignment.center,
89 1 cristobal hernandez
            children: [
90 1 cristobal hernandez
              Container(
91 1 cristobal hernandez
                height: 160, 
92 1 cristobal hernandez
                width: 160,
93 1 cristobal hernandez
                decoration: BoxDecoration(
94 1 cristobal hernandez
                  shape: BoxShape.circle,
95 1 cristobal hernandez
                  border: Border.all(color: const Color(0xFFFF5400), width: 4), 
96 1 cristobal hernandez
                  color: Colors.white.withOpacity(0.1),
97 1 cristobal hernandez
                  // Descomenta la siguiente línea cuando tengas tu imagen en assets
98 1 cristobal hernandez
                  image: const DecorationImage(image: AssetImage('assets/images/SaveNemo.png'), fit: BoxFit.cover),
99 1 cristobal hernandez
                ),
100 1 cristobal hernandez
                // Icono temporal por si la imagen falla o no está
101 1 cristobal hernandez
                child: const Icon(Icons.qr_code_scanner, size: 80, color: Colors.white24), 
102 1 cristobal hernandez
              ),
103 1 cristobal hernandez
              
104 1 cristobal hernandez
              const SizedBox(height: 40),
105 1 cristobal hernandez
              
106 1 cristobal hernandez
              const Text(
107 1 cristobal hernandez
                "Vincular Acuario",
108 1 cristobal hernandez
                style: TextStyle(
109 1 cristobal hernandez
                  color: Colors.white, 
110 1 cristobal hernandez
                  fontSize: 28, 
111 1 cristobal hernandez
                  fontWeight: FontWeight.bold,
112 1 cristobal hernandez
                  letterSpacing: 1.2
113 1 cristobal hernandez
                ),
114 1 cristobal hernandez
              ),
115 1 cristobal hernandez
              
116 1 cristobal hernandez
              const SizedBox(height: 15),
117 1 cristobal hernandez
              
118 1 cristobal hernandez
              const Text(
119 1 cristobal hernandez
                "Ingresa el código ID que aparece en\nla pantalla LCD de tu Raspberry Pi",
120 1 cristobal hernandez
                textAlign: TextAlign.center,
121 1 cristobal hernandez
                style: TextStyle(color: Colors.white60, fontSize: 16, height: 1.5),
122 1 cristobal hernandez
              ),
123 1 cristobal hernandez
124 1 cristobal hernandez
              const SizedBox(height: 50),
125 1 cristobal hernandez
126 1 cristobal hernandez
              // Texto ID
127 1 cristobal hernandez
              TextField(
128 1 cristobal hernandez
                controller: _idController,
129 1 cristobal hernandez
                textAlign: TextAlign.center,
130 1 cristobal hernandez
                style: const TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, letterSpacing: 3),
131 1 cristobal hernandez
                textCapitalization: TextCapitalization.characters, 
132 1 cristobal hernandez
                decoration: InputDecoration(
133 1 cristobal hernandez
                  hintText: "EJ: NEMO-1234",
134 1 cristobal hernandez
                  hintStyle: TextStyle(color: Colors.white.withOpacity(0.3), fontSize: 20, letterSpacing: 1),
135 1 cristobal hernandez
                  filled: true,
136 1 cristobal hernandez
                  fillColor: Colors.white.withOpacity(0.08),
137 1 cristobal hernandez
                  contentPadding: const EdgeInsets.symmetric(vertical: 20),
138 1 cristobal hernandez
                  border: OutlineInputBorder(
139 1 cristobal hernandez
                    borderRadius: BorderRadius.circular(15),
140 1 cristobal hernandez
                    borderSide: BorderSide.none
141 1 cristobal hernandez
                  ),
142 1 cristobal hernandez
                  prefixIcon: const Icon(Icons.tag, color: Color(0xFFFF5400), size: 30),
143 1 cristobal hernandez
                ),
144 1 cristobal hernandez
              ),
145 1 cristobal hernandez
146 1 cristobal hernandez
              const SizedBox(height: 40),
147 1 cristobal hernandez
148 1 cristobal hernandez
              // Boton Conectar
149 1 cristobal hernandez
              SizedBox(
150 1 cristobal hernandez
                width: double.infinity,
151 1 cristobal hernandez
                height: 60,
152 1 cristobal hernandez
                child: ElevatedButton(
153 1 cristobal hernandez
                  onPressed: _isLoading ? null : _conectarPecera,
154 1 cristobal hernandez
                  style: ElevatedButton.styleFrom(
155 1 cristobal hernandez
                    backgroundColor: const Color(0xFFFF5400),
156 1 cristobal hernandez
                    foregroundColor: Colors.white,
157 1 cristobal hernandez
                    shape: RoundedRectangleBorder(
158 1 cristobal hernandez
                      borderRadius: BorderRadius.circular(15),
159 1 cristobal hernandez
                    ),
160 1 cristobal hernandez
                    elevation: 10,
161 1 cristobal hernandez
                    shadowColor: const Color(0xFFFF5400).withOpacity(0.5),
162 1 cristobal hernandez
                  ),
163 1 cristobal hernandez
                  child: _isLoading 
164 1 cristobal hernandez
                    ? const SizedBox(
165 1 cristobal hernandez
                        height: 30, width: 30, 
166 1 cristobal hernandez
                        child: CircularProgressIndicator(color: Colors.white, strokeWidth: 3)
167 1 cristobal hernandez
                      )
168 1 cristobal hernandez
                    : const Text(
169 1 cristobal hernandez
                        "CONECTAR", 
170 1 cristobal hernandez
                        style: TextStyle(fontSize: 20, fontWeight: FontWeight.w900, letterSpacing: 2)
171 1 cristobal hernandez
                      ),
172 1 cristobal hernandez
                ),
173 1 cristobal hernandez
              ),
174 1 cristobal hernandez
              
175 1 cristobal hernandez
              const SizedBox(height: 20),
176 1 cristobal hernandez
              
177 1 cristobal hernandez
              // Texto pequeño de ayuda
178 1 cristobal hernandez
              Text(
179 1 cristobal hernandez
                "Asegúrate de que tu Raspberry Pi esté encendida",
180 1 cristobal hernandez
                style: TextStyle(color: Colors.white.withOpacity(0.3), fontSize: 12),
181 1 cristobal hernandez
              )
182 1 cristobal hernandez
            ],
183 1 cristobal hernandez
          ),
184 1 cristobal hernandez
        ),
185 1 cristobal hernandez
      ),
186 1 cristobal hernandez
    );
187 1 cristobal hernandez
  }
188 1 cristobal hernandez
}
189 1 cristobal hernandez
   
190 1 cristobal hernandez
</code></pre>