feat: implement splash and onboarding flows, update app assets, and add project design documentation

This commit is contained in:
Hamza-Ayed
2026-07-24 04:15:07 +03:00
parent 9f7bc31408
commit 213b459912
208 changed files with 23801 additions and 1066 deletions
@@ -4,6 +4,7 @@ import '../../../core/l10n/app_localizations.dart';
import 'package:go_router/go_router.dart';
import '../../../core/design/tokens.dart';
import '../../../core/ui/tripz_button.dart';
import '../../../core/ui/tripz_scaffold.dart';
import '../bloc/trip_bloc.dart';
import '../bloc/trip_state.dart';
import '../bloc/trip_event.dart';
@@ -15,94 +16,90 @@ class TripInvoiceScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final cs = Theme.of(context).colorScheme;
return BlocBuilder<TripBloc, TripState>(
builder: (context, state) {
final trip = state.trip;
if (trip == null) {
return Scaffold(
appBar: AppBar(title: Text(l10n.rideCompleted)),
body: const Center(child: CircularProgressIndicator()),
return TripzScaffold(
title: l10n.rideCompleted,
showBackButton: true,
onBack: () => context.go('/home'),
child: const Center(child: CircularProgressIndicator()),
);
}
final fare = trip.fare ?? 0;
final currency = trip.currency ?? 'JOD';
return Scaffold(
appBar: AppBar(
title: Text(l10n.rideCompleted),
automaticallyImplyLeading: false,
),
body: Padding(
padding: const EdgeInsets.all(T.pagePadding),
child: Column(
children: [
// أيقونة النجاح
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: const Icon(Icons.check_circle_rounded, size: 48, color: Colors.green),
return TripzScaffold(
title: l10n.rideCompleted,
showBackButton: false,
child: Column(
children: [
// أيقونة النجاح
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
const SizedBox(height: T.s16),
Text(
l10n.rideCompleted,
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: T.s24),
// تفاصيل الأجرة
Card(
child: Padding(
padding: const EdgeInsets.all(T.pagePadding),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(l10n.fareBreakdown,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
)),
const SizedBox(height: T.s12),
_FareRow(label: l10n.tripFare, value: '$fare $currency'),
if (trip.paymentMethod == 'wallet')
_FareRow(label: l10n.walletPayment, value: l10n.youPaid),
if (trip.paymentMethod == 'cash')
_FareRow(label: l10n.cash, value: l10n.payCash),
const Divider(height: T.s16),
_FareRow(
label: l10n.total,
value: '$fare $currency',
bold: true,
),
],
child: const Icon(Icons.check_circle_rounded, size: 48, color: Colors.green),
),
const SizedBox(height: T.s16),
Text(
l10n.rideCompleted,
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: T.s24),
// تفاصيل الأجرة
Card(
child: Padding(
padding: const EdgeInsets.all(T.pagePadding),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(l10n.fareBreakdown,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
)),
const SizedBox(height: T.s12),
_FareRow(label: l10n.tripFare, value: '$fare $currency'),
if (trip.paymentMethod == 'wallet')
_FareRow(label: l10n.walletPayment, value: l10n.youPaid),
if (trip.paymentMethod == 'cash')
_FareRow(label: l10n.cash, value: l10n.payCash),
const Divider(height: T.s16),
_FareRow(
label: l10n.total,
value: '$fare $currency',
bold: true,
),
],
),
),
),
const Spacer(),
const Spacer(),
// أزرار الإجراءات
TripzButton(
label: l10n.rateYourTrip,
onPressed: () => context.push('/trip-rating'),
),
const SizedBox(height: T.s8),
TextButton(
onPressed: () {
context.read<TripBloc>().add(const TripClear());
context.go('/home');
},
child: Text(l10n.skipRating),
),
],
),
// أزرار الإجراءات
TripzButton(
label: l10n.rateYourTrip,
onPressed: () => context.push('/trip-rating'),
),
const SizedBox(height: T.s8),
TextButton(
onPressed: () {
context.read<TripBloc>().add(const TripClear());
context.go('/home');
},
child: Text(l10n.skipRating),
),
],
),
);
},