MIF_E31221281/TA-mobile/lib/screen/proses/confirmReserv_page.dart

486 lines
23 KiB
Dart

import 'package:flutter/material.dart';
import 'package:salon_app/components/button.dart';
import 'package:salon_app/model/karyawan_model.dart';
import 'package:salon_app/model/pelanggan_model.dart';
import 'package:salon_app/screen/proses/selectDate_page.dart';
import 'package:salon_app/screen/proses/uploadPayment_page.dart';
import 'package:salon_app/services/karyawan_service.dart';
import 'package:salon_app/services/layanan_service.dart';
import 'package:salon_app/services/pelanggan_service.dart';
import 'package:salon_app/services/reservation_service.dart';
import 'package:salon_app/utils/config.dart';
import 'package:form_validation/form_validation.dart';
import 'package:flutter/services.dart';
class ConfirmReservPage extends StatefulWidget {
final DateTime selectedDate;
final String selectedWaktuAwal;
final String selectedWaktuAkhir;
final String selectedKaryawanId;
final String selectedLayananId;
const ConfirmReservPage({
super.key,
required this.selectedDate,
required this.selectedWaktuAwal,
required this.selectedWaktuAkhir,
required this.selectedKaryawanId,
required this.selectedLayananId,
});
@override
State<ConfirmReservPage> createState() => _ConfirmReservPageState();
}
class _ConfirmReservPageState extends State<ConfirmReservPage> {
final _formKey = GlobalKey<FormState>();
KaryawanModel? karyawan;
PelangganModel? pelanggan;
Map<String, dynamic>? layanan;
ReservationService reservationService = ReservationService();
LayananService layananService = LayananService();
KaryawanService karyawanService = KaryawanService();
PelangganService pelangganService = PelangganService();
final TextEditingController _namaPemesanController = TextEditingController();
final TextEditingController _poinDigunakanController =
TextEditingController();
int totalPoin = 0; // Poin yang dimiliki pelanggan
int hargaLayanan = 0; // Harga layanan
int poinDigunakan = 0; // Poin yang akan digunakan
// Variabel untuk menyimpan status switch
bool _isPelangganSelected = false;
bool isLoading = true;
bool isSubmitting = false;
// Fungsi untuk mengambil data karyawan, layanan, dan pelanggan berdasarkan ID
Future<void> getData() async {
try {
karyawan =
await karyawanService.getDataKaryawanId(widget.selectedKaryawanId);
layanan = await layananService.getDataLayananId(widget.selectedLayananId);
pelanggan = await pelangganService.getDataPelangganId();
if (layanan != null) {
hargaLayanan = layanan!['harga'] as int;
}
if (pelanggan != null) {
totalPoin = pelanggan!.poin ?? 0;
}
} finally {
setState(() {
isLoading = false;
});
}
}
@override
void initState() {
super.initState();
getData(); // Ambil data saat widget pertama kali di-load
}
@override
void dispose() {
_namaPemesanController.dispose();
_poinDigunakanController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? const Center(child: CircularProgressIndicator())
: SafeArea(
// Wrapping the body in SafeArea
child: SingleChildScrollView(
// Making the body scrollable
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Align(
alignment: Alignment.topRight,
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.blueAccent,
backgroundColor: Colors.white,
side: const BorderSide(color: Colors.blueAccent),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100),
),
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 8),
),
child: const Text(
'Kembali',
style: TextStyle(fontSize: 16),
),
),
),
const SizedBox(height: 20),
Card(
margin: const EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 4,
shadowColor: Colors.black26,
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Informasi Reservasi',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text(
'Tanggal Reservasi: ${widget.selectedDate.toLocal().toString().split(' ')[0]}',
style: const TextStyle(fontSize: 16),
),
Text(
'Waktu Reservasi: ${widget.selectedWaktuAwal} - ${widget.selectedWaktuAkhir}',
style: const TextStyle(fontSize: 16),
),
if (karyawan != null)
Text(
'Hair Stylist: ${karyawan!.nama}',
style: const TextStyle(fontSize: 16),
),
if (layanan != null) ...[
Text(
'Layanan: ${layanan!['nama']}',
style: const TextStyle(fontSize: 16),
),
Text(
'Harga: ${Config().formatNumber(layanan!['harga'])}',
style: const TextStyle(fontSize: 16),
),
Text(
'Poin didapatkan: ${layanan!['poin']}',
style: const TextStyle(fontSize: 16),
),
],
])),
)
],
),
),
const SizedBox(height: 10),
Card(
margin: const EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 4,
shadowColor: Colors.black26,
child: Row(children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
const Text(
'Detail Pemesan',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text(
'Nama: ${pelanggan?.nama ?? '-'}',
style: const TextStyle(fontSize: 16),
),
Text(
'Email: ${pelanggan?.email ?? '-'}',
style: const TextStyle(fontSize: 16),
),
Text(
'No telp: ${pelanggan?.no_telp ?? '-'}',
style: const TextStyle(fontSize: 16),
),
// Menampilkan Switch untuk memilih pelanggan
if (pelanggan != null) ...[
Row(
children: [
const Expanded(
child: Text(
'Tambahkan sebagai pelanggan:',
style:
TextStyle(fontSize: 16),
),
),
Transform.scale(
scale:
0.7, // Sesuaikan dengan ukuran yang diinginkan
child: Switch(
value: _isPelangganSelected,
onChanged: (bool value) {
setState(() {
_isPelangganSelected =
value;
if (_isPelangganSelected) {
// Jika switch dinyalakan, isi nama pemesan dengan nama pelanggan
_namaPemesanController
.text =
pelanggan!.nama;
} else {
// Jika switch dimatikan, biarkan nama pemesan kosong
_namaPemesanController
.clear();
}
});
},
),
),
],
)
],
])))
])),
const SizedBox(height: 10),
Card(
margin: const EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 4,
shadowColor: Colors.black26,
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Detail Pelanggan',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
// Input Nama Pemesan yang otomatis terisi jika switch diaktifkan
const Text(
'Nama Pelanggan:',
style: TextStyle(fontSize: 16),
),
const SizedBox(height: 10),
TextFormField(
controller: _namaPemesanController,
inputFormatters: [
FilteringTextInputFormatter.deny(
RegExp(r'[^a-zA-Z\s]')),
],
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Masukkan nama Anda',
),
validator: (value) {
final validator = Validator(
validators: [
const RequiredValidator(),
],
);
return validator.validate(
label: 'Nama Pelanggan',
value: value,
);
},
),
const SizedBox(height: 20),
const Text(
'Poin dimiliki:',
style: TextStyle(fontSize: 16),
),
Text(
totalPoin.toString(),
style: const TextStyle(fontSize: 16),
),
const SizedBox(height: 20),
// Input poin untuk digunakan
const Text(
'Gunakan Poin:',
style: TextStyle(fontSize: 16),
),
const SizedBox(height: 10),
TextField(
controller: _poinDigunakanController,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
decoration: InputDecoration(
border: const OutlineInputBorder(),
hintText: 'Masukkan jumlah poin',
suffixText: 'Max: $totalPoin',
),
onChanged: (value) {
setState(() {
poinDigunakan =
int.tryParse(value) ?? 0;
if (poinDigunakan > totalPoin) {
poinDigunakan = totalPoin;
_poinDigunakanController.text =
totalPoin.toString();
}
});
},
),
],
),
),
),
),
],
),
),
const SizedBox(height: 20),
Button(
width: double.infinity,
title: isSubmitting ? 'Loading...' : 'Reservasi',
disable: isSubmitting,
onPressed: () async {
if (_formKey.currentState!.validate()) {
setState(() {
isSubmitting = true;
});
final int sisaHarga = hargaLayanan - poinDigunakan;
// final int sisaPoin =
// (totalPoin - poinDigunakan + layanan!['poin'])
// .toInt();
final int sisaPoin =
(totalPoin - poinDigunakan).toInt();
final result = await reservationService.postReservasi(
_namaPemesanController.text,
widget.selectedDate,
widget.selectedWaktuAwal,
sisaHarga.toString(),
layanan!['poin'].toString(),
poinDigunakan.toString(),
sisaPoin.toString(),
widget.selectedLayananId,
widget.selectedKaryawanId,
);
setState(() {
isSubmitting = false;
});
if (result['success'] == true) {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Reservasi berhasil!'),
// backgroundColor: Colors.green,
// ),
// );
// Navigator.of(context).popAndPushNamed('/ticket',
// arguments: [
// result['reservationId'].toString()
// ]);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UploadPaymentPage(
reservationId: result['reservationId'].toString(),
),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
result['message'] ?? 'Reservasi gagal!'),
backgroundColor: Colors.red,
),
);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text("Gagal"),
content: Text(result['message'] ??
"Reservasi gagal, coba lagi."),
actions: [
// Tombol Batal
TextButton(
onPressed: () {
Navigator.of(context)
.pop(); // Tutup pop-up tanpa navigasi
},
child: const Text("Batal"),
),
// Tombol Reservasi Ulang
TextButton(
onPressed: () {
Navigator.of(context)
.pop(); // Tutup pop-up
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
SelectdatePage(
idLayanan:
widget.selectedLayananId,
),
),
); // Arahkan ke halaman lain
},
child: const Text("Reservasi Ulang"),
),
],
);
},
);
}
}
},
),
],
),
),
),
);
}
}