diff --git a/assets/img/logo_siopas.png b/assets/img/logo_siopas.png new file mode 100644 index 0000000..aae243d Binary files /dev/null and b/assets/img/logo_siopas.png differ diff --git a/assets/logo_login.png b/assets/logo_login.png deleted file mode 100644 index 33653f4..0000000 Binary files a/assets/logo_login.png and /dev/null differ diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index fcf91e6..2baa497 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -413,7 +413,7 @@ class _HomePageState extends State { textAlign: TextAlign.center, ), Text( - 'User Fullname', + '${user.fullname}', style: TextStyle( fontSize: 10, ), diff --git a/lib/pages/home/peminjaman_stock_page.dart b/lib/pages/home/peminjaman_stock_page.dart index 3485854..9a0fe30 100644 --- a/lib/pages/home/peminjaman_stock_page.dart +++ b/lib/pages/home/peminjaman_stock_page.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:data_table_2/data_table_2.dart'; +import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:siopas/models/asset_status_model.dart'; @@ -125,6 +126,7 @@ class AssetStatusPageState extends State { }, columns: const [ DataColumn(label: Text('No')), + DataColumn(label: Text('')), DataColumn(label: Text('Kode Peti')), DataColumn(label: Text('Nama Customer')), DataColumn(label: Text('Tgl Peminjaman')), @@ -190,14 +192,6 @@ class _DataSource extends DataTableSource { (index + 1).toString(), ), ), - DataCell( - Text( - // item.asset.exit_at.toString(), - item.peti!.customer!.code_customer.toString() + - '-' + - item.peti!.tipe_peti!.type.toString(), - ), - ), DataCell( GestureDetector( onTap: () { @@ -214,15 +208,32 @@ class _DataSource extends DataTableSource { print('asset id: ${item.id}'); } }, - child: Text( - item.peti!.customer!.name.toString(), - ), + child: Icon(Icons.article, + size: 40, + color: Colors.indigo[700]), // Ganti ikon sesuai kebutuhan + ), + ), + DataCell( + Text( + // item.asset.exit_at.toString(), + item.peti!.customer!.code_customer.toString() + + '-' + + item.peti!.tipe_peti!.type.toString(), + ), + ), + DataCell( + Text( + item.peti!.customer!.name.toString(), ), ), DataCell( Text( // item.asset.exit_at.toString(), - item.exit_at.toString(), + // item.exit_at.toString(), + // DateFormat('dd-MM-yyyy').format(item.est_pengembalian!) + item.est_pengembalian != null + ? DateFormat('dd-MM-yyyy').format(item.est_pengembalian!) + : '-', ), ), DataCell( diff --git a/lib/pages/home/setting_page.dart b/lib/pages/home/setting_page.dart index 91d1adb..6d03038 100644 --- a/lib/pages/home/setting_page.dart +++ b/lib/pages/home/setting_page.dart @@ -176,20 +176,7 @@ class SettingPageState extends State { ), _SingleSection( title: "General", - children: [ - _CustomListTile( - title: "Dark Mode", - icon: Icons.dark_mode_outlined, - trailing: Switch( - value: _isDark, - onChanged: (value) { - setState(() { - _isDark = value; - }); - }, - ), - ), - ], + children: [], ), const Divider(), _SingleSection( diff --git a/lib/pages/peminjaman_barang/show.dart b/lib/pages/peminjaman_barang/show.dart index 13c3bc8..5804526 100644 --- a/lib/pages/peminjaman_barang/show.dart +++ b/lib/pages/peminjaman_barang/show.dart @@ -35,7 +35,7 @@ class _DetailPeminjamanBarangPageState Future _fetchAssetStatusData() async { try { final response = await http.get( - Uri.parse('$baseUrl/asset-status/show/${widget.assetId}'), + Uri.parse('$baseUrl/asset-status/peminjaman/show/${widget.assetId}'), headers: { 'Content-Type': 'application/json', }, @@ -112,7 +112,7 @@ class _DetailPeminjamanBarangPageState SizedBox(height: 10), if (assetStatusData != null) ...[ _buildDetailItem( - 'Peti Nama', + 'Kode Peti', assetStatusData!['peti']['customer']['code_customer'] + ' - ' + assetStatusData!['peti']['tipe_peti']['type'], diff --git a/lib/pages/pengembalian_barang/create.dart b/lib/pages/pengembalian_barang/create.dart index 6bfbf58..d841fc6 100644 --- a/lib/pages/pengembalian_barang/create.dart +++ b/lib/pages/pengembalian_barang/create.dart @@ -63,7 +63,8 @@ class _CreatePengembalianBarangPageState _isLoading = true; }); - final response = await http.get(Uri.parse('$baseUrl/asset-status')); + final response = + await http.get(Uri.parse('$baseUrl/asset-status/pengembalian')); if (mounted) { // Periksa apakah widget masih "mounted" diff --git a/lib/pages/pengembalian_barang/pengembalian-index.dart b/lib/pages/pengembalian_barang/pengembalian-index.dart index e5af7ad..5f72e62 100644 --- a/lib/pages/pengembalian_barang/pengembalian-index.dart +++ b/lib/pages/pengembalian_barang/pengembalian-index.dart @@ -7,6 +7,7 @@ import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:siopas/models/asset_status_model.dart'; +import 'package:siopas/pages/pengembalian_barang/show.dart'; import 'package:siopas/providers/asset_status_provider.dart'; import 'package:http/http.dart' as http; @@ -126,6 +127,7 @@ class PengembalianBarangPageState extends State { }, columns: const [ DataColumn(label: Text('No')), + DataColumn(label: Text('')), DataColumn(label: Text('Kode Peti')), DataColumn(label: Text('Tgl Peminjaman')), DataColumn(label: Text('Estimasi Pengembalian')), @@ -196,14 +198,6 @@ class _DataSource extends DataTableSource { (index + 1).toString(), ), ), - DataCell( - Text( - // item.asset.exit_at.toString(), - item.peti!.customer!.code_customer.toString() + - '-' + - item.peti!.tipe_peti!.type.toString(), - ), - ), DataCell( GestureDetector( onTap: () { @@ -211,8 +205,8 @@ class _DataSource extends DataTableSource { Navigator.push( context, MaterialPageRoute( - builder: (context) => DetailPeminjamanBarangPage( - assetId: item.id!, + builder: (context) => DetailPengembalianBarangPage( + pengembalianId: item.id!, ), ), ); @@ -220,13 +214,28 @@ class _DataSource extends DataTableSource { print('asset id: ${item.id}'); } }, - child: Text( - item.exit_at != null - ? DateFormat('dd-MM-yyyy').format(item.exit_at!) - : '-', + child: Icon( + Icons.article_outlined, + size: 30, + color: Colors.indigo[700], ), ), ), + DataCell( + Text( + // item.asset.exit_at.toString(), + item.peti!.customer!.code_customer.toString() + + '-' + + item.peti!.tipe_peti!.type.toString(), + ), + ), + DataCell( + Text( + item.exit_at != null + ? DateFormat('dd-MM-yyyy').format(item.exit_at!) + : '-', + ), + ), DataCell( Text( // item.asset.exit_at.toString(), diff --git a/lib/pages/pengembalian_barang/show.dart b/lib/pages/pengembalian_barang/show.dart new file mode 100644 index 0000000..9cb0a46 --- /dev/null +++ b/lib/pages/pengembalian_barang/show.dart @@ -0,0 +1,206 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; +import 'package:siopas/connection/connection.dart'; + +class DetailPengembalianBarangPage extends StatefulWidget { + final int pengembalianId; + const DetailPengembalianBarangPage({Key? key, required this.pengembalianId}) + : super(key: key); + + @override + _DetailPengembalianBarangPageState createState() => + _DetailPengembalianBarangPageState(); +} + +class _DetailPengembalianBarangPageState + extends State { + Map? assetStatusData; + + String _formatDate(String date) { + try { + DateTime parsedDate = DateTime.parse(date); + String formattedDate = + DateFormat('EEEE, dd MMMM yyyy', 'id_ID').format(parsedDate); + return formattedDate; + } catch (e) { + // Handle the case where the date string is not valid + return 'Invalid date format'; + } + } + + @override + void initState() { + super.initState(); + _fetchAssetStatusDataPengembalian(); + } + + Future _fetchAssetStatusDataPengembalian() async { + try { + final response = await http.get( + Uri.parse( + '$baseUrl/asset-status/pengembalian/show/${widget.pengembalianId}'), + headers: { + 'Content-Type': 'application/json', + }, + ); + + if (response.statusCode == 200) { + setState(() { + assetStatusData = json.decode(response.body)['data']['asset_status']; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (e) { + print('Error fetching data: $e'); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.grey[200], + appBar: AppBar( + backgroundColor: Colors.indigo[700], + elevation: 0, + title: Text('Detail Pengembalian Barang', + style: TextStyle( + color: Colors.white, + fontSize: 16, + )), + leading: IconButton( + icon: Icon(Icons.arrow_back, color: Colors.white), + onPressed: () { + Navigator.pushNamed(context, '/pengembalian-barang'); + }, + ), + ), + body: Padding( + padding: EdgeInsets.all(16.0), + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15.0), + ), + elevation: 5, + child: Column( + children: [ + Card( + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.vertical(top: Radius.circular(15.0)), + ), + elevation: 0, + margin: EdgeInsets.all(0), + color: Colors.indigo[700], + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + children: [ + Icon(Icons.article, + size: 40, + color: Colors.white), // Ganti ikon sesuai kebutuhan + SizedBox(width: 10), + Text( + 'ID: ${widget.pengembalianId}', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ], + ), + ), + ), + SizedBox(height: 10), + if (assetStatusData != null) ...[ + _buildDetailItem( + 'Kode Peti', + assetStatusData!['peti']['customer']['code_customer'] + + ' - ' + + assetStatusData!['peti']['tipe_peti']['type'], + ), + Divider(thickness: 1), + _buildDetailItem( + 'Nama Customer', + assetStatusData!['peti']['customer']['name'] != null + ? assetStatusData!['peti']['customer']['name'] + .toString() + : '-'), + Divider(thickness: 1), + _buildDetailItem( + 'Tgl Peminjaman', + _formatDate(assetStatusData!['exit_at'] != null + ? assetStatusData!['exit_at'] + : '-')), + Divider(thickness: 1), + _buildDetailItem( + 'PJ Peminjaman', + assetStatusData!['exit_pic'] != null + ? assetStatusData!['exit_pic'].toString() + : '-'), + Divider(thickness: 1), + _buildDetailItem( + 'Asal WH Peminjaman', + assetStatusData!['warehouse']['name'] != null + ? assetStatusData!['warehouse']['name'].toString() + : '-'), + Divider(thickness: 1), + _buildDetailItem( + 'Tgl Pengembalian', + assetStatusData!['enter_at'] != null && + assetStatusData!['enter_at'] != '0000-00-00 00:00:00' + ? _formatDate(assetStatusData!['enter_at']) + : '-', + ), + Divider(thickness: 1), + _buildDetailItem( + 'PJ Pengembalian', + assetStatusData!['enter_pic'] != null + ? assetStatusData!['enter_pic'].toString() + : '-'), + Divider(thickness: 1), + _buildDetailItem( + 'Tujuan WH Pengembalian', + assetStatusData!['warehouse_enter'] != null + ? assetStatusData!['warehouse_enter']['name'].toString() + : '-'), + Divider(thickness: 1), + _buildDetailItem( + 'Kondisi Peti', + assetStatusData!['kondisi_peti'] != null + ? assetStatusData!['kondisi_peti'].toString() + : '-'), + Divider(thickness: 1), + _buildDetailItem( + 'Status', + assetStatusData!['warehouse_enter'] != null + ? assetStatusData!['warehouse_enter']['name'].toString() + : '-'), + ], + ], + ), + ), + ), + ); + } + + Widget _buildDetailItem(String label, String value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + label, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + ), + Text(value), + ], + ), + ); + } +} diff --git a/lib/pages/sign_in_page.dart b/lib/pages/sign_in_page.dart index 5fee0df..d08c708 100644 --- a/lib/pages/sign_in_page.dart +++ b/lib/pages/sign_in_page.dart @@ -18,212 +18,26 @@ class _SignInPageState extends State { TextEditingController passwordController = TextEditingController(text: ''); bool isLoading = false; bool _isPasswordVisible = false; - bool _rememberMe = false; @override Widget build(BuildContext context) { final bool isSmallScreen = MediaQuery.of(context).size.width < 600; - AuthProvider authProvider = Provider.of(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}'); - - // Periksa apakah pengguna memiliki roles - if (user.role_id == "1") { - print('Berhasil login HALAMAN ADMIN'); - Navigator.pushNamed(context, '/home'); - } else 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: Text( - 'Gagal Login', - textAlign: TextAlign.center, - ), - ), - ); - } - - // setState(() { - // isLoading = false; - // }); - } - - Widget header() { - return Container( - margin: EdgeInsets.only(top: 30), - child: Column( - children: [ - Image.asset( - 'assets/logo_login.png', - height: 100, // Sesuaikan tinggi gambar sesuai kebutuhan - ), - SizedBox(height: 10), - Text( - 'Login', - style: TextStyle( - fontSize: 24, - fontWeight: semiBold, - color: primaryTextColor, - ), - ), - SizedBox(height: 2), - Text( - 'Sign In to Continue', - style: TextStyle( - fontSize: 14, - fontWeight: regular, - color: Colors.black, - ), - ), - ], - ), - ); - } - - Widget emailInput() { - return Container( - margin: EdgeInsets.only(top: 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextFormField( - validator: (value) { - // add email validation - if (value == null || value.isEmpty) { - return 'Please enter some text'; - } - - bool emailValid = RegExp( - r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") - .hasMatch(value); - if (!emailValid) { - return 'Please enter a valid email'; - } - - return null; - }, - controller: emailController, - decoration: const InputDecoration( - labelText: 'Email', - hintText: 'Enter your email', - prefixIcon: Icon(Icons.email_outlined), - border: OutlineInputBorder(), - ), - ), - ], - ), - ); - } - - Widget passwordInput() { - return Container( - margin: EdgeInsets.only(top: 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextFormField( - validator: (value) { - if (value == null || value.isEmpty) { - return 'Please enter some text'; - } - - if (value.length < 6) { - return 'Password must be at least 6 characters'; - } - return null; - }, - obscureText: !_isPasswordVisible, - controller: passwordController, - decoration: InputDecoration( - labelText: 'Password', - hintText: 'Enter your password', - prefixIcon: const Icon(Icons.lock_outline_rounded), - border: const OutlineInputBorder(), - suffixIcon: IconButton( - icon: Icon(_isPasswordVisible - ? Icons.visibility_off - : Icons.visibility), - onPressed: () { - setState(() { - _isPasswordVisible = !_isPasswordVisible; - }); - }, - )), - ), - ], - ), - ); - } - - Widget signInButton() { - return Container( - height: 50, - width: double.infinity, - margin: EdgeInsets.only(top: 30), - child: 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( - 'Sign in', - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), - ), - ), - onPressed: () { - if (emailController.text.isEmpty || - passwordController.text.isEmpty) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - backgroundColor: alertColor, - content: Text( - 'Email dan Password tidak boleh kosong', - textAlign: TextAlign.center, - ), - ), - ); - } else { - handleSignIn(); - } - }), - ), - ); - } - return Scaffold( body: Center( child: isSmallScreen - ? Column( - mainAxisSize: MainAxisSize.min, - children: const [ - _Logo(), - _FormContent(), - ], + ? SingleChildScrollView( + reverse: true, + scrollDirection: Axis.vertical, // Tambahkan ini + child: Column( + mainAxisSize: MainAxisSize.min, + children: const [ + _Logo(), + _FormContent(), + ], + ), ) : Container( padding: const EdgeInsets.all(30.0), @@ -250,45 +64,25 @@ class _Logo extends StatelessWidget { return Column( mainAxisSize: MainAxisSize.min, children: [ - // FlutterLogo(size: isSmallScreen ? 100 : 200), Container( margin: EdgeInsets.only(top: 30), - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(10), // Mengatur sudut menjadi bulat - border: Border.all( - color: Colors.black, // Warna garis tepi - width: 2, // Lebar garis tepi - ), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 2, - blurRadius: 7, - offset: Offset(0, 3), // changes position of shadow - ), - ], - ), child: Image.asset( - 'assets/logo_login.png', - height: isSmallScreen ? 100 : 200, + '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: isSmallScreen - ? Theme.of(context).textTheme.headline5 - : Theme.of(context) - .textTheme - .headline4 - ?.copyWith(color: Colors.black), + style: TextStyle( + fontSize: isSmallScreen ? 18 : 22, + fontWeight: semiBold, + color: Colors.black, + ), ), ), - SizedBox(height: 2), ], ); } @@ -304,10 +98,11 @@ class _FormContent extends StatefulWidget { class __FormContentState extends State<_FormContent> { TextEditingController emailController = TextEditingController(text: ''); TextEditingController passwordController = TextEditingController(text: ''); + final GlobalKey _formKey = GlobalKey(); + bool isLoading = false; bool _isPasswordVisible = false; - bool _rememberMe = false; @override Widget build(BuildContext context) { @@ -328,12 +123,6 @@ class __FormContentState extends State<_FormContent> { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString('token', user.token!); // Pastikan user.token tidak null print('token dapat login: ${user.token}'); - - // Periksa apakah pengguna memiliki roles - // if (user.role_id == 1) { - // print('Berhasil login HALAMAN ADMIN'); - // Navigator.pushNamed(context, '/home'); - // } else if (user.role_id == 2) { print('Berhasil login HALAMAN USER'); Navigator.pushNamed(context, '/home'); @@ -344,12 +133,25 @@ class __FormContentState extends State<_FormContent> { ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: alertColor, - content: Text( - 'Gagal Login', - textAlign: TextAlign.center, + 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(() { @@ -359,112 +161,116 @@ class __FormContentState extends State<_FormContent> { return Container( constraints: const BoxConstraints(maxWidth: 300), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - TextFormField( - validator: (value) { - // add email validation - if (value == null || value.isEmpty) { - return 'Please enter some text'; - } + 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 'Please enter a valid email'; - } + 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: 'Enter your email', - prefixIcon: Icon(Icons.email_outlined), - border: OutlineInputBorder(), + 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 'Please enter some text'; - } + _gap(), + TextFormField( + validator: (value) { + if (value == null || value.isEmpty) { + return 'Silakan masukkan password anda'; + } - if (value.length < 6) { - return 'Password must be at least 6 characters'; - } - return null; - }, - obscureText: !_isPasswordVisible, - controller: passwordController, - decoration: InputDecoration( - labelText: 'Password', - hintText: 'Enter your password', - 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(), - // CheckboxListTile( - // value: _rememberMe, - // onChanged: (value) { - // if (value == null) return; - // setState(() { - // _rememberMe = value; - // }); - // }, - // title: const Text('Remember me'), - // controlAffinity: ListTileControlAffinity.leading, - // dense: true, - // contentPadding: const EdgeInsets.all(0), - // ), - _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 (emailController.text.isEmpty || - passwordController.text.isEmpty) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - backgroundColor: alertColor, - content: Text( - 'Email dan Password tidak boleh kosong', - textAlign: TextAlign.center, - ), - ), - ); - } else { - handleSignIn(); + 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(); + } + } + }, + ), + ), + ], + ), ), ); } diff --git a/lib/pages/splash_page.dart b/lib/pages/splash_page.dart index 2a4dc51..ba265a7 100644 --- a/lib/pages/splash_page.dart +++ b/lib/pages/splash_page.dart @@ -22,26 +22,6 @@ class _SplashPageState extends State { autoLogin(); } - // getInit() async { - // await Provider.of(context, listen: false).getSurvey(); - // Navigator.pushNamed(context, '/sign-in'); - // // await Provider.of(context, listen: false).getTransactions(); - // } - - // void getInit() async { - // try { - // final surveyProvider = - // Provider.of(context, listen: false); - // final categoryProvider = - // Provider.of(context, listen: false); - - // await surveyProvider.getSurvey(); - // await categoryProvider.getCategory(); - // } catch (e) { - // print('Error during getInit: $e'); - // } - // } - void autoLogin() async { try { SharedPreferences prefs = await SharedPreferences.getInstance(); @@ -70,34 +50,33 @@ class _SplashPageState extends State { } } - // @override - // void initState() { - // super.initState(); - // getInit(); - // } - - // void getInit() async { - // await Provider.of(context, listen: false).getSurvey(); - - // Timer(Duration(seconds: 2), () { - // Navigator.pushNamed(context, '/sign-in'); - // // Navigator.pushNamed(context, '/home'); - // }); - // } - @override Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor1, body: Center( - child: Container( - width: 130, - height: 150, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/logo_login.png'), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + width: 130, + height: 150, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/img/logo_siopas.png'), + ), + ), + ), + SizedBox( + height: + 16), // Jarak antara gambar dan CircularProgressIndicator + CircularProgressIndicator(), // Tambahkan ini + SizedBox(height: 16), // Jarak antara indicator dan teks + Text( + 'Memuat...', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), - ), + ], ), ), ); diff --git a/pubspec.yaml b/pubspec.yaml index 6d740b4..59747a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -72,7 +72,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - - assets/ + - assets/img/ # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see