nesward_flutter_app/lib/widgets/deal_of_the_day.dart

309 lines
9.5 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
class DealOfTheDay extends StatefulWidget {
const DealOfTheDay({super.key});
@override
State<DealOfTheDay> createState() => _DealOfTheDayState();
}
class _DealOfTheDayState extends State<DealOfTheDay> {
Duration _remainingTime = const Duration(hours: 5, minutes: 0, seconds: 0);
late Timer _timer;
// Both products are inside the same list now
final List<Map<String, dynamic>> _products = [
{
'name': 'Seeds of Change Organic Quinoa, Brown, & Red Rice',
'brand': 'NestFood',
'rating': 4.0,
'originalPrice': 33.8,
'discountedPrice': 32.85,
'imageUrl':
'https://nest-frontend-v6.vercel.app/assets/imgs/banner/banner-5.png',
},
{
'name': 'proudly simply smart oraganics Gluten free',
'brand': 'Green Harvest',
'rating': 4.5,
'originalPrice': 35.0,
'discountedPrice': 33.0,
'imageUrl':
'https://nest-frontend-v6.vercel.app/assets/imgs/banner/banner-6.png',
},
];
@override
void initState() {
super.initState();
_startCountdown();
}
void _startCountdown() {
_timer = Timer.periodic(const Duration(seconds: 1), (_) {
setState(() {
if (_remainingTime.inSeconds > 0) {
_remainingTime -= const Duration(seconds: 1);
} else {
_timer.cancel();
}
});
});
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
final days = _remainingTime.inDays;
final hours = _remainingTime.inHours.remainder(24);
final minutes = _remainingTime.inMinutes.remainder(60);
final seconds = _remainingTime.inSeconds.remainder(60);
return Container(
color: Colors.grey.shade50,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Deals Of The Day",
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: Color(0xFF253D4E),
),
),
const SizedBox(height: 20),
// Display multiple products dynamically
Column(
children: _products
.map((product) =>
_buildProductCard(product, days, hours, minutes, seconds))
.toList(),
),
],
),
),
);
}
Widget _buildProductCard(Map<String, dynamic> product, int days, int hours,
int minutes, int seconds) {
return Container(
margin: const EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
children: [
// Product Image + Countdown
Stack(
children: [
ClipRRect(
borderRadius:
const BorderRadius.vertical(top: Radius.circular(20)),
child: Image.network(
product['imageUrl'],
fit: BoxFit.cover,
height: 280,
width: double.infinity,
),
),
Positioned(
bottom: 20,
left: 0,
right: 0,
child: Center(
child: Container(
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.95),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
_buildTimeBox(days, 'Days'),
_buildTimeBox(hours, 'Hours'),
_buildTimeBox(minutes, 'Mins'),
_buildTimeBox(seconds, 'Sec'),
],
),
),
),
),
],
),
// Product Info
Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product['name'],
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Color(0xFF253D4E),
height: 1.4,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 10),
// Rating
Row(
children: [
...List.generate(5, (index) {
return Icon(
index < product['rating'].floor()
? Icons.star
: Icons.star_border,
color: const Color(0xFFFFC107),
size: 18,
);
}),
const SizedBox(width: 8),
Text(
"(${product['rating'].toStringAsFixed(1)})",
style: const TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
],
),
const SizedBox(height: 8),
// Brand
Text(
"By ${product['brand']}",
style: const TextStyle(
color: Color(0xFF7E7E7E),
fontSize: 14,
),
),
const SizedBox(height: 16),
// Price and Add Button
Row(
children: [
Text(
"\$${product['discountedPrice'].toStringAsFixed(2)}",
style: const TextStyle(
color: Color(0xFF3BB77E),
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 10),
Text(
"\$${product['originalPrice'].toStringAsFixed(1)}",
style: const TextStyle(
color: Colors.grey,
fontSize: 16,
decoration: TextDecoration.lineThrough,
),
),
const Spacer(),
ElevatedButton.icon(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text("Added to cart!"),
backgroundColor: const Color(0xFF3BB77E),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
},
icon: const Icon(Icons.shopping_cart_outlined, size: 20),
label: const Text(
"Add",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFDEF9EC),
foregroundColor: const Color(0xFF3BB77E),
elevation: 0,
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
],
),
],
),
),
],
),
);
}
Widget _buildTimeBox(int value, String label) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 4),
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: Colors.grey.shade200,
width: 1,
),
),
child: Column(
children: [
Text(
value.toString().padLeft(2, '0'),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Color(0xFF3BB77E),
),
),
const SizedBox(height: 2),
Text(
label,
style: const TextStyle(
fontSize: 12,
color: Color(0xFF7E7E7E),
fontWeight: FontWeight.w500,
),
),
],
),
);
}
}