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,135 @@
import 'package:flutter/material.dart';
import 'package:penyaluran_app/app/theme/app_colors.dart';
/// Kartu informasi yang digunakan untuk menampilkan informasi
///
/// Kartu ini memiliki judul, deskripsi, dan ikon, dan dapat dikonfigurasi
/// untuk berbagai ukuran dan warna.
class InfoCard extends StatelessWidget {
/// Judul kartu
final String title;
/// Deskripsi atau konten kartu
final String description;
/// Ikon yang ditampilkan di kartu (opsional)
final IconData? icon;
/// Widget ikon kustom yang ditampilkan di kartu (opsional)
final Widget? iconWidget;
/// Warna latar belakang kartu
final Color? backgroundColor;
/// Warna judul
final Color? titleColor;
/// Warna deskripsi
final Color? descriptionColor;
/// Warna ikon
final Color? iconColor;
/// Fungsi yang dipanggil ketika kartu ditekan (opsional)
final VoidCallback? onTap;
/// Padding kartu
final EdgeInsetsGeometry padding;
/// Margin kartu
final EdgeInsetsGeometry margin;
/// Konstruktor untuk InfoCard
const InfoCard({
super.key,
required this.title,
required this.description,
this.icon,
this.iconWidget,
this.backgroundColor,
this.titleColor,
this.descriptionColor,
this.iconColor,
this.onTap,
this.padding = const EdgeInsets.all(16),
this.margin = const EdgeInsets.all(0),
}) : assert(
icon != null ||
iconWidget != null ||
(icon == null && iconWidget == null),
'Cannot provide both icon and iconWidget');
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
final Color bgColor = backgroundColor ?? Colors.white;
final Color titleTextColor = titleColor ?? AppColors.textPrimary;
final Color descTextColor = descriptionColor ?? AppColors.textSecondary;
final Color iconColorValue = iconColor ?? AppColors.primary;
return Card(
margin: margin,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(12),
child: Container(
padding: padding,
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(12),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (icon != null)
Padding(
padding: const EdgeInsets.only(right: 16),
child: Icon(
icon,
size: 24,
color: iconColorValue,
),
)
else if (iconWidget != null)
Padding(
padding: const EdgeInsets.only(right: 16),
child: SizedBox(
width: 24,
height: 24,
child: iconWidget,
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: textTheme.titleMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.bold,
color: titleTextColor,
),
),
const SizedBox(height: 4),
Text(
description,
style: textTheme.bodyMedium?.copyWith(
fontSize: 14,
color: descTextColor,
),
),
],
),
),
],
),
),
),
);
}
}

View File

@ -0,0 +1,111 @@
import 'package:flutter/material.dart';
import 'package:penyaluran_app/app/theme/app_theme.dart';
/// Kartu statistik yang digunakan untuk menampilkan data statistik
///
/// Kartu ini memiliki judul, jumlah, dan subtitle, dan dapat dikonfigurasi
/// untuk berbagai ukuran dan warna.
class StatisticCard extends StatelessWidget {
/// Judul kartu
final String title;
/// Jumlah atau nilai statistik
final String count;
/// Subtitle atau deskripsi tambahan
final String subtitle;
/// Tinggi kartu
final double height;
/// Gradient latar belakang kartu
final Gradient? gradient;
/// Warna teks
final Color textColor;
/// Ikon yang ditampilkan di kartu (opsional)
final IconData? icon;
/// Warna ikon
final Color? iconColor;
/// Konstruktor untuk StatisticCard
const StatisticCard({
super.key,
required this.title,
required this.count,
required this.subtitle,
this.height = 100,
this.gradient,
this.textColor = Colors.white,
this.icon,
this.iconColor,
});
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
final Gradient backgroundGradient = gradient ?? AppTheme.primaryGradient;
final Color iconColorValue = iconColor ?? textColor;
return Container(
width: double.infinity,
height: height,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: backgroundGradient,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(26),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: textTheme.bodyMedium?.copyWith(
fontSize: 14,
color: textColor.withAlpha(204),
),
),
const SizedBox(height: 8),
Text(
count,
style: textTheme.headlineSmall?.copyWith(
fontSize: 24,
fontWeight: FontWeight.bold,
color: textColor,
),
),
const Spacer(),
Text(
subtitle,
style: textTheme.bodySmall?.copyWith(
fontSize: 12,
color: textColor,
),
),
],
),
),
if (icon != null)
Icon(
icon,
size: 40,
color: iconColorValue.withAlpha(51),
),
],
),
);
}
}