No content changes: git diff --ignore-all-space over these files is empty. The churn came from editing on Windows against a repo checked out with LF.
176 lines
7.1 KiB
Dart
176 lines
7.1 KiB
Dart
import 'dart:io';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import '../../config/app_config.dart';
|
|
import 'pending_documents_provider.dart';
|
|
|
|
class PendingDocumentCard extends ConsumerWidget {
|
|
final PendingDocument doc;
|
|
final VoidCallback onReload;
|
|
|
|
const PendingDocumentCard({
|
|
super.key,
|
|
required this.doc,
|
|
required this.onReload,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
Color statusColor;
|
|
String statusText;
|
|
IconData statusIcon;
|
|
|
|
switch (doc.status) {
|
|
case PendingDocumentStatus.uploading:
|
|
case PendingDocumentStatus.processing:
|
|
statusColor = Colors.orange;
|
|
statusText = 'Sedang memproses dokumen...';
|
|
statusIcon = Icons.cloud_upload;
|
|
break;
|
|
case PendingDocumentStatus.success:
|
|
statusColor = AppConfig.successColor;
|
|
statusText = 'Ketuk untuk dikonfirmasi';
|
|
statusIcon = Icons.check_circle;
|
|
break;
|
|
case PendingDocumentStatus.error:
|
|
statusColor = AppConfig.errorColor;
|
|
statusText = 'Gagal Memproses';
|
|
statusIcon = Icons.error;
|
|
break;
|
|
case PendingDocumentStatus.syncFailed:
|
|
statusColor = Colors.deepOrange;
|
|
statusText = 'Belum tersinkron ke server';
|
|
statusIcon = Icons.sync_problem;
|
|
break;
|
|
}
|
|
|
|
return Card(
|
|
elevation: 0,
|
|
margin: const EdgeInsets.only(bottom: AppConfig.spaceMedium),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(AppConfig.borderRadiusMedium),
|
|
side: BorderSide(color: statusColor.withOpacity(0.5)),
|
|
),
|
|
child: InkWell(
|
|
onTap: () {
|
|
if (doc.status == PendingDocumentStatus.success) {
|
|
final routePath = doc.scanMode == 'Product' ? '/product-editor' : '/editor';
|
|
context.push(routePath, extra: doc.id).then((_) {
|
|
onReload();
|
|
});
|
|
} else if (doc.status == PendingDocumentStatus.error) {
|
|
showModalBottomSheet(
|
|
context: context,
|
|
builder: (ctx) => SafeArea(
|
|
child: Wrap(
|
|
children: [
|
|
ListTile(
|
|
leading: const Icon(Icons.refresh),
|
|
title: const Text('Coba Unggah Ulang'),
|
|
onTap: () {
|
|
Navigator.pop(ctx);
|
|
ref.read(pendingDocumentsProvider.notifier).retryUpload(doc.id);
|
|
},
|
|
),
|
|
ListTile(
|
|
leading: const Icon(Icons.delete, color: AppConfig.errorColor),
|
|
title: const Text('Hapus Dokumen', style: TextStyle(color: AppConfig.errorColor)),
|
|
onTap: () {
|
|
Navigator.pop(ctx);
|
|
ref.read(pendingDocumentsProvider.notifier).removeDocument(doc.id);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
} else if (doc.status == PendingDocumentStatus.syncFailed) {
|
|
showModalBottomSheet(
|
|
context: context,
|
|
builder: (ctx) => SafeArea(
|
|
child: Wrap(
|
|
children: [
|
|
ListTile(
|
|
leading: const Icon(Icons.sync),
|
|
title: const Text('Coba Sinkron Ulang'),
|
|
onTap: () {
|
|
Navigator.pop(ctx);
|
|
ref.read(pendingDocumentsProvider.notifier).retrySync(doc.id);
|
|
},
|
|
),
|
|
ListTile(
|
|
leading: const Icon(Icons.delete, color: AppConfig.errorColor),
|
|
title: const Text('Hapus Dokumen', style: TextStyle(color: AppConfig.errorColor)),
|
|
onTap: () {
|
|
Navigator.pop(ctx);
|
|
ref.read(pendingDocumentsProvider.notifier).removeDocument(doc.id);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
},
|
|
borderRadius: BorderRadius.circular(AppConfig.borderRadiusMedium),
|
|
child: Padding(
|
|
padding: AppConfig.paddingLarge,
|
|
child: Row(
|
|
children: [
|
|
ClipRRect(
|
|
borderRadius: BorderRadius.circular(AppConfig.borderRadiusSmall),
|
|
child: Image.file(
|
|
File(doc.imagePath),
|
|
width: 60,
|
|
height: 60,
|
|
fit: BoxFit.cover,
|
|
errorBuilder: (context, error, stackTrace) => Container(
|
|
width: 60,
|
|
height: 60,
|
|
color: Colors.grey.shade200,
|
|
child: const Icon(Icons.image, color: Colors.grey),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: AppConfig.spaceLarge),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Icon(statusIcon, size: 16, color: statusColor),
|
|
const SizedBox(width: AppConfig.spaceXS),
|
|
Expanded(
|
|
child: Text(
|
|
statusText,
|
|
style: AppConfig.bodyMedium.copyWith(color: statusColor, fontWeight: FontWeight.bold),
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: AppConfig.spaceSmall),
|
|
if (doc.status == PendingDocumentStatus.uploading || doc.status == PendingDocumentStatus.processing)
|
|
const LinearProgressIndicator(),
|
|
if (doc.status == PendingDocumentStatus.success)
|
|
Text('Ketuk untuk mereview dan konfirmasi data', style: AppConfig.bodySmall),
|
|
if (doc.status == PendingDocumentStatus.error)
|
|
Text(doc.errorMessage ?? 'Kesalahan tidak diketahui', style: AppConfig.bodySmall.copyWith(color: AppConfig.errorColor), maxLines: 1, overflow: TextOverflow.ellipsis),
|
|
if (doc.status == PendingDocumentStatus.syncFailed)
|
|
Text(doc.errorMessage ?? 'Ketuk untuk coba sinkron ulang', style: AppConfig.bodySmall.copyWith(color: Colors.deepOrange), maxLines: 1, overflow: TextOverflow.ellipsis),
|
|
],
|
|
),
|
|
),
|
|
if (doc.status == PendingDocumentStatus.success)
|
|
const Icon(Icons.chevron_right, color: AppConfig.primaryColor),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|