MIF_E31231033/lib/screens/dashboard/admin/kelola_lokasi_screen.dart

190 lines
5.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import '../../../services/auth_service.dart';
class KelolaLokasiScreen extends StatefulWidget {
const KelolaLokasiScreen({super.key});
@override
State<KelolaLokasiScreen> createState() => _KelolaLokasiScreenState();
}
class _KelolaLokasiScreenState extends State<KelolaLokasiScreen> {
final String baseUrl = AuthService.baseUrl;
List<Map<String, dynamic>> lokasiList = [];
bool isLoading = false;
final TextEditingController namaController = TextEditingController();
@override
void initState() {
super.initState();
fetchLokasi();
}
Future<void> fetchLokasi() async {
try {
final response = await http.get(Uri.parse("$baseUrl/lokasi"));
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
setState(() {
lokasiList = List<Map<String, dynamic>>.from(data);
});
}
} catch (e) {
debugPrint("Error fetch lokasi: $e");
}
}
Future<void> tambahLokasi() async {
if (namaController.text.isEmpty) return;
setState(() => isLoading = true);
try {
final response = await http.post(
Uri.parse("$baseUrl/lokasi"),
headers: {"Content-Type": "application/json"},
body: jsonEncode({"nama_lokasi": namaController.text}),
);
if (response.statusCode == 201) {
Navigator.pop(context);
clearForm();
fetchLokasi();
}
} catch (e) {
debugPrint("Error tambah lokasi: $e");
}
setState(() => isLoading = false);
}
Future<void> updateLokasi(int id) async {
if (namaController.text.isEmpty) return;
setState(() => isLoading = true);
try {
final response = await http.put(
Uri.parse("$baseUrl/lokasi/$id"),
headers: {"Content-Type": "application/json"},
body: jsonEncode({"nama_lokasi": namaController.text}),
);
if (response.statusCode == 200) {
Navigator.pop(context);
clearForm();
fetchLokasi();
}
} catch (e) {
debugPrint("Error update lokasi: $e");
}
setState(() => isLoading = false);
}
Future<void> hapusLokasi(int id) async {
try {
await http.delete(Uri.parse("$baseUrl/lokasi/$id"));
fetchLokasi();
} catch (e) {
debugPrint("Error hapus lokasi: $e");
}
}
void clearForm() {
namaController.clear();
}
void showForm({Map<String, dynamic>? lokasi}) {
if (lokasi != null) {
namaController.text = lokasi['nama_lokasi'];
}
showDialog(
context: context,
builder:
(_) => AlertDialog(
title: Text(lokasi == null ? "Tambah Lokasi" : "Edit Lokasi"),
content: TextField(
controller: namaController,
decoration: const InputDecoration(
labelText: "Nama Lokasi",
border: OutlineInputBorder(),
),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
clearForm();
},
child: const Text("Batal"),
),
ElevatedButton(
onPressed:
isLoading
? null
: () {
if (lokasi == null) {
tambahLokasi();
} else {
updateLokasi(lokasi['id']);
}
},
child: Text(lokasi == null ? "Simpan" : "Update"),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Kelola Lokasi"),
backgroundColor: const Color(0xFF2F5BEA),
),
body:
isLoading
? const Center(child: CircularProgressIndicator())
: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: lokasiList.length,
itemBuilder: (context, index) {
final lokasi = lokasiList[index];
return Card(
child: ListTile(
title: Text(lokasi['nama_lokasi']),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.edit, color: Colors.orange),
onPressed: () => showForm(lokasi: lokasi),
),
IconButton(
icon: const Icon(Icons.delete, color: Colors.red),
onPressed: () => hapusLokasi(lokasi['id']),
),
],
),
),
);
},
),
floatingActionButton: FloatingActionButton(
backgroundColor: const Color(0xFF2F5BEA),
onPressed: () => showForm(),
child: const Icon(Icons.add),
),
);
}
}