added other
This commit is contained in:
@ -0,0 +1,229 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:panti_asuhan/app/themes/app_text.dart';
|
||||
import 'package:panti_asuhan/ui/widgets/my_textformfield.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import 'package:stacked_services/stacked_services.dart';
|
||||
import 'package:validatorless/validatorless.dart';
|
||||
|
||||
import '../../../../../app/themes/app_colors.dart';
|
||||
import './add_siswa_dialog_view_model.dart';
|
||||
|
||||
class DataSiswa {
|
||||
final String? nama;
|
||||
|
||||
DataSiswa({required this.nama, r});
|
||||
}
|
||||
|
||||
class AddSiswaDialogView extends StatelessWidget {
|
||||
final DialogRequest<DataSiswa> request;
|
||||
final Function(DialogResponse) completer;
|
||||
|
||||
const AddSiswaDialogView({
|
||||
Key? key,
|
||||
required DialogRequest request,
|
||||
required this.completer,
|
||||
}) : request = request as DialogRequest<DataSiswa>,
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<AddSiswaDialogViewModel>.reactive(
|
||||
viewModelBuilder: () => AddSiswaDialogViewModel(),
|
||||
onViewModelReady: (AddSiswaDialogViewModel model) async {
|
||||
await model.init();
|
||||
},
|
||||
builder: (
|
||||
BuildContext context,
|
||||
AddSiswaDialogViewModel model,
|
||||
Widget? child,
|
||||
) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: model.formKey,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'Tambah Siswa',
|
||||
style: boldTextStyle.copyWith(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
// create circle avatar
|
||||
Stack(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 50,
|
||||
backgroundColor: fontParagraphColor,
|
||||
child: model.imageBytes == null
|
||||
? const Icon(
|
||||
Icons.person,
|
||||
size: 50,
|
||||
color: Colors.white,
|
||||
)
|
||||
: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
child: Image.memory(
|
||||
model.imageBytes!,
|
||||
width: 100,
|
||||
height: 100,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: CircleAvatar(
|
||||
radius: 15,
|
||||
backgroundColor: blueColor,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
model.addImage();
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
color: lightColor,
|
||||
size: 15,
|
||||
)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MyTextFormField(
|
||||
labelText: 'NIS',
|
||||
controller: model.nisController,
|
||||
keyboardType: TextInputType.number,
|
||||
validator: Validatorless.multiple([
|
||||
Validatorless.required('NIS tidak boleh kosong'),
|
||||
Validatorless.number('NIS harus angka'),
|
||||
]),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MyTextFormField(
|
||||
labelText: 'Nama',
|
||||
controller: model.namaController,
|
||||
validator:
|
||||
Validatorless.required('Nama tidak boleh kosong'),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MyTextFormField(
|
||||
labelText: 'Tanggal Lahir',
|
||||
controller: model.tanggalLahirController,
|
||||
readOnly: true,
|
||||
validator: Validatorless.required(
|
||||
'Tanggal lahir tidak boleh kosong'),
|
||||
onTap: () {
|
||||
model.changeDate(context);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
// create dropdown button
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
border: Border.all(
|
||||
color: mainColor,
|
||||
),
|
||||
),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<String>(
|
||||
value: model.jenisKelamin,
|
||||
onChanged: (String? newValue) {
|
||||
// model.setSelectedJenisKelamin(newValue!);
|
||||
model.log.i(newValue);
|
||||
model.jenisKelamin = newValue!;
|
||||
model.notifyListeners();
|
||||
},
|
||||
items: model.jenisKelaminList.map((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(
|
||||
value,
|
||||
style: regularTextStyle.copyWith(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MyTextFormField(
|
||||
labelText: 'Alamat',
|
||||
controller: model.alamatController,
|
||||
maxLines: 2,
|
||||
validator:
|
||||
Validatorless.required('Alamat tidak boleh kosong'),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MyTextFormField(
|
||||
labelText: 'Keahlian',
|
||||
controller: model.keahlianController,
|
||||
maxLines: 4,
|
||||
validator: Validatorless.required(
|
||||
'Keahlian tidak boleh kosong'),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () => completer(
|
||||
DialogResponse(
|
||||
confirmed: false,
|
||||
),
|
||||
),
|
||||
child: const Text(
|
||||
'Batal',
|
||||
style: TextStyle(
|
||||
color: dangerColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (model.formKey.currentState!.validate()) {
|
||||
bool res = await model.postData();
|
||||
model.log.i("res: $res");
|
||||
// if (res) {
|
||||
// completer(
|
||||
// DialogResponse(
|
||||
// confirmed: true,
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
}
|
||||
},
|
||||
child: const Text(
|
||||
'Simpan',
|
||||
style: TextStyle(
|
||||
color: blueColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_holo_date_picker/flutter_holo_date_picker.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:panti_asuhan/app/app.locator.dart';
|
||||
import 'package:panti_asuhan/app/core/custom_base_view_model.dart';
|
||||
|
||||
import '../../../../../app/app.logger.dart';
|
||||
import '../../../../../services/http_services.dart';
|
||||
import '../../../../../services/my_easyloading.dart';
|
||||
|
||||
class AddSiswaDialogViewModel extends CustomBaseViewModel {
|
||||
final log = getLogger('AddSiswaDialogViewModel');
|
||||
final _httpService = locator<MyHttpServices>();
|
||||
final easyLoading = locator<MyEasyLoading>();
|
||||
List<String> jenisKelaminList = ['Laki-laki', 'Perempuan'];
|
||||
|
||||
String jenisKelamin = 'Laki-laki';
|
||||
|
||||
// image picker
|
||||
String? _imagePath;
|
||||
final ImagePicker _picker = ImagePicker();
|
||||
XFile? imageFile;
|
||||
Uint8List? imageBytes;
|
||||
|
||||
// form and text controller
|
||||
final formKey = GlobalKey<FormState>();
|
||||
|
||||
TextEditingController nisController = TextEditingController();
|
||||
TextEditingController namaController = TextEditingController();
|
||||
TextEditingController tanggalLahirController = TextEditingController();
|
||||
TextEditingController alamatController = TextEditingController();
|
||||
TextEditingController keahlianController = TextEditingController();
|
||||
|
||||
Future<void> init() async {}
|
||||
|
||||
void changeDate(BuildContext context) async {
|
||||
// get today's date
|
||||
var datePicked = await DatePicker.showSimpleDatePicker(
|
||||
context,
|
||||
initialDate: DateTime(2010),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2015),
|
||||
dateFormat: "dd-MMMM-yyyy",
|
||||
locale: DateTimePickerLocale.id,
|
||||
looping: true,
|
||||
);
|
||||
|
||||
if (datePicked != null) {
|
||||
String date = datePicked.toString().split(' ')[0];
|
||||
tanggalLahirController.text = date;
|
||||
}
|
||||
}
|
||||
|
||||
void addImage() async {
|
||||
try {
|
||||
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
|
||||
if (image != null) {
|
||||
imageFile = image;
|
||||
_imagePath = image.path;
|
||||
imageBytes = await image.readAsBytes();
|
||||
|
||||
log.i('image path: $_imagePath');
|
||||
notifyListeners();
|
||||
}
|
||||
} catch (e) {
|
||||
log.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> postData() async {
|
||||
if (imageBytes == null) {
|
||||
easyLoading.showError('Foto belum dipilih');
|
||||
return false;
|
||||
}
|
||||
|
||||
easyLoading.customLoading('Menambahkan data...');
|
||||
try {
|
||||
var formData = FormData.fromMap({
|
||||
'nis': nisController.text,
|
||||
'nama': namaController.text,
|
||||
'jenis_kelamin': jenisKelamin,
|
||||
'tanggal_lahir': tanggalLahirController.text,
|
||||
'alamat': alamatController.text,
|
||||
'keahlian': keahlianController.text,
|
||||
'foto': await MultipartFile.fromFile(_imagePath!),
|
||||
});
|
||||
|
||||
var response = await _httpService.postWithFormData('siswa', formData);
|
||||
easyLoading.dismissLoading();
|
||||
log.i(response.data);
|
||||
easyLoading.showSuccess('Siswa berhasil ditambahkan');
|
||||
return true;
|
||||
} catch (e) {
|
||||
easyLoading.dismissLoading();
|
||||
snackbarService.showSnackbar(
|
||||
message: 'Terjadi kesalahan',
|
||||
title: 'Gagal',
|
||||
duration: const Duration(seconds: 4),
|
||||
);
|
||||
log.e(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
// completer(
|
||||
// DialogResponse(
|
||||
// confirmed: true,
|
||||
// ),
|
||||
// );
|
||||
}
|
||||
}
|
||||
@ -20,10 +20,9 @@ class AdminIndexView extends StatelessWidget {
|
||||
) {
|
||||
return const Scaffold(
|
||||
body: Center(
|
||||
child: Text(
|
||||
'AdminIndexView asdas asda aasdsda a',
|
||||
),
|
||||
),
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.grey,
|
||||
)),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@ -36,6 +36,12 @@ class AdminIndexTrackingViewModel extends IndexTrackingViewModel {
|
||||
|
||||
Future<void> init() async {
|
||||
setIndex(1);
|
||||
// await 2 seconds to make sure the view is loaded
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
_navigationService.navigateTo(
|
||||
_views[1],
|
||||
id: 3,
|
||||
);
|
||||
}
|
||||
|
||||
void handleNavigation(int index) {
|
||||
|
||||
@ -21,14 +21,62 @@ class DanaSosialAdminView extends StatelessWidget {
|
||||
Widget? child,
|
||||
) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
width: double.infinity,
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: mainColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: mainGrey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Dana Sosial Bulan Ini',
|
||||
style: boldTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Total Dana Sosial',
|
||||
style: regularTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Rp. 1.000.000',
|
||||
style: regularTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: mainColor,
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
@ -40,84 +88,38 @@ class DanaSosialAdminView extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Dana Sosial Bulan Ini',
|
||||
style: boldTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15, vertical: 10),
|
||||
itemCount: 20,
|
||||
itemBuilder: (context, index) {
|
||||
return Card(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
model.log.i('Card $index tapped');
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text('1/02/15 - 10.00 am',
|
||||
style: boldTextStyle.copyWith(
|
||||
fontSize: 13, color: mainColor)),
|
||||
subtitle: Text('Progress $index'),
|
||||
trailing: Text('Pembangunan $index'),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Total Dana Sosial',
|
||||
style: regularTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Rp. 1.000.000',
|
||||
style: regularTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: mainGrey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset:
|
||||
const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15, vertical: 10),
|
||||
itemCount: 20,
|
||||
itemBuilder: (context, index) {
|
||||
return Card(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
model.log.i('Card $index tapped');
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text('1/02/15 - 10.00 am',
|
||||
style: boldTextStyle.copyWith(
|
||||
fontSize: 13, color: mainColor)),
|
||||
subtitle: Text('Progress $index'),
|
||||
trailing: Text('Pembangunan $index'),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: const FloatingActionButton(
|
||||
onPressed: null,
|
||||
child: Icon(Icons.add),
|
||||
));
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
model.goToTambahDanaSosial();
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
import 'package:panti_asuhan/app/core/custom_base_view_model.dart';
|
||||
|
||||
import '../../../../app/app.logger.dart';
|
||||
import '../../../../app/app.router.dart';
|
||||
import '../../../../app/core/custom_base_view_model.dart';
|
||||
|
||||
class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
final log = getLogger('DanaSosialAdminViewModel');
|
||||
Future<void> init() async {}
|
||||
|
||||
goToTambahDanaSosial() {
|
||||
navigationService.navigateTo(Routes.tambahDanaSosialView);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
|
||||
import '../../../../app/themes/app_colors.dart';
|
||||
import '../../../../app/themes/app_text.dart';
|
||||
import './data_siswa_view_model.dart';
|
||||
|
||||
class DataSiswaView extends StatelessWidget {
|
||||
@ -18,11 +20,102 @@ class DataSiswaView extends StatelessWidget {
|
||||
DataSiswaViewModel model,
|
||||
Widget? child,
|
||||
) {
|
||||
return const Scaffold(
|
||||
body: Center(
|
||||
child: Text(
|
||||
'DataSiswaView',
|
||||
),
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: mainColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: mainGrey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Total Siswa',
|
||||
style: regularTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'20 orang',
|
||||
style: regularTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: mainGrey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset:
|
||||
const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15, vertical: 10),
|
||||
itemCount: 20,
|
||||
itemBuilder: (context, index) {
|
||||
return Card(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
model.log.i('Card $index tapped');
|
||||
},
|
||||
child: ListTile(
|
||||
title: Text('Namanya',
|
||||
style: boldTextStyle.copyWith(
|
||||
fontSize: 13, color: mainColor)),
|
||||
subtitle: Text('Umurnya : $index'),
|
||||
// circle avatar
|
||||
trailing: Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: mainColor,
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.person,
|
||||
color: Colors.white,
|
||||
),
|
||||
)),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
model.addSiswa();
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@ -1,5 +1,19 @@
|
||||
import 'package:panti_asuhan/app/core/custom_base_view_model.dart';
|
||||
|
||||
import '../../../../app/app.dialogs.dart';
|
||||
import '../../../../app/app.logger.dart';
|
||||
import '../add_siswa_dialog/add_siswa_dialog/add_siswa_dialog_view.dart';
|
||||
|
||||
class DataSiswaViewModel extends CustomBaseViewModel {
|
||||
final log = getLogger('DataSiswaViewModel');
|
||||
Future<void> init() async {}
|
||||
|
||||
void addSiswa() async {
|
||||
final res = await dialogService.showCustomDialog(
|
||||
variant: DialogType.addSiswaDialogView,
|
||||
data: DataSiswa(nama: null),
|
||||
);
|
||||
|
||||
if (res?.confirmed != true) return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,58 +24,60 @@ class LoginScreenView extends StatelessWidget {
|
||||
return Scaffold(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.2,
|
||||
),
|
||||
// show the logo.png
|
||||
const Center(
|
||||
child: Image(
|
||||
image: AssetImage("assets/logo.png"),
|
||||
width: 150,
|
||||
height: 150,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.2,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"SILAHKAN LOGIN",
|
||||
style: boldTextStyle.copyWith(
|
||||
fontSize: 18,
|
||||
// show the logo.png
|
||||
const Center(
|
||||
child: Image(
|
||||
image: AssetImage("assets/logo.png"),
|
||||
width: 150,
|
||||
height: 150,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const MyTextFormField(
|
||||
hintText: "Username",
|
||||
prefixIcon: Icon(Icons.person),
|
||||
// controller: model.usernameController,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const MyTextFormField(
|
||||
hintText: "Password",
|
||||
prefixIcon: Icon(Icons.lock),
|
||||
// controller: model.passwordController,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.5,
|
||||
child: MyButton(
|
||||
text: "LOGIN",
|
||||
onPressed: () {
|
||||
model.goToAdmin();
|
||||
},
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"SILAHKAN LOGIN",
|
||||
style: boldTextStyle.copyWith(
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const MyTextFormField(
|
||||
hintText: "Username",
|
||||
prefixIcon: Icon(Icons.person),
|
||||
// controller: model.usernameController,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const MyTextFormField(
|
||||
hintText: "Password",
|
||||
prefixIcon: Icon(Icons.lock),
|
||||
// controller: model.passwordController,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.5,
|
||||
child: MyButton(
|
||||
text: "LOGIN",
|
||||
onPressed: () {
|
||||
model.goToAdmin();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
134
lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view.dart
Normal file
134
lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view.dart
Normal file
@ -0,0 +1,134 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:panti_asuhan/app/themes/app_colors.dart';
|
||||
import 'package:panti_asuhan/app/themes/app_text.dart';
|
||||
import 'package:panti_asuhan/ui/widgets/my_button.dart';
|
||||
import 'package:panti_asuhan/ui/widgets/my_textformfield.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import 'package:validatorless/validatorless.dart';
|
||||
|
||||
import './tambah_dana_sosial_view_model.dart';
|
||||
|
||||
class TambahDanaSosialView extends StatelessWidget {
|
||||
const TambahDanaSosialView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder<TambahDanaSosialViewModel>.reactive(
|
||||
viewModelBuilder: () => TambahDanaSosialViewModel(),
|
||||
onViewModelReady: (TambahDanaSosialViewModel model) async {
|
||||
await model.init();
|
||||
},
|
||||
builder: (
|
||||
BuildContext context,
|
||||
TambahDanaSosialViewModel model,
|
||||
Widget? child,
|
||||
) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text(
|
||||
"Form Dana Sosial",
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
backgroundColor: mainColor,
|
||||
elevation: 0,
|
||||
),
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
|
||||
child: Form(
|
||||
key: model.formKey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Keterangan",
|
||||
style: regularTextStyle.copyWith(color: mainColor),
|
||||
),
|
||||
MyTextFormField(
|
||||
hintText: "Keterangan",
|
||||
controller: model.ketController,
|
||||
maxLines: 3,
|
||||
validator: Validatorless.required(
|
||||
'Keterangan tidak boleh kosong'),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
"Jumlah (Rp. )",
|
||||
style: regularTextStyle.copyWith(color: mainColor),
|
||||
),
|
||||
MyTextFormField(
|
||||
hintText: "Jumlah (Rp. )",
|
||||
keyboardType: TextInputType.number,
|
||||
controller: model.jumlahController,
|
||||
validator: Validatorless.multiple(
|
||||
[
|
||||
Validatorless.required('Jumlah tidak boleh kosong'),
|
||||
Validatorless.number('Jumlah harus angka'),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
"Tanggal",
|
||||
style: regularTextStyle.copyWith(color: mainColor),
|
||||
),
|
||||
MyTextFormField(
|
||||
hintText: 'Tanggal',
|
||||
readOnly: true,
|
||||
validator: Validatorless.required(
|
||||
'Tanggal lahir tidak boleh kosong'),
|
||||
onTap: () {
|
||||
model.changeDate(context);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
"Jenis Dana",
|
||||
style: regularTextStyle.copyWith(color: mainColor),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
border: Border.all(
|
||||
color: mainColor,
|
||||
),
|
||||
),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<String>(
|
||||
value: model.jenisDana,
|
||||
onChanged: (String? newValue) {
|
||||
model.jenisDana = newValue!;
|
||||
},
|
||||
items: model.jenisDanaList
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value,
|
||||
style: const TextStyle(fontSize: 16)),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
MyButton(
|
||||
text: "Simpan",
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:panti_asuhan/app/core/custom_base_view_model.dart';
|
||||
|
||||
class TambahDanaSosialViewModel extends CustomBaseViewModel {
|
||||
String jenisDana = 'Pemasukan';
|
||||
List<String> jenisDanaList = ['Pemasukan', 'Pengeluaran'];
|
||||
|
||||
final formKey = GlobalKey<FormState>();
|
||||
|
||||
TextEditingController ketController = TextEditingController();
|
||||
TextEditingController jumlahController = TextEditingController();
|
||||
TextEditingController tanggalController = TextEditingController();
|
||||
|
||||
Future<void> init() async {}
|
||||
|
||||
void changeDate(BuildContext context) async {
|
||||
// get today's date
|
||||
var datePicked = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
// last date is today's date
|
||||
lastDate: DateTime.now(),
|
||||
);
|
||||
|
||||
if (datePicked != null) {
|
||||
String date = datePicked.toString().split(' ')[0];
|
||||
tanggalController.text = date;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user