Files
tripz-llc/apps/driver/lib/features/home/view/home_screen.dart
T

190 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:driver/core/l10n/app_localizations.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import 'package:driver/core/design/tokens.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:driver/features/home/cubit/driver_cubit.dart';
import 'package:driver/features/offers/bloc/offers_bloc.dart';
import 'widgets/driver_status_indicator.dart';
import 'widgets/trip_offer_card.dart';
import 'dart:async';
/// شاشة السائق الرئيسية — خريطة + مفتاح الاتصال/الانقطاع + overlay العروض.
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final Completer<IntaleqMapController> _mapController = Completer();
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final cs = Theme.of(context).colorScheme;
return Scaffold(
body: Stack(
children: [
// ── الخريطة ──
_buildMap(cs),
// ── شريط الحالة العلوي ──
Positioned(
top: MediaQuery.of(context).padding.top + T.s8,
left: T.s16,
right: T.s16,
child: _buildTopBar(context, l10n, cs),
),
// ── مؤشر حالة السائق ──
Positioned(
bottom: T.s24,
left: T.s16,
right: T.s16,
child: const DriverStatusIndicator(),
),
// ── overlay العروض الواردة ──
const _OffersOverlay(),
],
),
);
}
Widget _buildMap(ColorScheme cs) {
return BlocBuilder<DriverCubit, DriverState>(
builder: (context, state) {
final driverLat = state.profile?.lat ?? 33.3128;
final driverLng = state.profile?.lng ?? 44.3615;
return IntaleqMap(
apiKey: '',
initialCameraPosition: CameraPosition(
target: LatLng(driverLat, driverLng),
zoom: 14,
),
myLocationEnabled: true,
myLocationButtonEnabled: false,
zoomControlsEnabled: false,
onMapCreated: (controller) {
if (!_mapController.isCompleted) {
_mapController.complete(controller);
}
},
);
},
);
}
Widget _buildTopBar(BuildContext context, AppLocalizations l10n, ColorScheme cs) {
return SafeArea(
child: Row(
children: [
// زر القائمة
Container(
decoration: BoxDecoration(
color: cs.surface,
borderRadius: BorderRadius.circular(T.rCircle),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.08),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: IconButton(
icon: const Icon(Icons.menu_rounded),
onPressed: () {
// TODO: Q4 drawer
},
),
),
const Spacer(),
// معلومات السائق
Container(
padding: const EdgeInsets.symmetric(
horizontal: T.s12,
vertical: T.s8,
),
decoration: BoxDecoration(
color: cs.surface,
borderRadius: BorderRadius.circular(T.r12),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.08),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [
Icon(Icons.star_rounded, size: 18, color: Colors.amber[600]),
const SizedBox(width: T.s4),
Text(
'${context.read<DriverCubit>().state.profile?.rating?.toStringAsFixed(1) ?? "-"}',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w600,
),
),
],
),
),
],
),
);
}
}
/// overlay يعرض العروض الواردة كبطاقات في أسفل الشاشة.
class _OffersOverlay extends StatelessWidget {
const _OffersOverlay();
@override
Widget build(BuildContext context) {
return BlocBuilder<OffersBloc, OffersState>(
builder: (context, state) {
if (!state.hasOffers) return const SizedBox.shrink();
return Positioned(
bottom: 100,
left: T.s16,
right: T.s16,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// عدد العروض
if (state.offers.length > 1)
Container(
margin: const EdgeInsets.only(bottom: T.s8),
padding: const EdgeInsets.symmetric(
horizontal: T.s12,
vertical: T.s4,
),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.circular(T.rCircle),
),
child: Text(
'${state.offers.length} ${AppLocalizations.of(context)!.offersAvailable}',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onPrimary,
fontWeight: FontWeight.w600,
),
),
),
// العرض الأحدث
TripOfferCard(offer: state.offers.first),
],
),
);
},
);
}
}