Commit 44048e79 authored by Nurrofimutaqin's avatar Nurrofimutaqin

menambahkan hal yang kurang dalam fitur-fitur

parent bef5cd9e
......@@ -10,11 +10,11 @@ class Peminjaman {
factory Peminjaman.fromJson(Map<String, dynamic> json) {
return Peminjaman(
id: json['id'],
tanggal_pinjam: json['tanggal_pinjam'],
tanggal_kembali: json['tanggal_kembali'],
tanggal_pinjam: json['tanggal_pinjam'].toString(),
tanggal_kembali: json['tanggal_kembali'].toString(),
status: json['status'],
member_nama: json['member_nama'],
buku_judul: json['buku_judul'],
member_nama: json['member_nama'].toString(),
buku_judul: json['buku_judul'].toString(),
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:perpustakaan/models/book.dart';
import 'package:perpustakaan/providers/api_loans.dart';
import 'package:shared_preferences/shared_preferences.dart';
class BookDetailScreen extends StatelessWidget {
late final Book book;
final TextEditingController tanggal_kembalicontroller= TextEditingController();
// final TextEditingController tanggal_kembalicontroller= TextEditingController();
BookDetailScreen({required this.book});
// Declare a field that holds the Todo.
// late final Book bookId;
// Future<void> pinjam(BuildContext context) async {
// try {
// await peminjaman.Bookloans(
// tanggal_kembali: tanggal_kembali.text, id: book.id,
// );
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Change data successfully'),
// backgroundColor: Colors.green,
// ),
// );
// } catch (e) {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Failed to change user data. Please try again.'),
// backgroundColor: Colors.red,
// ),
// );
// print('Error changing user data: $e');
// }
// }
Future<void> bookloan(BuildContext context) async {
final String apiUrl = 'http://10.0.2.2:8000/api/member/book-loan-by-buku/${book.id}';
......@@ -48,12 +21,23 @@ class BookDetailScreen extends StatelessWidget {
final Map<String, String> token = {
'Authorization': 'Bearer $accessToken',
};
// Mengambil data dari kontroler teks
final String tanggal_kembali = tanggal_kembalicontroller.text;
// // Mengambil data dari kontroler teks
// final String tanggal_kembali = tanggal_kembalicontroller.text;
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime.now(),
lastDate: DateTime(2101),
);
// Jika pengguna memilih tanggal, kirim permintaan pinjam buku
if (pickedDate != null) {
// Konversi tanggal ke format "YYYY-MM-DD"
String formattedDate =
"${pickedDate.year}-${pickedDate.month.toString().padLeft(2, '0')}-${pickedDate.day.toString().padLeft(2, '0')}";
// Membuat payload data
final Map<String, String> data = {
'tanggal_kembali': tanggal_kembali,
'tanggal_kembali': formattedDate,
};
// Mengirim permintaan POST ke server
......@@ -84,6 +68,7 @@ class BookDetailScreen extends StatelessWidget {
print('Terjadi kesalahan: ${response.statusCode}');
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
......@@ -109,12 +94,12 @@ class BookDetailScreen extends StatelessWidget {
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: tanggal_kembalicontroller,
decoration: InputDecoration(
labelText: 'Tanggal Kembali',
border: OutlineInputBorder()),
),
// TextField(
// controller: tanggal_kembalicontroller,
// decoration: InputDecoration(
// labelText: 'Tanggal Kembali',
// border: OutlineInputBorder()),
// ),
SizedBox(height: 20),
ElevatedButton(
onPressed: ()=> bookloan(context),
......
......@@ -31,7 +31,13 @@ class BookLoans extends StatelessWidget {
child: ListTile(
tileColor: Colors.grey.withOpacity(0.1),
title: Text( peminjaman['buku_judul']),
subtitle: Text('Tanggal pinjam : ${peminjaman["tanggal_pinjam"]} || Due Date: ${peminjaman["tanggal_kembali"]}'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Tanggal pinjam : ${peminjaman["tanggal_pinjam"]}'),
Text('Due Date: ${peminjaman["tanggal_kembali"]}')
],
),
trailing: Text(status),
),
);
......
......@@ -32,7 +32,13 @@ class BookLoansAll extends StatelessWidget {
child: ListTile(
tileColor: Colors.grey.withOpacity(0.1),
title: Text( peminjaman['buku_judul']),
subtitle: Text('Tanggal pinjam : ${peminjaman["tanggal_pinjam"]} || Due Date: ${peminjaman["tanggal_kembali"]}'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Tanggal pinjam : ${peminjaman["tanggal_pinjam"]}'),
Text('Due Date: ${peminjaman["tanggal_kembali"]}')
],
),
trailing: Text(status),
onTap: () async {
var peminjamanId = peminjaman['id'];
......
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
// import 'package:intl/intl.dart';
import 'package:perpustakaan/pages/detail_peminjaman.dart';
import 'package:perpustakaan/providers/api_loans.dart';
......@@ -34,8 +34,13 @@ class BookLoansOverdue extends StatelessWidget {
child: ListTile(
tileColor: Colors.grey.withOpacity(0.1),
title: Text(peminjaman['buku_judul']),
subtitle: Text(
'Tanggal pinjam : ${peminjaman["tanggal_pinjam"]} || Due Date: ${peminjaman["tanggal_kembali"]}'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Tanggal pinjam : ${peminjaman["tanggal_pinjam"]}'),
Text('Due Date: ${peminjaman["tanggal_kembali"]}')
],
),
trailing: Text(status),
onTap: () async {
var peminjamanId = peminjaman['id'];
......
......@@ -29,6 +29,7 @@ class _ChangeDataState extends State<ChangeData> {
emailController = TextEditingController(text: widget.user.email);
usernameController = TextEditingController(text: widget.user.username);
}
Future<void> changedatauser(BuildContext context) async {
final String apiUrl = 'http://10.0.2.2:8000/api/change-data/member/';
......@@ -63,6 +64,10 @@ class _ChangeDataState extends State<ChangeData> {
// Memeriksa status response
if (response.statusCode == 200) {
// Data berhasil ditambahkan
setState(() {
UserApi.userDetail();
});
print('Data berhasil ditambahkan');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
......@@ -118,14 +123,8 @@ class _ChangeDataState extends State<ChangeData> {
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
setState(() {
ApiUser apiuser = ApiUser();
apiuser.getdatauser();
changedatauser(context);
});
Navigator.pop(context);
} ,
},
child: Text('Change Data'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey,
......@@ -137,5 +136,3 @@ class _ChangeDataState extends State<ChangeData> {
);
}
}
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:perpustakaan/models/peminjaman.dart';
import 'package:shared_preferences/shared_preferences.dart';
class DetailPeminjaman extends StatelessWidget {
class DetailPeminjaman extends StatefulWidget {
late final Peminjaman detail;
DetailPeminjaman({required this.detail});
@override
State<DetailPeminjaman> createState() => _DetailPeminjamanState();
}
class _DetailPeminjamanState extends State<DetailPeminjaman> {
final TextEditingController tglKembalicontroller = TextEditingController();
bool ischecked = false;
Future<void> Returned(BuildContext context) async {
final String apiUrl = 'http://10.0.2.2:8000/api/book-loans/${widget.detail.id}/';
// Mengambil token akses dari SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
final String accessToken = prefs.getString('access_token') ?? '';
// Membuat header dengan menyertakan token akses
final Map<String, String> token = {
'Authorization': 'Bearer $accessToken',
};
// Mengambil data dari kontroler teks
final String tanggal_kembali = tglKembalicontroller.text;
final String status = ischecked.toString();
final Map<String, dynamic> data = {
'status' : status,
'tanggal_kembali': tanggal_kembali,
};
// Mengirim permintaan POST ke server
final http.Response response = await http.put(
Uri.parse(apiUrl),
headers: token,
body: data,
);
// Memeriksa status response
if (response.statusCode == 200) {
// Data berhasil ditambahkan
print('Data berhasil ditambahkan');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Returned successfully'),
backgroundColor: Colors.green,
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Returned failed'),
backgroundColor: Colors.red,
),
);
// Terjadi kesalahan
print('Terjadi kesalahan: ${response.statusCode}');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
......@@ -17,8 +78,7 @@ class DetailPeminjaman extends StatelessWidget {
height: 400,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.pink.withOpacity(0.3)
),
color: Colors.pink.withOpacity(0.3)),
margin: EdgeInsets.all(10),
child: Column(
children: [
......@@ -26,37 +86,71 @@ class DetailPeminjaman extends StatelessWidget {
children: [
Container(
padding: EdgeInsets.all(10),
child: Text('Nama Peminjam:')
),
child: Text('Nama Peminjam:')),
Container(
padding: EdgeInsets.all(10),
child: Text(detail.member_nama)
)
child: Text(widget.detail.member_nama))
],
),
Row(
children: [
Container(
padding: EdgeInsets.all(10),
child: Text('Judul Buku:')
),
child: Text('Judul Buku:')),
Container(
padding: EdgeInsets.all(10),
child: Text(detail.buku_judul)
)
child: Text(widget.detail.buku_judul))
],
),
Row(
children: [
Container(
padding: EdgeInsets.all(10),
child: Text('Tanggal Pinjam')
),
child: Text('Tanggal Pinjam')),
Container(
padding: EdgeInsets.all(10),
child: Text('peminjaman.tanggal_pinjam')
)
child: Text(widget.detail.tanggal_kembali))
],
),
GestureDetector(
onTap: () {
setState(() {
ischecked = !ischecked; // Toggle the ischecked state
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Status'),
Checkbox(
value: ischecked,
onChanged: (value) {
setState(() {
ischecked = value ?? false;
print(ischecked); // Update ischecked based on value
});
},
),
],
),
),
Container(
padding: EdgeInsets.all(10),
child: TextField(
decoration: InputDecoration(
labelText: 'Tanggal Pengembalian',
border: OutlineInputBorder()),
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: (){
Returned(context);
},
child: Text('Pengembalian'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey,
foregroundColor: Colors.purpleAccent),
),
],
)),
......
......@@ -4,7 +4,7 @@ import 'package:perpustakaan/pages/book_loans_near_overdue.dart';
import 'package:perpustakaan/pages/book_loans_overdue.dart';
import 'package:perpustakaan/pages/change-data.dart';
import 'package:perpustakaan/pages/change-password.dart';
import 'package:perpustakaan/pages/detail_peminjaman.dart';
// import 'package:perpustakaan/pages/detail_peminjaman.dart';
import 'package:perpustakaan/pages/search_book.dart';
import 'package:perpustakaan/providers/api_authenticated.dart';
import 'package:perpustakaan/providers/api_category.dart';
......@@ -21,15 +21,16 @@ class HomeScreen extends StatefulWidget {
class _HomeScreenState extends State<HomeScreen> {
late String _role = '';
ApiUser UserApi = ApiUser();
ApiBook BookApi = ApiBook();
ApiCategory CategoryApi = ApiCategory();
@override
void initState() {
super.initState();
_loadUserData();
}
ApiUser UserApi = ApiUser();
ApiBook BookApi = ApiBook();
ApiCategory CategoryApi = ApiCategory();
Future<void> _loadUserData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
......@@ -174,7 +175,7 @@ class _HomeScreenState extends State<HomeScreen> {
? Column(
children: [
ListTile(
leading: Icon(Icons.info),
leading: Icon(Icons.calendar_month_rounded),
title: Text("Book Loans Near Overdue"),
onTap: () {
Navigator.push(
......@@ -185,7 +186,7 @@ class _HomeScreenState extends State<HomeScreen> {
},
),
ListTile(
leading: Icon(Icons.info),
leading: Icon(Icons.calendar_view_month),
title: Text("Book Loans Overdue"),
onTap: () {
Navigator.push(
......@@ -195,6 +196,17 @@ class _HomeScreenState extends State<HomeScreen> {
);
},
),
ListTile(
leading: Icon(Icons.info),
title: Text("Change Password"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChangePassword()),
);
},
),
ListTile(
leading: Icon(Icons.logout),
title: Text("Logout"),
......@@ -213,4 +225,3 @@ class _HomeScreenState extends State<HomeScreen> {
);
}
}
......@@ -4,9 +4,15 @@ import 'package:perpustakaan/pages/register.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class LoginScreen extends StatelessWidget {
class LoginScreen extends StatefulWidget {
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final TextEditingController usernameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
bool _obscureText = true;
Future<void> loginUser(BuildContext context) async {
final String apiUrl = 'http://10.0.2.2:8000/api/login/';
......@@ -34,7 +40,8 @@ class LoginScreen extends StatelessWidget {
final String token = responseData['access'];
final String role = responseData['user']['role'];
print('Token: $token');print('Token: $role');
print('Token: $token');
print('Token: $role');
// Simpan token ke SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('access_token', token);
......@@ -59,7 +66,7 @@ class LoginScreen extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login'),
title: Center(child: Text('LOGIN')),
),
body: Center(
child: Column(
......@@ -71,8 +78,7 @@ class LoginScreen extends StatelessWidget {
width: 350,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.grey,
),
color: Colors.pink.withOpacity(0.5)),
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
......@@ -83,27 +89,27 @@ class LoginScreen extends StatelessWidget {
controller: usernameController,
decoration: InputDecoration(
labelText: 'Username',
labelStyle: TextStyle(
color: Colors.pink,
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.pink,
)),
),
labelStyle: TextStyle(color: Colors.white),
border: OutlineInputBorder()),
),
SizedBox(height: 20),
TextField(
obscureText: _obscureText,
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
labelStyle: TextStyle(color: Colors.white),
labelText: 'Password',
labelStyle: TextStyle(
color: Colors.pink,
border: OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(_obscureText
? Icons.visibility
: Icons.visibility_off),
onPressed: () {
setState(() {
_obscureText = !_obscureText;
});
},
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.pink,
)),
),
),
SizedBox(height: 20),
......
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class RegisterPage extends StatelessWidget {
class RegisterPage extends StatefulWidget {
@override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
final TextEditingController firstNameController = TextEditingController();
final TextEditingController lastNameController = TextEditingController();
final TextEditingController emailController = TextEditingController();
final TextEditingController usernameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
bool _obscureText = true;
Future<void> RegisterUser(BuildContext context) async {
final String apiUrl = 'http://10.0.2.2:8000/api/registration/';
// Mengambil data dari kontroler teks
final String first_name = firstNameController.text;
final String last_name = lastNameController.text;
final String email = emailController.text;
final String username = usernameController.text;
final String password = passwordController.text;
// Membuat payload data untuk permintaan login
final Map<String, String> data = {
'first_name': first_name,
'last_name': last_name,
'email': email,
'username': username,
'password': password,
};
......@@ -28,7 +47,7 @@ class RegisterPage extends StatelessWidget {
if (response.statusCode == 201) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Login Gagal. Periksa kembali username dan password.'),
content: Text('Registration Successfuly'),
backgroundColor: Colors.green,
duration: Duration(seconds: 3),
),
......@@ -40,7 +59,7 @@ class RegisterPage extends StatelessWidget {
// Menampilkan SnackBar jika login gagal
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('regis Gagal. Periksa kembali username dan password.'),
content: Text('regis Failed. Periksa kembali username dan password.'),
backgroundColor: Colors.red,
),
);
......@@ -62,11 +81,11 @@ class RegisterPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 500,
height: 600,
width: 350,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.grey,
color: Colors.pink.withOpacity(0.5),
),
child: Padding(
padding: EdgeInsets.all(16.0),
......@@ -74,6 +93,26 @@ class RegisterPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TextField(
controller: firstNameController,
decoration: InputDecoration(
labelText: 'Fisrt Name',
border: OutlineInputBorder()),
),
SizedBox(height: 20),
TextField(
controller: lastNameController,
decoration: InputDecoration(
labelText: 'Last Name',
border: OutlineInputBorder()),
),
SizedBox(height: 20),
TextField(
controller: emailController,
decoration: InputDecoration(
labelText: 'Email', border: OutlineInputBorder()),
),
SizedBox(height: 20),
TextField(
controller: usernameController,
decoration: InputDecoration(
......@@ -83,10 +122,21 @@ class RegisterPage extends StatelessWidget {
SizedBox(height: 20),
TextField(
controller: passwordController,
obscureText: true,
obscureText: _obscureText,
decoration: InputDecoration(
labelText: 'Password',
border: OutlineInputBorder()),
border: OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(_obscureText
? Icons.visibility
: Icons.visibility_off),
onPressed: () {
setState(() {
_obscureText = !_obscureText;
});
},
),
),
),
SizedBox(height: 20),
ElevatedButton(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment