Files
unionflow-mobile-apps/lib/features/onboarding/presentation/pages/onboarding_flow_page.dart
2026-03-31 09:14:47 +00:00

150 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../bloc/onboarding_bloc.dart';
import '../../../../core/di/injection.dart';
import 'plan_selection_page.dart';
import 'period_selection_page.dart';
import 'subscription_summary_page.dart';
import 'wave_payment_page.dart';
import 'awaiting_validation_page.dart';
/// Page conteneur du workflow d'onboarding.
/// Reçoit l'état initial du backend (onboardingState) et dispatch au bon écran.
class OnboardingFlowPage extends StatelessWidget {
final String onboardingState;
final String? souscriptionId;
final String organisationId;
const OnboardingFlowPage({
super.key,
required this.onboardingState,
required this.organisationId,
this.souscriptionId,
});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => getIt<OnboardingBloc>()
..add(OnboardingStarted(
initialState: onboardingState,
existingSouscriptionId: souscriptionId,
)),
child: const _OnboardingFlowView(),
);
}
}
class _OnboardingFlowView extends StatelessWidget {
const _OnboardingFlowView();
@override
Widget build(BuildContext context) {
return BlocBuilder<OnboardingBloc, OnboardingState>(
builder: (context, state) {
if (state is OnboardingLoading || state is OnboardingInitial) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}
if (state is OnboardingError) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.error_outline, size: 64, color: Colors.red),
const SizedBox(height: 16),
Text(state.message, textAlign: TextAlign.center),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () => context.read<OnboardingBloc>().add(
OnboardingStarted(initialState: 'NO_SUBSCRIPTION'),
),
child: const Text('Réessayer'),
),
],
),
),
),
);
}
if (state is OnboardingStepFormule) {
return PlanSelectionPage(formules: state.formules);
}
if (state is OnboardingStepPeriode) {
return PeriodSelectionPage(
codeFormule: state.codeFormule,
plage: state.plage,
formules: state.formules,
);
}
if (state is OnboardingStepSummary) {
return SubscriptionSummaryPage(souscription: state.souscription);
}
if (state is OnboardingStepPaiement) {
return WavePaymentPage(
souscription: state.souscription,
waveLaunchUrl: state.waveLaunchUrl,
);
}
if (state is OnboardingStepAttente) {
return AwaitingValidationPage(souscription: state.souscription);
}
if (state is OnboardingRejected) {
return _RejectedPage(commentaire: state.commentaire);
}
return const Scaffold(body: Center(child: CircularProgressIndicator()));
},
);
}
}
class _RejectedPage extends StatelessWidget {
final String? commentaire;
const _RejectedPage({this.commentaire});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.cancel_outlined, size: 72, color: Colors.red),
const SizedBox(height: 24),
const Text(
'Souscription rejetée',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
if (commentaire != null) ...[
const SizedBox(height: 12),
Text(commentaire!, textAlign: TextAlign.center),
],
const SizedBox(height: 32),
ElevatedButton(
onPressed: () => context.read<OnboardingBloc>().add(
OnboardingStarted(initialState: 'NO_SUBSCRIPTION'),
),
child: const Text('Nouvelle souscription'),
),
],
),
),
),
);
}
}