MIF_E31231027/smart_cycling/lib/screens/login_screen.dart

165 lines
5.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import '../widgets/custom_button.dart';
import '../widgets/custom_text_field.dart';
import '../utils/session_manager.dart';
import '../utils/api_config.dart';
import '../widgets/responsive_layout.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final usernameController = TextEditingController();
final passwordController = TextEditingController();
bool isLoading = false;
Future<void> loginUser() async {
setState(() => isLoading = true);
// Mengambil baseUrl dari pengaturan sentral di utils/api_config.dart
final url = Uri.parse("${ApiConfig.baseUrl}/login.php");
try {
final response = await http.post(url, body: {
'username': usernameController.text,
'password': passwordController.text,
});
final data = jsonDecode(response.body);
if (!mounted) return;
if (data['status'] == 'success') {
// Simpan Nama, Username, dan Photo ke SessionManager
SessionManager.saveSession(
int.parse(data['user']['id_users'].toString()),
data['user']['nama'],
data['user']['username'],
data['user']['photo_url']
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Login Berhasil!')),
);
Navigator.pushReplacementNamed(context, '/home');
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(data['message'])),
);
}
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Gagal terhubung ke server!')),
);
} finally {
if (mounted) setState(() => isLoading = false);
}
}
@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
return ResponsiveLayout(
child: Scaffold(
backgroundColor: const Color(0xFF3949AB),
body: SingleChildScrollView(
child: Column(
children: [
Container(
height: 260,
width: double.infinity,
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF3949AB), Color(0xFF00BCD4)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: SafeArea(
bottom: false,
child: Center(
child: Image.asset(
'assets/images/cyclist.png',
height: 140,
fit: BoxFit.contain,
),
),
),
),
Transform.translate(
offset: const Offset(0, -40),
child: Container(
constraints: BoxConstraints(
minHeight: screenHeight - 220,
),
width: double.infinity,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(40),
topRight: Radius.circular(40),
),
),
padding: const EdgeInsets.symmetric(horizontal: 32.0, vertical: 40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'Hello!',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 26,
fontWeight: FontWeight.w800,
color: Color(0xFF3949AB),
),
),
const SizedBox(height: 32),
CustomTextField(
hintText: 'Username',
controller: usernameController,
prefixIcon: Icons.person_outline,
),
const SizedBox(height: 16),
CustomTextField(
hintText: 'Password',
obscureText: true,
controller: passwordController,
prefixIcon: Icons.lock_outline,
),
const SizedBox(height: 16),
const SizedBox(height: 24),
isLoading
? const Center(child: CircularProgressIndicator())
: CustomButton(
text: 'Log In',
onPressed: () {
if (usernameController.text.isNotEmpty && passwordController.text.isNotEmpty) {
loginUser();
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Isi semua kolom!')),
);
}
},
),
const SizedBox(height: 24),
],
),
),
),
],
),
),
),
);
}
}