import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:go_router/go_router.dart'; import '../../utils/definitions/style_guide.dart'; import '../../utils/logic/preferences_service.dart'; // For Haptic Feedback class StartPage extends StatelessWidget { const StartPage({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( title: 'PIN Input', home: PinInputScreen(), ); } } class PinInputScreen extends StatefulWidget { const PinInputScreen({super.key}); @override State createState() => _PinInputScreen(); } class _PinInputScreen extends State { String _pin = ''; static const int pinLength = 4; String _displayedText = "welcome back!"; @override void initState() { super.initState(); _checkPinStatus(); } Future _checkPinStatus() async { bool pinEnabled = await PreferencesService().isPinEnabled(); if (!pinEnabled) { Future.microtask(() { if (mounted) { context.go("/first"); } }); } } // This method would be your actual method for checking the pin // Replace with your actual method from PreferencesService Future checkPin(int pin) async { bool pinRight = await PreferencesService().checkPin(pin); return pinRight; } void _onNumberTap(int number) { if (_pin.length < pinLength) { setState(() { _pin += number.toString(); }); if (_pin.length == pinLength) { Timer(const Duration(milliseconds: 200), () { _validatePin(); }); } } } Future _validatePin() async { bool correct = await checkPin(int.parse(_pin)); if (correct) { if (mounted) { context.go("/first"); } // Perform any actions you need on successful pin entry } else { // Handle wrong pin entry, e.g., reset pin, show error, etc. if (kDebugMode) { print("Wrong PIN"); setState(() { _displayedText = "oops! try again."; }); } } // Resetting the PIN for this example, you might want to do this differently setState(() { _pin = ''; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppStyle.backgroundColor, body: Center( child: Container( height: 550, width: 380, decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(_displayedText, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), const SizedBox(height: 20), Row( mainAxisSize: MainAxisSize.min, children: List.generate(pinLength, (index) { return Container( margin: const EdgeInsets.all(4), width: 15, height: 15, decoration: BoxDecoration( color: _pin.length > index ? const Color(0xffD9D9D9) : Colors.transparent, border: Border.all(color: const Color(0xffD9D9D9)), borderRadius: BorderRadius.circular(15), ), ); }), ), const SizedBox(height: 20), ..._buildNumberPad(), ], ), ), ), ); } List _buildNumberPad() { List numbers = List.generate(9, (index) => index + 1); List rows = []; // First three rows (1-9) for (var i = 0; i < 3; i++) { rows.add( Row( mainAxisAlignment: MainAxisAlignment.center, children: numbers.skip(i * 3).take(3).map((number) { return _buildNumberButton(number); }).toList(), ), ); } // Last row with 0 rows.add( Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container(width: 70), // Empty container to align 0 in center _buildNumberButton(0), Container(width: 70), // Empty container to align 0 in center ], ), ); return rows; } Widget _buildNumberButton(int number) { return GestureDetector( onTap: () => _onNumberTap(number), onTapDown: (_) => HapticFeedback.lightImpact(), // Cool haptic feedback on tap child: Container( width: 70, height: 70, margin: const EdgeInsets.all(10), decoration: BoxDecoration( border: Border.all(color: Colors.black), borderRadius: BorderRadius.circular(35), ), child: Center( child: Text( number.toString(), style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), ), ), ); } }