Perbarui struktur dan referensi file di dashboard_view.dart dan detail_donatur_view.dart. Tambahkan dokumentasi pada kelas DateTimeHelper dan perkenalan fungsi baru untuk format tanggal relatif serta nama hari dan bulan. Hapus widget yang tidak digunakan seperti detail_penitipan_dialog.dart, loading_indicator.dart, navigation_button.dart, statistic_card.dart, dan status_pill.dart untuk menyederhanakan kode.

This commit is contained in:
Khafidh Fuadi
2025-03-16 16:30:23 +07:00
parent 5814b19546
commit 078d74aad3
22 changed files with 1639 additions and 509 deletions

View File

@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:penyaluran_app/app/widgets/indicators/loading_indicator.dart';
/// Indikator loading yang menempati seluruh layar
///
/// Indikator ini memiliki latar belakang semi-transparan dan dapat
/// dikonfigurasi dengan pesan.
class FullScreenLoading extends StatelessWidget {
/// Pesan yang ditampilkan di bawah indikator loading (opsional)
final String? message;
/// Warna indikator loading
final Color? color;
/// Warna latar belakang
final Color backgroundColor;
/// Apakah dapat dibatalkan dengan mengetuk di luar
final bool dismissible;
/// Konstruktor untuk FullScreenLoading
const FullScreenLoading({
super.key,
this.message,
this.color,
this.backgroundColor = Colors.black54,
this.dismissible = false,
});
@override
Widget build(BuildContext context) {
return Container(
color: backgroundColor,
child: LoadingIndicator(
message: message,
color: color ?? Colors.white,
textColor: Colors.white,
),
);
}
/// Menampilkan indikator loading di seluruh layar
static void show(BuildContext context,
{String? message, bool dismissible = false}) {
showDialog(
context: context,
barrierDismissible: dismissible,
builder: (context) => FullScreenLoading(
message: message,
dismissible: dismissible,
),
);
}
/// Menyembunyikan indikator loading
static void hide(BuildContext context) {
Navigator.of(context, rootNavigator: true).pop();
}
}

View File

@ -0,0 +1,73 @@
import 'package:flutter/material.dart';
import 'package:penyaluran_app/app/theme/app_colors.dart';
/// Indikator loading yang digunakan untuk menampilkan status loading
///
/// Indikator ini dapat dikonfigurasi dengan pesan, warna, dan ukuran.
class LoadingIndicator extends StatelessWidget {
/// Pesan yang ditampilkan di bawah indikator loading (opsional)
final String? message;
/// Warna indikator loading
final Color? color;
/// Ukuran indikator loading
final double size;
/// Ketebalan garis indikator loading
final double strokeWidth;
/// Warna teks pesan
final Color? textColor;
/// Ukuran teks pesan
final double textSize;
/// Jarak antara indikator loading dan pesan
final double spacing;
/// Konstruktor untuk LoadingIndicator
const LoadingIndicator({
super.key,
this.message,
this.color,
this.size = 40.0,
this.strokeWidth = 3.0,
this.textColor,
this.textSize = 16.0,
this.spacing = 16.0,
});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: size,
height: size,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
color ?? AppColors.primary,
),
strokeWidth: strokeWidth,
),
),
if (message != null) ...[
SizedBox(height: spacing),
Text(
message!,
style: TextStyle(
fontSize: textSize,
color: textColor ?? Colors.grey[700],
),
textAlign: TextAlign.center,
),
],
],
),
);
}
}

View File

@ -0,0 +1,103 @@
import 'package:flutter/material.dart';
import 'package:penyaluran_app/app/theme/app_theme.dart';
/// Indikator status berbentuk pill yang digunakan untuk menampilkan status
///
/// Indikator ini memiliki teks status dan warna latar belakang yang dapat
/// dikonfigurasi.
class StatusPill extends StatelessWidget {
/// Teks status yang ditampilkan
final String status;
/// Warna latar belakang pill
final Color? backgroundColor;
/// Gaya teks status
final TextStyle? textStyle;
/// Warna teks status
final Color? textColor;
/// Padding pill
final EdgeInsetsGeometry padding;
/// Radius border pill
final double borderRadius;
/// Konstruktor untuk StatusPill
const StatusPill({
super.key,
required this.status,
this.backgroundColor,
this.textStyle,
this.textColor,
this.padding = const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
this.borderRadius = 12,
});
/// Konstruktor factory untuk StatusPill dengan status "Terverifikasi"
factory StatusPill.verified({String status = 'Terverifikasi'}) {
return StatusPill(
status: status,
backgroundColor: AppTheme.verifiedColor,
textColor: Colors.white,
);
}
/// Konstruktor factory untuk StatusPill dengan status "Diproses"
factory StatusPill.processed({String status = 'Diproses'}) {
return StatusPill(
status: status,
backgroundColor: AppTheme.processedColor,
textColor: Colors.white,
);
}
/// Konstruktor factory untuk StatusPill dengan status "Ditolak"
factory StatusPill.rejected({String status = 'Ditolak'}) {
return StatusPill(
status: status,
backgroundColor: AppTheme.rejectedColor,
textColor: Colors.white,
);
}
/// Konstruktor factory untuk StatusPill dengan status "Dijadwalkan"
factory StatusPill.scheduled({String status = 'Dijadwalkan'}) {
return StatusPill(
status: status,
backgroundColor: AppTheme.scheduledColor,
textColor: Colors.white,
);
}
/// Konstruktor factory untuk StatusPill dengan status "Selesai"
factory StatusPill.completed({String status = 'Selesai'}) {
return StatusPill(
status: status,
backgroundColor: AppTheme.completedColor,
textColor: Colors.white,
);
}
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Container(
padding: padding,
decoration: BoxDecoration(
color: backgroundColor ?? AppTheme.verifiedColor,
borderRadius: BorderRadius.circular(borderRadius),
),
child: Text(
status,
style: textStyle ??
textTheme.bodySmall?.copyWith(
fontSize: 10,
color: textColor ?? Colors.white,
),
),
);
}
}