taxgilde/lib/consts/home_page_headers.dart
2026-04-11 10:21:31 +05:30

263 lines
9.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_riverpod/legacy.dart';
import 'package:get/get.dart';
import 'package:taxglide/consts/app_asstes.dart';
import 'package:taxglide/view/screens/notification_screen.dart';
import 'package:taxglide/controller/api_contoller.dart';
final serviceSearchProvider = StateProvider<String>((ref) => "");
class HomePageHeader extends ConsumerWidget {
final String userName;
const HomePageHeader({super.key, required this.userName});
@override
Widget build(BuildContext context, WidgetRef ref) {
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
final headerHeight = screenHeight * 0.21;
final profileSize = screenWidth * 0.14;
final iconSize = screenWidth * 0.07;
final horizontalPadding = screenWidth * 0.04;
final searchBoxHeight = screenHeight * 0.07;
final welcomeFontSize = screenWidth * 0.035;
final userFontSize = screenWidth * 0.045;
final initialFontSize = screenWidth * 0.045;
// 🔴 Fetch Notification Count
final notifCountAsync = ref.watch(notificationCountProvider);
// 🔴 Fetch Profile Data for Image
final profileAsync = ref.watch(profileProvider);
return Stack(
clipBehavior: Clip.none,
children: [
// Background Header
ClipRRect(
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
),
child: Image.asset(
AppAssets.homepageheader,
width: double.infinity,
height: headerHeight,
fit: BoxFit.cover,
),
),
// Profile + Welcome + Notification Icon
Positioned(
top: headerHeight * 0.15,
left: horizontalPadding,
right: horizontalPadding,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Profile Avatar
profileAsync.when(
data: (profileModel) {
final String? logoUrl = profileModel.data?.logo;
if (logoUrl != null && logoUrl.isNotEmpty) {
return Container(
width: profileSize,
height: profileSize,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 2),
image: DecorationImage(
image: NetworkImage(logoUrl),
fit: BoxFit.cover,
),
),
);
}
// Fallback to initial
return Container(
width: profileSize,
height: profileSize,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.8),
border: Border.all(color: Colors.white, width: 2),
),
child: Center(
child: Text(
userName.isNotEmpty ? userName[0].toUpperCase() : "M",
style: TextStyle(
color: Colors.white,
fontSize: initialFontSize,
fontWeight: FontWeight.bold,
),
),
),
);
},
loading: () => Container(
width: profileSize,
height: profileSize,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey[300],
border: Border.all(color: Colors.white, width: 2),
),
),
error: (e, st) => Container(
width: profileSize,
height: profileSize,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.8),
border: Border.all(color: Colors.white, width: 2),
),
child: Center(
child: Text(
userName.isNotEmpty ? userName[0].toUpperCase() : "M",
style: TextStyle(
color: Colors.white,
fontSize: initialFontSize,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(width: screenWidth * 0.03),
// Welcome & Username
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Welcome to TaxGlide",
style: TextStyle(
color: Colors.black,
fontSize: welcomeFontSize,
fontWeight: FontWeight.w400,
),
),
Text(
userName,
style: TextStyle(
color: Colors.black,
fontSize: userFontSize,
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
),
],
),
),
// Notifications with Badge
GestureDetector(
onTap: () => Get.to(NotificationScreen()),
child: Stack(
clipBehavior: Clip.none,
children: [
Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
),
padding: EdgeInsets.all(screenWidth * 0.025),
child: Icon(
Icons.notifications,
color: Colors.white,
size: iconSize,
),
),
// 🔴 Notification Badge
Positioned(
right: -2,
top: -2,
child: notifCountAsync.when(
loading: () => const SizedBox.shrink(),
error: (e, st) => const SizedBox.shrink(),
data: (count) {
if (count.count == 0) {
return const SizedBox.shrink();
}
return Container(
padding: const EdgeInsets.all(4),
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text(
count.count.toString(),
style: const TextStyle(
fontSize: 10,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
);
},
),
),
],
),
),
],
),
),
// Search Bar
Positioned(
top: headerHeight - (searchBoxHeight * 0.6),
left: screenWidth * 0.05,
right: screenWidth * 0.05,
child: Container(
height: searchBoxHeight,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(50),
border: Border.all(color: const Color(0xFFE4E4E4), width: 1),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 6,
offset: const Offset(0, 2),
),
],
),
child: TextField(
textAlign: TextAlign.start, // ✅ Start (left) alignment
style: TextStyle(fontSize: screenWidth * 0.04),
onChanged: (value) {
ref.read(serviceSearchProvider.notifier).state = value;
},
decoration: InputDecoration(
hintText: "Search services...",
hintStyle: TextStyle(
color: Colors.grey,
fontSize: screenWidth * 0.04,
),
prefixIcon: Icon(
Icons.search,
color: Colors.black54,
size: screenWidth * 0.06,
),
border: InputBorder.none,
// ✅ Only vertical center
contentPadding: EdgeInsets.symmetric(
vertical: searchBoxHeight * 0.3,
),
),
),
),
),
],
);
}
}