You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

409 lines
14 KiB

import 'package:flutter/material.dart';
import 'package:supplier_new/common/settings.dart';
void main() => runApp(const MaterialApp(home: ResourcesScreen()));
class ResourcesScreen extends StatefulWidget {
const ResourcesScreen({super.key});
@override
State<ResourcesScreen> createState() => _ResourcesScreenState();
}
class _ResourcesScreenState extends State<ResourcesScreen> {
int selectedTab = 0;
String search = '';
final List<Map<String, dynamic>> items = [
{
'title': 'Tanker Name',
'subtitle': 'Drinking water - 10,000 L',
'status': ['filled', 'available'],
'code': 'TS 07 J 3492',
'owner': 'Ramesh Krishna'
},
{
'title': 'Drinking Water - 15,000L',
'subtitle': 'Drinking water - 15,000 L',
'status': ['empty', 'available'],
'code': 'TS 07 J 3492',
'owner': 'Ramesh Krishna'
},
{
'title': 'Tanker Name',
'subtitle': 'Drinking water - 10,000 L',
'status': ['filled', 'in-use'],
'code': 'TS 07 J 3492',
'owner': 'Ramesh Krishna'
},
{
'title': 'Drinking Water - 15,000L',
'subtitle': 'Drinking water - 15,000 L',
'status': ['empty', 'in-use'],
'code': 'TS 07 J 3492',
'owner': 'Ramesh Krishna'
},
{
'title': 'Tanker Name',
'subtitle': 'Drinking water - 10,000 L',
'status': ['filled', 'maintenance'],
'code': 'TS 07 J 3492',
'owner': 'Ramesh Krishna'
},
];
@override
Widget build(BuildContext context) {
final filtered = items.where((it) {
final q = search.trim().toLowerCase();
if (q.isEmpty) return true;
return it['title'].toLowerCase().contains(q) ||
it['subtitle'].toLowerCase().contains(q) ||
it['owner'].toLowerCase().contains(q);
}).toList();
return Scaffold(
backgroundColor: const Color(0xFFF6F6F7),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0.7,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black87),
onPressed: () => Navigator.of(context).maybePop(),
),
title: Text(
'Resources',
style: fontTextStyle(16, const Color(0xFF2A2A2A), FontWeight.w600),
),
centerTitle: false,
actions: [
TextButton(
onPressed: () {},
child: Text('HELP', style: fontTextStyle(12, const Color(0xFF8270DB), FontWeight.w600)),
),
],
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Segmented tabs
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: const Color(0xFFF1F1F3),
borderRadius: BorderRadius.circular(24),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(3, (i) {
final labels = ['Fleet', 'Drivers', 'Sources'];
final isSelected = selectedTab == i;
return GestureDetector(
onTap: () => setState(() => selectedTab = i),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration(
color: isSelected ? Colors.white : Colors.transparent,
borderRadius: BorderRadius.circular(20),
),
child: Text(
labels[i],
style: TextStyle(
color: isSelected ? Colors.black87 : Colors.grey.shade700,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500,
),
),
),
);
}),
),
),
const SizedBox(height: 16),
// Summary card and small stats row
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Big card
Expanded(
flex: 2,
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 6, offset: const Offset(0, 3))
],
),
child: Row(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: const Color(0xFFF6F0FF),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(Icons.local_shipping_outlined, color: Color(0xFF6F5FBA)),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text('Total Tankers', style: TextStyle(fontSize: 14, color: Colors.black87)),
SizedBox(height: 6),
Text('14', style: TextStyle(fontSize: 28, fontWeight: FontWeight.w700, color: Color(0xFF173F5F))),
SizedBox(height: 2),
Text('+2 since last month', style: TextStyle(fontSize: 12, color: Colors.grey)),
],
),
),
],
),
),
),
const SizedBox(width: 12),
// Small stat cards
Expanded(
flex: 1,
child: Column(
children: [
StatCard(title: 'Active', value: '2'),
const SizedBox(height: 8),
StatCard(title: 'Inactive', value: '3'),
const SizedBox(height: 8),
StatCard(title: 'Under\nMaintenances', value: '1'),
],
),
)
],
),
const SizedBox(height: 16),
// Search and filter row
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: [
const Icon(Icons.search, color: Colors.grey),
const SizedBox(width: 8),
Expanded(
child: TextField(
decoration: const InputDecoration(
hintText: 'Search',
border: InputBorder.none,
isDense: true,
),
onChanged: (v) => setState(() => search = v),
),
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.filter_list, color: Colors.grey),
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.swap_vert, color: Colors.grey),
)
],
),
),
const SizedBox(height: 12),
// List
Expanded(
child: ListView.separated(
itemCount: filtered.length,
separatorBuilder: (_, __) => const SizedBox(height: 10),
itemBuilder: (context, idx) {
final it = filtered[idx];
return TankCard(
title: it['title'],
subtitle: it['subtitle'],
code: it['code'],
owner: it['owner'],
status: List<String>.from(it['status']),
);
},
),
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: const Color(0xFF2E2B5F),
child: const Icon(Icons.add),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: 0,
selectedItemColor: const Color(0xFF6F5FBA),
unselectedItemColor: Colors.grey,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home_outlined), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.receipt_long_outlined), label: 'Orders'),
BottomNavigationBarItem(icon: Icon(Icons.calendar_month), label: 'Plans'),
BottomNavigationBarItem(icon: Icon(Icons.group_outlined), label: 'Resources'),
BottomNavigationBarItem(icon: Icon(Icons.menu), label: 'More'),
],
),
);
}
}
class StatCard extends StatelessWidget {
final String title;
final String value;
const StatCard({super.key, required this.title, required this.value});
@override
Widget build(BuildContext context) {
return Container(
height: 58,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.grey.shade200),
),
child: Row(
children: [
Expanded(child: Text(title, style: const TextStyle(fontSize: 13, color: Colors.black87))),
Text(value, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w700, color: Color(0xFF173F5F))),
],
),
);
}
}
class TankCard extends StatelessWidget {
final String title;
final String subtitle;
final String code;
final String owner;
final List<String> status;
const TankCard({
super.key,
required this.title,
required this.subtitle,
required this.code,
required this.owner,
required this.status,
});
Color _chipColor(String s) {
switch (s) {
case 'filled':
return const Color(0xFFE8F7F1);
case 'available':
return const Color(0xFFE8F0FF);
case 'empty':
return const Color(0xFFFFEEEE);
case 'in-use':
return const Color(0xFFFFF0E6);
case 'maintenance':
return const Color(0xFFFFF4E6);
default:
return const Color(0xFFECECEC);
}
}
Color _chipTextColor(String s) {
switch (s) {
case 'filled':
return Colors.green.shade700;
case 'available':
return const Color(0xFF2E2B5F);
case 'empty':
return Colors.red.shade600;
case 'in-use':
return Colors.orange.shade700;
case 'maintenance':
return Colors.orange.shade700;
default:
return Colors.black87;
}
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey.shade100),
),
child: Row(
children: [
// left column: chips + texts
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// chips
Row(
children: status.map((s) {
return Container(
margin: const EdgeInsets.only(right: 6),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: _chipColor(s),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey.withOpacity(0.12)),
),
child: Text(
s,
style: TextStyle(fontSize: 11, fontWeight: FontWeight.w600, color: _chipTextColor(s)),
),
);
}).toList(),
),
const SizedBox(height: 8),
Text(title, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w700)),
const SizedBox(height: 6),
Text(subtitle, style: const TextStyle(fontSize: 13, color: Colors.grey)),
const SizedBox(height: 10),
Row(
children: [
CircleAvatar(radius: 10, backgroundColor: const Color(0xFFEEF5FF), child: const Icon(Icons.person, size: 12, color: Color(0xFF6F5FBA))),
const SizedBox(width: 6),
Expanded(child: Text(owner, style: const TextStyle(fontSize: 12, color: Colors.grey))),
],
),
],
),
),
// right column: code
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(code, style: const TextStyle(fontSize: 12, color: Colors.grey)),
const SizedBox(height: 28),
],
),
],
),
);
}
}