Siopas Inventory PETI for ISTW Mobile
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

279 lines
9.0 KiB

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/theme.dart';
import '../models/user_model.dart';
import '../providers/auth_provider.dart';
import '../widget/loading_button.dart';
class SignInPage extends StatefulWidget {
@override
State<SignInPage> createState() => _SignInPageState();
}
class _SignInPageState extends State<SignInPage> {
TextEditingController emailController = TextEditingController(text: '');
TextEditingController passwordController = TextEditingController(text: '');
bool isLoading = false;
bool _isPasswordVisible = false;
@override
Widget build(BuildContext context) {
final bool isSmallScreen = MediaQuery.of(context).size.width < 600;
AuthProvider authProvider = Provider.of<AuthProvider>(context);
UserModel user = authProvider.user;
return Scaffold(
body: Center(
child: isSmallScreen
? SingleChildScrollView(
reverse: true,
scrollDirection: Axis.vertical, // Tambahkan ini
child: Column(
mainAxisSize: MainAxisSize.min,
children: const [
_Logo(),
_FormContent(),
],
),
)
: Container(
padding: const EdgeInsets.all(30.0),
constraints: const BoxConstraints(maxWidth: 800),
child: Row(
children: const [
Expanded(child: _Logo()),
Expanded(
child: Center(child: _FormContent()),
),
],
),
)));
}
}
class _Logo extends StatelessWidget {
const _Logo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final bool isSmallScreen = MediaQuery.of(context).size.width < 600;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: EdgeInsets.only(top: 30),
child: Image.asset(
'assets/img/logo_siopas.png',
height: isSmallScreen ? 135 : 200,
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"Welcome To Siopas!",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: isSmallScreen ? 18 : 22,
fontWeight: semiBold,
color: Colors.black,
),
),
),
],
);
}
}
class _FormContent extends StatefulWidget {
const _FormContent({Key? key}) : super(key: key);
@override
State<_FormContent> createState() => __FormContentState();
}
class __FormContentState extends State<_FormContent> {
TextEditingController emailController = TextEditingController(text: '');
TextEditingController passwordController = TextEditingController(text: '');
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
bool isLoading = false;
bool _isPasswordVisible = false;
@override
Widget build(BuildContext context) {
AuthProvider authProvider = Provider.of<AuthProvider>(context);
UserModel user = authProvider.user;
handleSignIn() async {
setState(() {
isLoading = true;
});
if (await authProvider.login(
email: emailController.text,
password: passwordController.text,
)) {
UserModel user = authProvider.user;
// Simpan token pengguna ke SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('token', user.token!); // Pastikan user.token tidak null
print('token dapat login: ${user.token}');
if (user.role_id == 2) {
print('Berhasil login HALAMAN USER');
Navigator.pushNamed(context, '/home');
} else {
print('Tidak ada informasi peran (roles) yang tersedia');
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: alertColor,
content: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.warning,
color: Colors.white,
),
SizedBox(width: 8), // Jarak antara ikon dan teks
Text(
'Gagal Login, Email dan Password anda salah',
textAlign: TextAlign.center,
),
],
),
),
);
Future.delayed(Duration(seconds: 3), () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
});
}
setState(() {
isLoading = false;
});
}
return Container(
constraints: const BoxConstraints(maxWidth: 300),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
validator: (value) {
// add email validation
if (value == null || value.isEmpty) {
return 'Silakan masukkan email anda';
}
bool emailValid = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(value);
if (!emailValid) {
return 'Tolong masukkan email yang benar';
}
return null;
},
controller: emailController,
decoration: const InputDecoration(
labelText: 'Email',
hintText: 'Masukkan email Anda',
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
),
),
_gap(),
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Silakan masukkan password anda';
}
if (value.length < 6) {
return 'Kata sandi minimal harus 6 karakter';
}
return null;
},
obscureText: !_isPasswordVisible,
controller: passwordController,
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Masukkan kata sandi Anda',
prefixIcon: const Icon(Icons.lock_outline_rounded),
border: const OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(_isPasswordVisible
? Icons.visibility_off
: Icons.visibility),
onPressed: () {
setState(() {
_isPasswordVisible = !_isPasswordVisible;
});
},
)),
),
_gap(),
SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)),
),
child: const Padding(
padding: EdgeInsets.all(10.0),
child: Text(
'Login',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
onPressed: () {
if (_formKey.currentState!.validate()) {
if (emailController.text.isEmpty ||
passwordController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: alertColor,
content: Row(
children: [
Icon(
Icons.warning,
color: Colors.white,
),
SizedBox(width: 8), // Jarak antara ikon dan teks
Text(
'Email dan Password tidak boleh kosong',
textAlign: TextAlign.center,
),
],
),
),
);
Future.delayed(Duration(seconds: 2), () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
});
} else {
handleSignIn();
}
}
},
),
),
],
),
),
);
}
Widget _gap() => const SizedBox(height: 16);
}