Files
tripz-llc/apps/rider-archive-cubit/lib/core/router.dart
T
Hamza-AyedandClaude Opus 5 9909d9b4c1 chore: أرشفة تطبيقات ولوحات تريبز التي سيحلّ محلها كود سيرو
استكمال قرار 2026-07-27 (كوميت fff76c9 أرشف الباك إند):
  apps/rider          → apps/rider-archive-cubit
  apps/driver         → apps/driver-archive-cubit
  dashboards/admin-web    → dashboards/admin-web-archive
  dashboards/service-web  → dashboards/service-web-archive

إعادة تسمية بلا تعديل محتوى. rider/driver كانا إعادة بناء Cubit مبنية على
عقد NestJS المؤرشف. admin-web و service-web نموذجان بملف HTML واحد (164 و
128 سطراً) — يحلّ محلهما siro_admin و siro_service المكتملان.

يُحمل من المؤرشف ولا يُعاد اكتشافه: عقد map-saas المثبَّت بالتجربة في
apps/rider-archive-cubit/lib/core/api/ (x-api-key ترويسة، reverse مصفوفة،
route في points) ودرس مسار FCM.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 05:12:04 +03:00

124 lines
4.8 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import '../features/auth/cubit/auth_cubit.dart';
import '../features/auth/cubit/auth_state.dart';
import '../features/splash/view/splash_screen.dart';
import '../features/onboarding/view/onboarding_screen.dart';
import '../features/auth/view/phone_screen.dart';
import '../features/auth/view/otp_screen.dart';
import '../features/auth/view/name_screen.dart';
import '../features/home/view/home_screen.dart';
import '../features/home/view/destination_screen.dart';
import '../features/home/view/route_preview_screen.dart';
import '../features/trip/view/trip_tracking_screen.dart';
import '../features/trip/view/trip_invoice_screen.dart';
import '../features/trip/view/rating_screen.dart';
import '../features/home/cubit/home_cubit.dart';
import '../features/home/cubit/destination_cubit.dart';
import '../features/home/cubit/quote_cubit.dart';
import '../features/home/cubit/saved_places_cubit.dart';
import '../features/home/data/models/place_model.dart';
import '../features/home/data/maps_repository.dart';
import '../features/home/data/tariff_repository.dart';
import '../core/storage/saved_places_store.dart';
import '../core/l10n/app_localizations.dart';
import 'di.dart';
GoRouter buildRouter(AuthCubit auth) {
return GoRouter(
initialLocation: '/splash',
refreshListenable: _StreamRefresh(auth.stream),
redirect: (context, state) {
final status = auth.state.status;
final loc = state.matchedLocation;
final onSplash = loc == '/splash';
final onOnboarding = loc == '/onboarding';
final onAuthPages = loc == '/phone' || loc == '/otp' || loc == '/name';
final onNamePage = loc == '/name';
if (status == AuthStatus.authenticated) {
final hasName = auth.state.user?.name != null &&
auth.state.user!.name!.trim().isNotEmpty;
if (!hasName && !onNamePage) return '/name';
if (hasName && onNamePage) return '/home';
if (onAuthPages || onSplash || onOnboarding) return hasName ? '/home' : '/name';
return null;
}
if (onSplash || onOnboarding) return null;
if (status == AuthStatus.codeSent && loc == '/phone') return '/otp';
if (status != AuthStatus.authenticated && !onAuthPages) return '/phone';
return null;
},
routes: [
GoRoute(path: '/splash', builder: (_, __) => const SplashScreen()),
GoRoute(path: '/onboarding', builder: (_, __) => const OnboardingScreen()),
GoRoute(path: '/phone', builder: (_, __) => const PhoneScreen()),
GoRoute(path: '/otp', builder: (_, __) => const OtpScreen()),
GoRoute(path: '/name', builder: (_, __) => const NameScreen()),
GoRoute(
path: '/home',
builder: (_, __) => MultiBlocProvider(
providers: [
BlocProvider(create: (_) => HomeCubit(getIt<MapsRepository>())),
BlocProvider(create: (_) => SavedPlacesCubit(getIt<SavedPlacesStore>())),
],
child: const HomeScreen(),
),
),
GoRoute(
path: '/destination',
builder: (_, state) {
final extra = state.extra as Map<String, dynamic>?;
final currentLocation = extra?['currentLocation'] as LatLng?;
return BlocProvider(
create: (_) => DestinationCubit(getIt<MapsRepository>()),
child: DestinationScreen(currentLocation: currentLocation),
);
},
),
GoRoute(
path: '/route-preview',
builder: (_, state) {
final extra = state.extra as Map<String, dynamic>?;
final pickup = extra?['pickup'] as PlaceModel?;
final destination = extra?['destination'] as PlaceModel?;
if (pickup == null || destination == null) {
return Builder(
builder: (ctx) => Scaffold(
body: Center(
child: Text(AppLocalizations.of(ctx)?.missingDataError ?? ''),
),
),
);
}
return BlocProvider(
create: (_) => QuoteCubit(getIt<TariffRepository>()),
child: RoutePreviewScreen(pickup: pickup, destination: destination),
);
},
),
GoRoute(path: '/trip-tracking', builder: (_, __) => const TripTrackingScreen()),
GoRoute(path: '/trip-invoice', builder: (_, __) => const TripInvoiceScreen()),
GoRoute(path: '/trip-rating', builder: (_, __) => const RatingScreen()),
],
);
}
class _StreamRefresh extends ChangeNotifier {
late final StreamSubscription<dynamic> _sub;
_StreamRefresh(Stream<dynamic> stream) {
notifyListeners();
_sub = stream.asBroadcastStream().listen((_) => notifyListeners());
}
@override
void dispose() {
_sub.cancel();
super.dispose();
}
}