woocommerce_inventory/mobile_app/lib/screens/profile_login_screen.dart

138 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../profile_manager.dart';
class ProfileLoginScreen extends StatefulWidget {
const ProfileLoginScreen({super.key});
@override
State<ProfileLoginScreen> createState() => _ProfileLoginScreenState();
}
class _ProfileLoginScreenState extends State<ProfileLoginScreen> {
final _pinController = TextEditingController();
final _confirmController = TextEditingController();
bool _isCreating = false;
String _error = '';
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Check if we need to create a PIN
final profile = Provider.of<ProfileManager>(context, listen: false);
// Note: profile status might update async, so we rely on Consumer in AuthWrapper usually,
// but here we are inside the screen.
// Actually, AuthWrapper decides if we show this screen.
// If we are here, it means !isAuthenticated.
// We check hasPin to decide mode.
}
void _handleSubmit() async {
final profile = Provider.of<ProfileManager>(context, listen: false);
if (_pinController.text.length < 4) {
setState(() => _error = 'PIN must be at least 4 digits');
return;
}
if (!profile.hasPin) {
// Creating Request
if (!_isCreating) {
// Ask for confirmation
setState(() {
_isCreating = true;
_error = '';
});
return;
}
if (_pinController.text != _confirmController.text) {
setState(() => _error = 'PINs do not match');
return;
}
await profile.setPin(_pinController.text);
} else {
// Unlocking
final success = await profile.unlock(_pinController.text);
if (!success) {
setState(() => _error = 'Incorrect PIN');
}
}
}
@override
Widget build(BuildContext context) {
// Watch hasPin to react if it changes (rare here but good practice)
final hasPin = Provider.of<ProfileManager>(context).hasPin;
return Scaffold(
body: Center(
child: Container(
constraints: const BoxConstraints(maxWidth: 400),
padding: const EdgeInsets.all(32),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.lock_outline, size: 64, color: Colors.blue),
const SizedBox(height: 24),
Text(
hasPin ? 'Enter Master PIN' : (_isCreating ? 'Confirm Master PIN' : 'Create Master PIN'),
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
hasPin
? 'Unlock your secure profiles'
: 'Protect your store credentials',
style: const TextStyle(color: Colors.grey),
),
const SizedBox(height: 32),
TextField(
controller: _pinController,
obscureText: true,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'PIN',
prefixIcon: Icon(Icons.password),
),
onSubmitted: (_) => _isCreating ? null : _handleSubmit(), // If confirming, focus next or submit
),
if (_isCreating) ...[
const SizedBox(height: 16),
TextField(
controller: _confirmController,
obscureText: true,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'Confirm PIN',
prefixIcon: Icon(Icons.check),
),
onSubmitted: (_) => _handleSubmit(),
),
],
if (_error.isNotEmpty) ...[
const SizedBox(height: 16),
Text(_error, style: const TextStyle(color: Colors.red)),
],
const SizedBox(height: 32),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _handleSubmit,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
child: Text(hasPin ? 'Unlock' : (_isCreating ? 'Save PIN' : 'Next')),
),
),
],
),
),
),
);
}
}