| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- import 'dart:async';
- import 'dart:math';
- import 'package:flutter/material.dart';
- import 'package:fluttertoast/fluttertoast.dart';
- import 'package:localstore/localstore.dart';
- import '../providers/otp_provider.dart';
- class OTPPage extends StatefulWidget {
- const OTPPage({Key? key}) : super(key: key);
- @override
- State<OTPPage> createState() => _OTPPageState();
- }
- class _OTPPageState extends State<OTPPage> {
- final TextEditingController _codigo = TextEditingController();
- final _otpProvider = OTPProvider();
- final db = Localstore.instance;
- late Timer _timer;
- late String _oneTimePwd;
- int _errorCounter = 0;
- int _minutes = 5;
- int _seconds = 0;
- bool _verifyActive = false;
- bool _isWaiting = true;
- dynamic _logInfo;
- @override
- void initState() {
- super.initState();
- _oneTimePwd = _generateKey();
- _init();
- }
- void _startTimer(){
- const oneSec = Duration(seconds: 1);
- _timer = Timer.periodic(oneSec, (timer) => setState(() {
- if(_minutes < 1 && _seconds < 1){
- timer.cancel();
- }else if(_seconds == 0){
- _minutes -= 1;
- _seconds = 59;
- }else{
- _seconds -= 1;
- }
- }));
- }
- String _generateKey(){
- final rand = Random();
- String num = rand.nextInt(999999).toString();
- num = num.length == 5 ? "0$num" : num.length == 4 ? "00$num" : num.length == 3 ? "000$num" : num.length == 2 ? "0000$num" : num.length == 1 ? "00000$num" : num;
- return num;
- }
- void _init() async{
- final items = await db.collection('quiosco').get();
- final key = items!.keys.last;
- final info = items[key];
- _logInfo = info;
- _otpProvider.fetchOTP(info['accessToken'], info['dinum'], _oneTimePwd,
- _formattedDate(DateTime.now().toIso8601String()),
- _formattedDate(DateTime.now().add(const Duration(minutes: 5)).toIso8601String()),
- DateTime.now().year.toString());
- _startTimer();
- setState(() => _isWaiting = false);
- }
- @override
- void dispose() {
- _timer.cancel();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- final _screenSize = MediaQuery.of(context).size;
- return Scaffold(
- body: SafeArea(
- child: SingleChildScrollView(
- child: Column(
- children: [
- const SizedBox(height: 32.0),
- Row(
- children: const [
- SizedBox(
- width: 32.0,
- ),
- Image(
- image: AssetImage('assets/logo.png'),
- width: 64.0,
- ),
- SizedBox(width: 16.0),
- Expanded(
- child: Image(
- image: AssetImage('assets/logo_completo.png'),
- ),
- ),
- SizedBox(width: 32.0)
- ],
- ),
- const SizedBox(height: 48.0),
- const Image(
- image: AssetImage('assets/quiosco.png'),
- width: 88.0,
- fit: BoxFit.cover,
- ),
- const SizedBox(height: 16.0),
- const Text(
- 'QUIOSCO',
- textAlign: TextAlign.center,
- style: TextStyle(
- fontFamily: 'Helvetica Neue Black Cond',
- fontSize: 28.0
- ),
- ),
- const Text(
- 'Colaborador',
- textAlign: TextAlign.center,
- style: TextStyle(
- fontFamily: 'Helvetica Neue Light',
- fontSize: 22.0,
- fontWeight: FontWeight.w600,
- color: Color.fromRGBO(104, 104, 104, 1)
- ),
- ),
- const SizedBox(height: 16.0),
- if(_seconds > 0 || _minutes > 0)
- Container(
- margin: const EdgeInsets.symmetric(horizontal: 32.0),
- child: Text(
- 'Hola ${_isWaiting ? '' : _logInfo['user']}, hemos enviado un código a tu correo. '
- 'Por favor introdúcelo debajo para saber que eres tú.',
- textAlign: TextAlign.center,
- style: const TextStyle(
- fontFamily: 'Helvetica Neue Light',
- fontSize: 16.0,
- fontWeight: FontWeight.w300,
- color: Colors.grey
- ),
- ),
- ),
- if(_seconds < 1 && _minutes < 1)
- Container(
- margin: const EdgeInsets.symmetric(horizontal: 32.0),
- child: Text(
- 'Hola ${_logInfo['user']}, el código anterior ha expirado. '
- 'Por favor genera uno nuevo.',
- textAlign: TextAlign.center,
- style: const TextStyle(
- fontFamily: 'Helvetica Neue Light',
- fontSize: 16.0,
- fontWeight: FontWeight.w300,
- color: Colors.grey
- ),
- ),
- ),
- const SizedBox(height: 8.0),
- Text(
- _time(_minutes, _seconds),
- textAlign: TextAlign.center,
- style: const TextStyle(
- fontFamily: 'Helvetica Neue Light',
- fontSize: 22.0,
- fontWeight: FontWeight.w600,
- color: Color.fromRGBO(104, 104, 104, 1)
- ),
- ),
- const SizedBox(height: 16.0),
- Container(
- margin: const EdgeInsets.symmetric(horizontal: 32.0),
- child: Column(
- children: <Widget>[
- if(_seconds > 0 || _minutes > 0)
- TextField(
- keyboardType: TextInputType.number,
- controller: _codigo,
- decoration: const InputDecoration(
- hintText: 'Código de verificación:',
- contentPadding: EdgeInsets.zero,
- ),
- maxLines: 1,
- cursorColor: const Color.fromRGBO(180, 4, 4, 1),
- style: const TextStyle(
- fontSize: 20.0,
- ),
- onChanged: (value){
- setState(() {
- if(value.length == 6){
- _verifyActive = true;
- }else{
- _verifyActive = false;
- }
- });
- },
- ),
- if(_seconds < 1 && _minutes < 1)
- MaterialButton(
- elevation: 4.0,
- padding: const EdgeInsets.symmetric(vertical: 8.0),
- minWidth: _screenSize.width-64.0,
- color: const Color.fromRGBO(255, 0, 0, 1),
- child: const Text(
- 'Generar nuevo código',
- style: TextStyle(
- fontFamily: 'Helvetica Neue Black Cond',
- fontSize: 28.0,
- color: Colors.white,
- ),
- ),
- onPressed: () async{
- setState(() {
- _minutes = 5;
- _isWaiting = true;
- });
- _oneTimePwd = _generateKey();
- await _otpProvider.fetchOTP(
- _logInfo['accessToken'],
- _logInfo['dinum'],
- _oneTimePwd,
- _formattedDate(DateTime.now().toIso8601String()),
- _formattedDate(DateTime.now().add(const Duration(minutes: 5)).toIso8601String()),
- DateTime.now().year.toString()
- );
- _startTimer();
- setState(() {
- _isWaiting = false;
- });
- },
- ),
- const SizedBox(height: 16.0),
- if(_isWaiting)
- const CircularProgressIndicator(),
- if(!_isWaiting)
- MaterialButton(
- elevation: 4.0,
- padding: const EdgeInsets.symmetric(vertical: 8.0),
- minWidth: _screenSize.width-64.0,
- color: const Color.fromRGBO(255, 0, 0, 1),
- disabledColor: Colors.grey,
- child: const Text(
- 'Verificar',
- style: TextStyle(
- fontFamily: 'Helvetica Neue Black Cond',
- fontSize: 28.0,
- color: Colors.white,
- ),
- ),
- onPressed: !_verifyActive ? null : () async{
- FocusScope.of(context).requestFocus(FocusNode());
- if(_codigo.text == _oneTimePwd){ //Si entra en el intervalo de tiempo da true
- Fluttertoast.showToast(
- msg: 'Bienvenido ${_logInfo['user']}',
- toastLength: Toast.LENGTH_SHORT,
- gravity: ToastGravity.CENTER,
- timeInSecForIosWeb: 1,
- );
- final action = await Navigator.pushNamed(context, 'home');
- if(action == 'logout'){
- Navigator.pop(context);
- }else{
- print(action);
- }
- }else{
- setState(() {
- Fluttertoast.showToast(
- msg: 'Código inválido, intento ${_errorCounter + 1} de 3',
- toastLength: Toast.LENGTH_SHORT,
- gravity: ToastGravity.CENTER,
- timeInSecForIosWeb: 1,
- );
- _codigo.text = '';
- _verifyActive = false;
- _errorCounter += 1;
- if(_errorCounter > 2){
- Fluttertoast.showToast(
- msg: 'Ha exedido el número de intentos permitidos.',
- toastLength: Toast.LENGTH_LONG,
- gravity: ToastGravity.CENTER,
- timeInSecForIosWeb: 3,
- );
- _minutes = 0;
- _seconds = 0;
- }
- });
- }
- },
- ),
- ],
- ),
- ),
- const SizedBox(height: 32.0),
- ],
- ),
- ),
- ),
- );
- }
- String _formattedDate(String date){
- final year = date.substring(2, 4);
- final month = date.substring(5, 7);
- final day = date.substring(8, 10);
- final hour = date.substring(11, 13);
- final minuts = date.substring(14, 16);
- final seconds = date.substring(17, 19);
- return '$day/$month/$year $hour:$minuts:$seconds';
- }
- String _time(int min, int sec){
- if(sec < 10){
- return '0$min:0$sec';
- }else{
- return '0$min:$sec';
- }
- }
- }
|