Files
app-hyggecraftery/lib/screens/order_detail_screen.dart
2026-01-03 15:24:36 +01:00

294 lines
9.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:intl/intl.dart';
import '../models/order.dart';
class OrderDetailScreen extends StatelessWidget {
final Order order;
const OrderDetailScreen({
super.key,
required this.order,
});
@override
Widget build(BuildContext context) {
final dateFormat = DateFormat('dd.MM.yyyy HH:mm');
final statusColor = _getStatusColor(order.status);
return Scaffold(
appBar: AppBar(
title: Text('Bestellung #${order.id}'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Status
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: statusColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: statusColor),
),
child: Row(
children: [
Icon(Icons.info_outline, color: statusColor),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Status',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Colors.grey[600],
),
),
Text(
order.statusDisplay,
style: TextStyle(
color: statusColor,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
],
),
),
],
),
),
const SizedBox(height: 16),
// Bestelldatum
_buildInfoRow(
context,
'Bestelldatum',
dateFormat.format(order.dateCreated),
Icons.calendar_today,
),
const SizedBox(height: 16),
// Produkte
Text(
'Produkte',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
...order.items.map((item) => _buildOrderItem(context, item)),
const SizedBox(height: 16),
// Zahlungsmethode
if (order.paymentMethodTitle != null) ...[
_buildInfoRow(
context,
'Zahlungsmethode',
order.paymentMethodTitle!,
Icons.payment,
),
const SizedBox(height: 16),
],
// Rechnungsadresse
if (order.billing != null) ...[
Text(
'Rechnungsadresse',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
),
child: Text(
order.billing!.fullAddress,
style: Theme.of(context).textTheme.bodyMedium,
),
),
const SizedBox(height: 16),
],
// Lieferadresse
if (order.shipping != null) ...[
Text(
'Lieferadresse',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
),
child: Text(
order.shipping!.fullAddress,
style: Theme.of(context).textTheme.bodyMedium,
),
),
const SizedBox(height: 16),
],
// Gesamtsumme
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF8B6F47).withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Gesamtsumme:',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
'${order.total} ${order.currency}',
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
color: const Color(0xFF8B6F47),
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
),
);
}
Widget _buildInfoRow(
BuildContext context,
String label,
String value,
IconData icon,
) {
return Row(
children: [
Icon(icon, size: 20, color: Colors.grey[600]),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Colors.grey[600],
),
),
Text(
value,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w500,
),
),
],
),
),
],
);
}
Widget _buildOrderItem(BuildContext context, OrderItem item) {
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: Padding(
padding: const EdgeInsets.all(12),
child: Row(
children: [
if (item.imageUrl != null)
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: CachedNetworkImage(
imageUrl: item.imageUrl!,
width: 60,
height: 60,
fit: BoxFit.cover,
errorWidget: (context, url, error) => Container(
width: 60,
height: 60,
color: Colors.grey[300],
child: const Icon(Icons.image_not_supported),
),
),
)
else
Container(
width: 60,
height: 60,
color: Colors.grey[300],
child: const Icon(Icons.image_not_supported),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item.name,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
'Menge: ${item.quantity}',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Colors.grey[600],
),
),
],
),
),
Text(
'${item.price}',
style: Theme.of(context).textTheme.titleSmall?.copyWith(
color: const Color(0xFF8B6F47),
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
Color _getStatusColor(String status) {
switch (status) {
case 'completed':
return Colors.green;
case 'processing':
return Colors.blue;
case 'pending':
return Colors.orange;
case 'on-hold':
return Colors.amber;
case 'cancelled':
return Colors.red;
case 'refunded':
return Colors.purple;
case 'failed':
return Colors.red;
default:
return Colors.grey;
}
}
}