nesward_flutter_app/lib/widgets/top_selling.dart

334 lines
10 KiB
Dart

import 'package:flutter/material.dart';
class TopSellingAndTrending extends StatelessWidget {
const TopSellingAndTrending({super.key});
// Top Selling Products
final List<Map<String, dynamic>> topSellingProducts = const [
{
'name': 'Nestle Original Coffee-Mate Coffee Creamer',
'originalPrice': 33.8,
'discountedPrice': 32.85,
'imageUrl':
'https://nest-frontend-v6.vercel.app/assets/imgs/shop/thumbnail-1.jpg',
},
{
'name': 'Nestle Original Coffee-Mate Coffee Creamer',
'originalPrice': 33.8,
'discountedPrice': 32.85,
'imageUrl':
'https://nest-frontend-v6.vercel.app/assets/imgs/shop/thumbnail-2.jpg',
},
{
'name': 'Nestle Original Coffee-Mate Coffee Creamer',
'originalPrice': 33.8,
'discountedPrice': 32.85,
'imageUrl':
'https://nest-frontend-v6.vercel.app/assets/imgs/shop/thumbnail-3.jpg',
},
];
// Trending Products
final List<Map<String, dynamic>> trendingProducts = const [
{
'name': 'Organic Cage-Free Grade A Large Brown Eggs',
'originalPrice': 33.8,
'discountedPrice': 32.85,
'imageUrl':
'https://nest-frontend-v6.vercel.app/assets/imgs/shop/thumbnail-4.jpg',
},
{
'name': 'Seeds of Change Organic Quinoa, Brown, & Red Rice',
'originalPrice': 33.8,
'discountedPrice': 32.85,
'imageUrl':
'https://nest-frontend-v6.vercel.app/assets/imgs/shop/thumbnail-5.jpg',
},
{
'name': 'Naturally Flavored Cinnamon Vanilla Light Roast Coffee',
'originalPrice': 33.8,
'discountedPrice': 32.85,
'imageUrl':
'https://nest-frontend-v6.vercel.app/assets/imgs/shop/thumbnail-6.jpg',
},
];
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Top Selling Section
_buildSection('Top Selling', topSellingProducts),
const SizedBox(height: 24),
// Newsletter Section
_buildNewsletterSection(),
const SizedBox(height: 32),
// Trending Products Section
_buildSection('Trending Products', trendingProducts),
const SizedBox(height: 80),
],
),
),
);
}
Widget _buildSection(String title, List<Map<String, dynamic>> products) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 24),
Text(
title,
style: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Color(0xFF253D4E),
),
),
const SizedBox(height: 4),
Container(
width: 60,
height: 3,
decoration: BoxDecoration(
color: const Color(0xFF3BB77E),
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 20),
ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: products.length,
separatorBuilder: (context, index) => const SizedBox(height: 16),
itemBuilder: (context, index) {
return _buildProductItem(products[index]);
},
),
],
),
);
}
Widget _buildProductItem(Map<String, dynamic> product) {
return Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey.shade200,
width: 1,
),
),
child: Row(
children: [
// Product Image
Container(
width: 90,
height: 90,
decoration: BoxDecoration(
color: Colors.grey.shade50,
borderRadius: BorderRadius.circular(10),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
product['imageUrl'],
fit: BoxFit.cover,
),
),
),
const SizedBox(width: 16),
// Product Info
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
product['name'],
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Color(0xFF253D4E),
height: 1.4,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 8),
Row(
children: [
Text(
"\$${product['discountedPrice'].toStringAsFixed(2)}",
style: const TextStyle(
color: Color(0xFF3BB77E),
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 8),
Text(
"\$${product['originalPrice'].toStringAsFixed(1)}",
style: TextStyle(
color: Colors.grey.shade500,
fontSize: 14,
decoration: TextDecoration.lineThrough,
),
),
],
),
],
),
),
],
),
);
}
Widget _buildNewsletterSection() {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: const Color(0xFFDEF9EC),
borderRadius: BorderRadius.circular(20),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Stay home & get your daily\nneeds from our shop',
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Color(0xFF253D4E),
height: 1.4,
),
),
const SizedBox(height: 12),
RichText(
text: const TextSpan(
style: TextStyle(
fontSize: 15,
color: Color(0xFF7E7E7E),
),
children: [
TextSpan(text: 'Start Your Daily Shopping with '),
TextSpan(
text: 'Nest Mart',
style: TextStyle(
color: Color(0xFF3BB77E),
fontWeight: FontWeight.w600,
),
),
],
),
),
const SizedBox(height: 20),
Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(50),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: TextField(
decoration: InputDecoration(
hintText: 'Your email address',
hintStyle: TextStyle(
color: Colors.grey.shade400,
fontSize: 15,
),
prefixIcon: Icon(
Icons.send_outlined,
color: Colors.grey.shade400,
size: 20,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 16,
),
),
),
),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF3BB77E),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
horizontal: 28,
vertical: 16,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
),
child: const Text(
'Subscribe',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
),
),
),
],
),
],
),
);
}
}
// Scroll to top button widget (to be added to your main scaffold)
class ScrollToTopButton extends StatelessWidget {
final VoidCallback onPressed;
const ScrollToTopButton({super.key, required this.onPressed});
@override
Widget build(BuildContext context) {
return Positioned(
bottom: 80,
right: 16,
child: FloatingActionButton(
onPressed: onPressed,
backgroundColor: Colors.white,
elevation: 4,
child: const Icon(
Icons.arrow_upward,
color: Color(0xFF253D4E),
),
),
);
}
}