Files
be_happy_public/lib/presentation/screens/subscription_details_screen.dart
2026-05-12 12:02:40 +03:00

229 lines
6.6 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import '../components/app_checkbox.dart';
import '../components/gradient_button.dart';
import '../components/period_selector.dart';
import '../event/subscription_details_event.dart';
import '../state/susbcription_details_state.dart';
import '../viewmodel/susbcription_details_bloc.dart';
class SubscriptionDetailsScreen extends StatelessWidget {
final int subscriptionId;
const SubscriptionDetailsScreen({super.key, required this.subscriptionId});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF1A2355),
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
onPressed: () => context.pop(),
),
title: BlocBuilder<SubscriptionDetailsBloc, SubscriptionDetailsState>(
builder: (context, state) {
if (state is DetailsContentState) {
return Text(state.subscription.title);
}
return const Text("Загрузка...");
},
),
),
body: Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Opacity(
opacity: 0.5,
child: Image.asset('assets/wave.png'),
),
),
BlocBuilder<SubscriptionDetailsBloc, SubscriptionDetailsState>(
builder: (context, state) {
if (state is DetailsLoading) {
return const Center(
child: CircularProgressIndicator(color: Color(0xFF80FFD1)),
);
}
if (state is DetailsError) {
return Center(
child: Text(
state.message,
style: const TextStyle(color: Colors.white),
),
);
}
if (state is DetailsContentState) {
return _buildContent(context, state);
}
return const SizedBox();
},
),
],
)
);
}
Widget _buildContent(BuildContext context, DetailsContentState state) {
return SingleChildScrollView(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
state.subscription.fullDescription,
style: const TextStyle(
color: Colors.white,
fontSize: 15,
height: 1.5,
),
),
const SizedBox(height: 30),
_ActionCard(state: state),
const SizedBox(height: 30),
GradientButton(
text: 'Активировать',
onTap: () => context.read<SubscriptionDetailsBloc>().add(
ActivateSubscriptionPressed(),
),
width: double.infinity,
height: 56,
fontSize: 16,
showArrows: true,
),
],
),
);
}
}
class _ActionCard extends StatelessWidget {
final DetailsContentState state;
const _ActionCard({required this.state});
@override
Widget build(BuildContext context) {
final List<String> periodTitles = state.subscription.options
.map((e) => e.title)
.toList();
final int selectedIndex = state.subscription.options.indexOf(
state.selectedPeriod,
);
context.read<SubscriptionDetailsBloc>().add(
SelectPeriodEvent(state.subscription.options[selectedIndex]));
return Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: const Color(0xFF131B47),
borderRadius: BorderRadius.circular(30),
border: Border.all(color: Colors.white.withOpacity(0.1)),
),
child: Column(
children: [
const Text(
"Выберите период действия",
style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
),
const SizedBox(height: 20),
PeriodSelector(
periods: periodTitles,
currentIndex: selectedIndex != -1 ? selectedIndex : 0,
onSelect: (index) {
final selectedOption = state.subscription.options[index];
context.read<SubscriptionDetailsBloc>().add(
SelectPeriodEvent(selectedOption),
);
},
),
const SizedBox(height: 30),
_PriceRow(price: state.selectedPeriod.pricePrint),
const SizedBox(height: 20),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppCheckbox(
value: state.isAgreed,
onChanged: (bool? value) {
if (value != null) {
context.read<SubscriptionDetailsBloc>().add(
ToggleAgreementEvent(value),
);
}
},
),
const SizedBox(width: 12),
const Flexible(
child: Text(
'Я подтверждаю, что ознакомился со всеми условиями предоставления подписки и принимаю их безоговорочно',
style: TextStyle(color: Colors.white70, fontSize: 12),
),
),
],
),
],
),
);
}
}
class _PriceRow extends StatelessWidget {
final String price;
const _PriceRow({required this.price});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.05),
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset("assets/icons/money_icon.png", width: 72, height: 72),
SizedBox(width: 15),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Стоимость:", style: TextStyle(color: Color(0xFF80FFD1))),
Text(
price,
style: const TextStyle(
color: Color(0xFF80FFD1),
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
);
}
}