MIF_E31222653/aplikasi/lib/presentation/screens/features/food_detail_page.dart

215 lines
7.4 KiB
Dart

import 'package:flutter/material.dart';
import 'custom_order_page.dart';
class FoodDetailPage extends StatefulWidget {
final String name;
final String description;
final String price;
final String imageUrl;
final String location;
const FoodDetailPage({
super.key,
required this.name,
required this.description,
required this.price,
required this.imageUrl,
required this.location,
});
@override
State<FoodDetailPage> createState() => _FoodDetailPageState();
}
class _FoodDetailPageState extends State<FoodDetailPage> {
bool isFavorite = false;
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Image kotak, rounded atas, max width 250, di tengah
Center(
child: ClipRRect(
borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
child: SizedBox(
width: 350,
child: AspectRatio(
aspectRatio: 1,
child: Image.asset(
widget.imageUrl,
fit: BoxFit.cover,
),
),
),
),
),
// Content
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 16),
// Title
Text(
widget.name,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
// Description
Text(
widget.description,
style: TextStyle(
fontSize: 13,
color: Colors.grey[600],
),
),
const SizedBox(height: 8),
// Price and Location (kantin)
Row(
children: [
Text(
widget.price,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
const Spacer(),
Text(
widget.location,
style: TextStyle(
fontSize: 13,
color: Colors.grey[600],
),
),
],
),
const SizedBox(height: 16),
// Action Buttons: Favorit di kiri, Lapor & Bagikan di kanan
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildOutlinedActionButton(
icon: isFavorite ? Icons.favorite : Icons.favorite_border,
label: 'Favorit',
onTap: () {
setState(() {
isFavorite = !isFavorite;
});
},
color: isFavorite ? Colors.red : Colors.grey[600],
),
Row(
children: [
_buildOutlinedActionButton(
icon: Icons.report_outlined,
label: 'Lapor',
onTap: () {},
color: Colors.grey[600],
),
const SizedBox(width: 4),
_buildOutlinedActionButton(
icon: Icons.share_outlined,
label: 'Bagikan',
onTap: () {},
color: Colors.grey[600],
),
],
),
],
),
const SizedBox(height: 20),
// Add to Cart Button
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () async {
// Navigasi ke CustomOrderPage dengan animasi scale
await Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => CustomOrderPage(
name: widget.name,
price: int.tryParse(widget.price.replaceAll(RegExp(r'[^0-9]'), '')) ?? 0,
),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
final scale = Tween<double>(begin: 0.8, end: 1.0).animate(
CurvedAnimation(parent: animation, curve: Curves.easeOutBack),
);
return ScaleTransition(
scale: scale,
child: child,
);
},
transitionDuration: const Duration(milliseconds: 350),
reverseTransitionDuration: const Duration(milliseconds: 250),
),
);
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF21A5E7),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
elevation: 0,
),
child: const Text(
'Tambah Pembelian',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
),
const SizedBox(height: 16),
],
),
),
],
),
);
}
Widget _buildOutlinedActionButton({
required IconData icon,
required String label,
required VoidCallback onTap,
required Color? color,
}) {
return OutlinedButton.icon(
onPressed: onTap,
icon: Icon(icon, color: color, size: 18),
label: Text(
label,
style: TextStyle(fontSize: 12, color: color, fontWeight: FontWeight.w500),
),
style: OutlinedButton.styleFrom(
side: BorderSide(color: Colors.grey[400]!),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
minimumSize: const Size(0, 32),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.compact,
),
);
}
}