|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
|
import 'package:watermanagement/supplier/todaysprice/graph_data2.dart';
|
|
|
|
|
|
import '../../common/settings.dart';
|
|
|
|
|
|
|
|
|
class TodaysPriceMainScreen extends StatefulWidget {
|
|
|
const TodaysPriceMainScreen({super.key});
|
|
|
|
|
|
@override
|
|
|
State<TodaysPriceMainScreen> createState() => _TodaysPriceMainScreenState();
|
|
|
}
|
|
|
|
|
|
class _TodaysPriceMainScreenState extends State<TodaysPriceMainScreen> {
|
|
|
int selectedType = 0;
|
|
|
late PageController waterController;
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
|
super.initState();
|
|
|
waterController = PageController();
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
void dispose() {
|
|
|
waterController.dispose();
|
|
|
super.dispose();
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
return Scaffold(
|
|
|
backgroundColor: Colors.black,
|
|
|
appBar: AppBar(
|
|
|
backgroundColor: Colors.white,
|
|
|
elevation: 3,
|
|
|
|
|
|
leading: Padding(
|
|
|
padding: const EdgeInsets.only(left: 10),
|
|
|
child: GestureDetector(
|
|
|
onTap: () => Navigator.pop(context),
|
|
|
child: Container(
|
|
|
padding: const EdgeInsets.all(6),
|
|
|
child: const Icon(Icons.arrow_back_ios_new,
|
|
|
size: 18, color: Colors.black
|
|
|
),
|
|
|
),
|
|
|
),
|
|
|
),
|
|
|
|
|
|
title: Text(
|
|
|
"Today's Prices",
|
|
|
style: fontTextStyle(20, Colors.black, FontWeight.w600),
|
|
|
),
|
|
|
),
|
|
|
|
|
|
body: Column(
|
|
|
children: [
|
|
|
// TOP CARD WITH CHART (80% height)
|
|
|
Container(
|
|
|
height: MediaQuery.of(context).size.height* 0.38,
|
|
|
width: double.infinity,
|
|
|
decoration: BoxDecoration(
|
|
|
color: Colors.white,
|
|
|
borderRadius: const BorderRadius.only(
|
|
|
bottomLeft: Radius.circular(30),
|
|
|
bottomRight: Radius.circular(30)
|
|
|
)
|
|
|
),
|
|
|
|
|
|
child: Column(
|
|
|
children: [
|
|
|
|
|
|
// DOUBLE BAR GRAPH
|
|
|
Expanded(
|
|
|
child: Padding(
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
|
|
child: GraphScreen(selectedType: selectedType),
|
|
|
),
|
|
|
),
|
|
|
|
|
|
const SizedBox(height: 1),
|
|
|
|
|
|
// LEGEND
|
|
|
buildLegend(),
|
|
|
const SizedBox(height: 10),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
|
|
|
const SizedBox(height: 15),
|
|
|
|
|
|
// ------------ WATER TABS ------------
|
|
|
Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
children: [
|
|
|
waterTab(0),
|
|
|
const SizedBox(width: 20),
|
|
|
waterTab(1),
|
|
|
],
|
|
|
),
|
|
|
const SizedBox(height: 10),
|
|
|
|
|
|
// ----------- PAGE VIEW – SWIPE FOR BOTH -----------
|
|
|
Expanded(
|
|
|
child: PageView.builder(
|
|
|
itemCount: 2, // 0 = Drinking, 1 = Bore
|
|
|
controller: waterController, // 🔥 added controller
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
onPageChanged: (i) => setState(() => selectedType = i),
|
|
|
itemBuilder: (context, pageIndex) {
|
|
|
final title = pageIndex == 0 ? "Drinking Water" : "Bore Water";
|
|
|
final list = pageIndex == 0
|
|
|
? drinkingWaterSuppliers
|
|
|
: boreWaterSuppliers;
|
|
|
|
|
|
return Stack(
|
|
|
children: [
|
|
|
// SCROLLING SUPPLIER LIST UNDER WATER CARD
|
|
|
Positioned.fill(
|
|
|
child: ListView.builder(
|
|
|
padding: EdgeInsets.only(top: 150),
|
|
|
itemCount: list.length,
|
|
|
itemBuilder: (context, i) {
|
|
|
final s = list[i];
|
|
|
return Padding(
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
|
|
child: SupplierCard(
|
|
|
name: s["name"]!,
|
|
|
distance: s["distance"]!,
|
|
|
rating: s["rating"]!,
|
|
|
reviews: s["reviews"]!,
|
|
|
price: s["price"]!,
|
|
|
),
|
|
|
);
|
|
|
},
|
|
|
),
|
|
|
),
|
|
|
|
|
|
// WATER CARD FIXED ON TOP
|
|
|
Positioned(
|
|
|
top: 0,
|
|
|
left: 25,
|
|
|
right: 25,
|
|
|
child: WaterCard(
|
|
|
title: selectedType == 0 ? "Drinking Water" : "Bore Water",
|
|
|
priceRange: selectedType == 0
|
|
|
? "₹1,575 – ₹1,700"
|
|
|
: "₹740 – ₹850",
|
|
|
),
|
|
|
)
|
|
|
],
|
|
|
);
|
|
|
|
|
|
}
|
|
|
)
|
|
|
)
|
|
|
],
|
|
|
)
|
|
|
);
|
|
|
}
|
|
|
|
|
|
Widget waterTab(int i) {
|
|
|
return GestureDetector(
|
|
|
onTap: () {
|
|
|
waterController.animateToPage(
|
|
|
i,
|
|
|
duration: const Duration(milliseconds: 250),
|
|
|
curve: Curves.easeInOut,
|
|
|
);
|
|
|
setState(() => selectedType = i);
|
|
|
},
|
|
|
child: AnimatedContainer(
|
|
|
duration: const Duration(milliseconds: 250),
|
|
|
width: 160,
|
|
|
height: 4,
|
|
|
decoration: BoxDecoration(
|
|
|
color: selectedType == i ? Colors.white : Colors.white24,
|
|
|
borderRadius: BorderRadius.circular(10),
|
|
|
),
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
class WaterSection extends StatefulWidget {
|
|
|
final Function(int) onTabChanged;
|
|
|
|
|
|
const WaterSection({super.key, required this.onTabChanged});
|
|
|
|
|
|
@override
|
|
|
State<WaterSection> createState() => _WaterSectionState();
|
|
|
}
|
|
|
|
|
|
class _WaterSectionState extends State<WaterSection> {
|
|
|
final PageController controller = PageController();
|
|
|
int index = 0;
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
return Column(
|
|
|
children: [
|
|
|
// ------------ TABS ------------
|
|
|
Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
children: [
|
|
|
tabBar(0),
|
|
|
const SizedBox(width: 20),
|
|
|
tabBar(1),
|
|
|
],
|
|
|
),
|
|
|
|
|
|
// const SizedBox(height: 20),
|
|
|
|
|
|
// ------------ PAGE VIEW ------------
|
|
|
Expanded(
|
|
|
child: Padding(
|
|
|
padding: EdgeInsets.only(top: 10),
|
|
|
child: PageView(
|
|
|
controller: controller,
|
|
|
onPageChanged: (i) {
|
|
|
setState(() => index = i);
|
|
|
widget.onTabChanged(i); // 🔥 send tab index to parent
|
|
|
},
|
|
|
children: const [
|
|
|
WaterCard(
|
|
|
title: "Drinking Water",
|
|
|
priceRange: "₹1,200 – ₹1,500",
|
|
|
),
|
|
|
WaterCard(
|
|
|
title: "Bore Water",
|
|
|
priceRange: "₹740 – ₹850",
|
|
|
),
|
|
|
],
|
|
|
|
|
|
),
|
|
|
),
|
|
|
)
|
|
|
],
|
|
|
);
|
|
|
}
|
|
|
|
|
|
// ---------------- TAB BAR ---------------
|
|
|
Widget tabBar(int i) {
|
|
|
return GestureDetector(
|
|
|
onTap: () {
|
|
|
controller.animateToPage(
|
|
|
i,
|
|
|
duration: const Duration(milliseconds: 250),
|
|
|
curve: Curves.easeInOut,
|
|
|
);
|
|
|
setState(() => index = i);
|
|
|
widget.onTabChanged(i); // 🔥 send index
|
|
|
},
|
|
|
child: AnimatedContainer(
|
|
|
duration: const Duration(milliseconds: 250),
|
|
|
width: 160,
|
|
|
height: 4,
|
|
|
decoration: BoxDecoration(
|
|
|
color: index == i ? Colors.white : Colors.white24,
|
|
|
borderRadius: BorderRadius.circular(10),
|
|
|
),
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class WaterCard extends StatelessWidget {
|
|
|
final String title;
|
|
|
final String priceRange;
|
|
|
final String volume;
|
|
|
|
|
|
const WaterCard({
|
|
|
super.key,
|
|
|
required this.title,
|
|
|
required this.priceRange,
|
|
|
this.volume = "/5,000L", // Default value
|
|
|
});
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
return Container(
|
|
|
margin: const EdgeInsets.symmetric(horizontal: 6),
|
|
|
padding: const EdgeInsets.all(18),
|
|
|
height: 130,
|
|
|
width: 350,
|
|
|
decoration: BoxDecoration(
|
|
|
color: const Color(0xFF2E2E2E),
|
|
|
borderRadius: BorderRadius.circular(18),
|
|
|
boxShadow: [
|
|
|
BoxShadow(
|
|
|
color: Colors.black.withOpacity(0.25),
|
|
|
blurRadius: 8,
|
|
|
offset: const Offset(0, 3),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
child: Column(
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
children: [
|
|
|
Text(
|
|
|
title,
|
|
|
style: fontTextStyle(16, Colors.white.withOpacity(0.8), FontWeight.w600),
|
|
|
),
|
|
|
|
|
|
const SizedBox(height: 6),
|
|
|
|
|
|
Text(
|
|
|
priceRange,
|
|
|
style: fontTextStyle(26, Colors.white, FontWeight.w700),
|
|
|
),
|
|
|
|
|
|
const SizedBox(height: 4),
|
|
|
|
|
|
Text(
|
|
|
volume,
|
|
|
style: fontTextStyle(14, Colors.white54, FontWeight.w400),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
final List<Map<String, String>> drinkingWaterSuppliers = [
|
|
|
{
|
|
|
"name": "Balaji Suppliers",
|
|
|
"distance": "2.5 km",
|
|
|
"rating": "4.2",
|
|
|
"reviews": "20k+",
|
|
|
"price": "₹1575"
|
|
|
},
|
|
|
{
|
|
|
"name": "Manikanta Water",
|
|
|
"distance": "4.2 km",
|
|
|
"rating": "4.5",
|
|
|
"reviews": "18k+",
|
|
|
"price": "₹1650"
|
|
|
},
|
|
|
{
|
|
|
"name": "Sai Durga Water",
|
|
|
"distance": "3.1 km",
|
|
|
"rating": "4.1",
|
|
|
"reviews": "25k+",
|
|
|
"price": "₹1500"
|
|
|
},
|
|
|
{
|
|
|
"name": "Tirupati Suppliers",
|
|
|
"distance": "1.5 km",
|
|
|
"rating": "4.2",
|
|
|
"reviews": "20k+",
|
|
|
"price": "₹1500"
|
|
|
},
|
|
|
];
|
|
|
|
|
|
final List<Map<String, String>> boreWaterSuppliers = [
|
|
|
{
|
|
|
"name": "Green Borewell",
|
|
|
"distance": "3.4 km",
|
|
|
"rating": "4.0",
|
|
|
"reviews": "12k+",
|
|
|
"price": "₹799"
|
|
|
},
|
|
|
{
|
|
|
"name": "Crystal Bore Water",
|
|
|
"distance": "5.1 km",
|
|
|
"rating": "4.3",
|
|
|
"reviews": "9k+",
|
|
|
"price": "₹850"
|
|
|
},
|
|
|
{
|
|
|
"name": "PureDrop Bore",
|
|
|
"distance": "2.8 km",
|
|
|
"rating": "4.1",
|
|
|
"reviews": "14k+",
|
|
|
"price": "₹820"
|
|
|
},
|
|
|
{
|
|
|
"name": "Blue Borewell",
|
|
|
"distance": "4.4 km",
|
|
|
"rating": "4.3",
|
|
|
"reviews": "10k+",
|
|
|
"price": "₹899"
|
|
|
},
|
|
|
];
|
|
|
|
|
|
|
|
|
class SupplierCard extends StatelessWidget {
|
|
|
final String name;
|
|
|
final String distance;
|
|
|
final String rating;
|
|
|
final String reviews;
|
|
|
final String price;
|
|
|
|
|
|
const SupplierCard({
|
|
|
super.key,
|
|
|
required this.name,
|
|
|
required this.distance,
|
|
|
required this.rating,
|
|
|
required this.reviews,
|
|
|
required this.price,
|
|
|
});
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
return Container(
|
|
|
margin: const EdgeInsets.symmetric(horizontal: 14, vertical: 6),
|
|
|
padding: const EdgeInsets.all(14),
|
|
|
decoration: BoxDecoration(
|
|
|
color: const Color(0xFFF2F2F2).withOpacity(0.2), // light grey
|
|
|
borderRadius: BorderRadius.circular(22),
|
|
|
border: Border.all(color: Colors.black12, width: 1),
|
|
|
),
|
|
|
|
|
|
child: Row(
|
|
|
children: [
|
|
|
// Avatar
|
|
|
const CircleAvatar(
|
|
|
radius: 22,
|
|
|
backgroundColor: Colors.white,
|
|
|
child: Icon(Icons.person, color: Colors.grey),
|
|
|
),
|
|
|
|
|
|
const SizedBox(width: 12),
|
|
|
|
|
|
// Name + Location
|
|
|
Expanded(
|
|
|
child: Column(
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
children: [
|
|
|
Text(
|
|
|
name,
|
|
|
style: fontTextStyle(17, Colors.white.withOpacity(0.95), FontWeight.w700),
|
|
|
),
|
|
|
const SizedBox(height: 4),
|
|
|
Text(
|
|
|
"Location: $distance",
|
|
|
style: fontTextStyle(12, Colors.white, FontWeight.w500),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
|
|
|
// Rating badge + Price
|
|
|
Column(
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
children: [
|
|
|
Container(
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3),
|
|
|
decoration: BoxDecoration(
|
|
|
color: Colors.white,
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
),
|
|
|
child: Row(
|
|
|
children: [
|
|
|
const Icon(Icons.star, color: Colors.amber, size: 14),
|
|
|
Text(
|
|
|
" $rating (${reviews})",
|
|
|
style: fontTextStyle(12, Colors.black87, FontWeight.w600),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
|
|
|
const SizedBox(height: 10),
|
|
|
|
|
|
Text(
|
|
|
price,
|
|
|
style: fontTextStyle(18, Colors.white.withOpacity(0.95), FontWeight.w700),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
}
|