MIF_E31222596/monitoring/lib/screens/login_screen.dart

153 lines
5.2 KiB
Dart

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:monitoring/config.dart';
import 'forgot_password_screen.dart';
class LoginScreen extends StatefulWidget {
final Function(String token, Map<String, dynamic> user) onLoginSuccess;
const LoginScreen({super.key, required this.onLoginSuccess});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final TextEditingController _usernameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
bool _isLoading = false;
String _error = '';
Future<void> login() async {
setState(() {
_isLoading = true;
_error = '';
});
final url = Uri.parse('$baseUrl/login');
final response = await http.post(
url,
headers: {'Accept': 'application/json'},
body: {
'username': _usernameController.text.trim(),
'password': _passwordController.text.trim(),
},
);
setState(() {
_isLoading = false;
});
if (response.statusCode == 200) {
final data = json.decode(response.body);
final token = data['access_token'];
final user = Map<String, dynamic>.from(data['user']);
widget.onLoginSuccess(token, user);
} else {
final data = json.decode(response.body);
setState(() {
_error = data['message'] ?? 'Login gagal';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF43A047), Color(0xFFFFF176)], // Hijau ke kuning
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
padding: const EdgeInsets.all(16.0),
child: Center(
child: SingleChildScrollView(
child: Card(
elevation: 12,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
'Login Santri',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: Color(0xFF388E3C), // Hijau Tua
),
),
const SizedBox(height: 24),
if (_error.isNotEmpty)
Text(
_error,
style: const TextStyle(color: Colors.red),
),
TextField(
controller: _usernameController,
decoration: const InputDecoration(
labelText: 'Username',
prefixIcon: Icon(Icons.person),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: _passwordController,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 24),
_isLoading
? const CircularProgressIndicator()
: SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF8BC34A), // Hijau Muda
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: login,
child: const Text(
'Login',
style: TextStyle(fontSize: 16, color: Colors.white),
),
),
),
const SizedBox(height: 16),
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const ForgotPasswordScreen()),
);
},
child: const Text(
'Lupa Password?',
style: TextStyle(color: Color(0xFF388E3C)),
),
),
],
),
),
),
),
),
),
);
}
}