Files
lis/mylis/lib/screens/examinations/examination_detail_screen.dart
T
2026-07-22 10:01:55 +07:00

174 lines
5.5 KiB
Dart

part of '../../app/app.dart';
class ExaminationDetailScreen extends StatefulWidget {
const ExaminationDetailScreen({
super.key,
required this.token,
required this.baseUrl,
required this.id,
});
final String token;
final String baseUrl;
final int id;
@override
State<ExaminationDetailScreen> createState() =>
_ExaminationDetailScreenState();
}
class _ExaminationDetailScreenState extends State<ExaminationDetailScreen> {
late final ApiClient _api;
late Future<Map<String, dynamic>> _future;
@override
void initState() {
super.initState();
_api = ApiClient(baseUrl: widget.baseUrl, token: widget.token);
_future = _api.get('api/mobile/examinations/${widget.id}');
}
void _reload() {
setState(() {
_future = _api.get('api/mobile/examinations/${widget.id}');
});
}
Future<void> _launch(String? url) async {
if (url == null || url.isEmpty) {
return;
}
final uri = Uri.parse(url);
if (!await launchUrl(uri, mode: LaunchMode.externalApplication)) {
if (!mounted) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Halaman tidak bisa dibuka.')),
);
}
}
Future<void> _openExpertise() async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ExpertiseScreen(
token: widget.token,
baseUrl: widget.baseUrl,
id: widget.id,
),
),
);
_reload();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Detail Pemeriksaan'),
actions: [
IconButton(
onPressed: _reload,
icon: const Icon(Icons.refresh),
tooltip: 'Cek status',
),
],
),
body: FutureBuilder<Map<String, dynamic>>(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const LoadingScreen();
}
if (snapshot.hasError) {
return ErrorView(
message: _message(snapshot.error),
onRetry: _reload,
);
}
final data = snapshot.data!;
final item = asMap(data['item']);
return ListView(
padding: const EdgeInsets.all(16),
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
item['nmpasien']?.toString() ?? '-',
style: Theme.of(context).textTheme.titleLarge
?.copyWith(fontWeight: FontWeight.w800),
),
),
StatusPill(
status: item['status']?.toString() ?? 'NEW',
),
],
),
const SizedBox(height: 16),
DetailRow(label: 'No. Lab', value: item['nofoto']),
DetailRow(label: 'No. RM', value: item['noregister']),
DetailRow(label: 'Order', value: item['reques']),
DetailRow(
label: 'Asal Pasien',
value: item['asalpasien'],
),
DetailRow(label: 'Ruangan', value: item['ruangan']),
DetailRow(
label: 'Dokter Pengirim',
value: item['klinisi'] ?? item['nmdokter'],
),
DetailRow(label: 'Spesimen', value: item['nm_spesimen']),
DetailRow(label: 'Tanggal Daftar', value: item['daftar']),
DetailRow(
label: 'Tanggal Sampel',
value: item['tanggalsampel'],
),
DetailRow(
label: 'Cara Pengambilan',
value: item['pengambilan'],
),
DetailRow(
label: 'Asal Pengambilan',
value: item['asalpengirim'],
),
DetailRow(label: 'Alamat', value: item['alamatpasien']),
],
),
),
),
const SizedBox(height: 12),
FilledButton.icon(
onPressed: _openExpertise,
icon: const Icon(Icons.edit_document),
label: const Text('Expertise'),
),
OutlinedButton.icon(
onPressed: _reload,
icon: const Icon(Icons.fact_check_outlined),
label: const Text('Cek Status'),
),
if (data['result_url'] != null)
TextButton.icon(
onPressed: () => _launch(data['result_url']?.toString()),
icon: const Icon(Icons.description_outlined),
label: const Text('Preview Hasil'),
),
],
);
},
),
);
}
}