feature(settings): Верстка экранов настроек
This commit is contained in:
81
lib/screens/settings/states/about.dart
Normal file
81
lib/screens/settings/states/about.dart
Normal file
@@ -0,0 +1,81 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:remever/common/functions.dart';
|
||||
import 'package:remever/common/resources.dart';
|
||||
import 'package:remever/common/widgets/typography.dart';
|
||||
import 'package:remever/common/widgets/wspace.dart';
|
||||
import 'package:remever/components/extensions/context.dart';
|
||||
import 'package:remever/gen/assets.gen.dart';
|
||||
import 'package:remever/screens/settings/cubit/settings_cubit.dart';
|
||||
import 'package:remever/widgets/primary_button.dart';
|
||||
|
||||
class AboutSettingsState extends StatelessWidget {
|
||||
const AboutSettingsState({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bg,
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 66.h,
|
||||
backgroundColor: AppColors.white,
|
||||
shadowColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: AppTypography('О приложении', type: SemiBold20px()),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
context.read<SettingsCubit>().toInitialState();
|
||||
},
|
||||
icon: Icon(CupertinoIcons.left_chevron),
|
||||
color: Colors.black,
|
||||
),
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
showInfoToast('тут будет sharing');
|
||||
},
|
||||
icon: Assets.icons.settingsShare.image(height: 24.h, width: 24.w),
|
||||
color: Colors.black,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16).r,
|
||||
child: Column(
|
||||
children: [
|
||||
Spacer(),
|
||||
Assets.images.logo.image(width: 308.w, height: 100.h),
|
||||
AppTypography(
|
||||
'Версия приложения: 1.10.12\nот 23.05.2025',
|
||||
type: Regular12px(),
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
Spacer(),
|
||||
AppTypography(
|
||||
'Лицензионное соглашение',
|
||||
type: Regular14px(),
|
||||
color: AppColors.primary,
|
||||
),
|
||||
HSpace(10),
|
||||
AppTypography(
|
||||
'Политика конфиденциальности',
|
||||
type: Regular14px(),
|
||||
color: AppColors.primary,
|
||||
),
|
||||
HSpace(60),
|
||||
PrimaryButton(
|
||||
onTap: () {},
|
||||
child: AppTypography(
|
||||
'Обновить приложение',
|
||||
type: Medium14px(),
|
||||
color: AppColors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
92
lib/screens/settings/states/faq.dart
Normal file
92
lib/screens/settings/states/faq.dart
Normal file
@@ -0,0 +1,92 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:remever/common/resources.dart';
|
||||
import 'package:remever/common/typography.dart';
|
||||
import 'package:remever/common/widgets/typography.dart';
|
||||
import 'package:remever/common/widgets/wspace.dart';
|
||||
import 'package:remever/components/extensions/context.dart';
|
||||
import 'package:remever/screens/settings/cubit/settings_cubit.dart';
|
||||
import 'package:remever/widgets/primary_button.dart';
|
||||
|
||||
class FaqSettingsState extends StatelessWidget {
|
||||
const FaqSettingsState({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bg,
|
||||
appBar: _buildAppBar(context),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16).r,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)).r,
|
||||
),
|
||||
child: _buildFaqList(),
|
||||
),
|
||||
),
|
||||
HSpace(16),
|
||||
PrimaryButton(
|
||||
onTap: () {},
|
||||
child: AppTypography(
|
||||
'Задать свой вопрос',
|
||||
type: Medium14px(),
|
||||
color: AppColors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFaqList() {
|
||||
return ListView(
|
||||
children: [
|
||||
_buildExpansion('Есть ли ограничения по количеству коллекций?', 'Нет'),
|
||||
Divider(thickness: 1, height: 1, color: AppColors.bg),
|
||||
_buildExpansion(
|
||||
'Как поделиться коллекцией с друзьями?',
|
||||
'Другу необходимо установить приложение Remever на свой телефон, после этого вы сможете обмениваться друг с другом коллекциями',
|
||||
),
|
||||
Divider(thickness: 1, height: 1, color: AppColors.bg),
|
||||
_buildExpansion('Можно ли пользоваться бесплатно?', 'Пока да'),
|
||||
Divider(thickness: 1, height: 1, color: AppColors.bg),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// AppBar экрана FAQ
|
||||
AppBar _buildAppBar(BuildContext context) {
|
||||
return AppBar(
|
||||
toolbarHeight: 66.h,
|
||||
backgroundColor: AppColors.white,
|
||||
shadowColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: AppTypography('FAQ', type: SemiBold20px()),
|
||||
leading: IconButton(
|
||||
onPressed: () => context.read<SettingsCubit>().toInitialState(),
|
||||
icon: Icon(CupertinoIcons.left_chevron),
|
||||
color: Colors.black,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildExpansion(String title, String answer) {
|
||||
return ExpansionTile(
|
||||
title: AppTypography(title, type: Medium16px(), maxLines: 2),
|
||||
textColor: Colors.black,
|
||||
children: [
|
||||
ListTile(
|
||||
title: AppTypography(answer, type: Regular14px(), maxLines: 99),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
136
lib/screens/settings/states/initial.dart
Normal file
136
lib/screens/settings/states/initial.dart
Normal file
@@ -0,0 +1,136 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:remever/common/functions.dart';
|
||||
import 'package:remever/common/resources.dart';
|
||||
import 'package:remever/common/widgets/typography.dart';
|
||||
import 'package:remever/common/widgets/wspace.dart';
|
||||
import 'package:remever/components/extensions/context.dart';
|
||||
import 'package:remever/gen/assets.gen.dart';
|
||||
import 'package:remever/screens/settings/cubit/settings_cubit.dart';
|
||||
import 'package:remever/widgets/primary_button.dart';
|
||||
|
||||
class InitialSettingsState extends StatelessWidget {
|
||||
const InitialSettingsState({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bg,
|
||||
appBar: _buildAppBar(context),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.all(16.r),
|
||||
child: Column(
|
||||
children: [
|
||||
_buildSettingsItem(
|
||||
context,
|
||||
Assets.icons.settingsProfile,
|
||||
'Профиль',
|
||||
SettingsCubitType.profile,
|
||||
),
|
||||
HSpace(8),
|
||||
_buildSettingsItem(
|
||||
context,
|
||||
Assets.icons.settingsNotification,
|
||||
'Уведомления',
|
||||
SettingsCubitType.notifications,
|
||||
),
|
||||
HSpace(8),
|
||||
_buildSettingsItem(
|
||||
context,
|
||||
Assets.icons.settingsFaq,
|
||||
'FAQ',
|
||||
SettingsCubitType.faq,
|
||||
),
|
||||
HSpace(8),
|
||||
_buildSettingsItem(
|
||||
context,
|
||||
Assets.icons.settingsAbout,
|
||||
'О приложении',
|
||||
SettingsCubitType.about,
|
||||
),
|
||||
const Spacer(),
|
||||
_buildContactDeveloperButton(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// AppBar экрана настроек
|
||||
AppBar _buildAppBar(BuildContext context) {
|
||||
return AppBar(
|
||||
toolbarHeight: 66.h,
|
||||
backgroundColor: AppColors.white,
|
||||
shadowColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
leadingWidth: 0,
|
||||
title: AppTypography('Настройки', type: SemiBold20px()),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () => showInfoToast('Тут будет выход'),
|
||||
icon: Assets.icons.settingsExit.image(height: 24.h, width: 24.w),
|
||||
color: Colors.black,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Общий метод для построения пункта меню
|
||||
Widget _buildSettingsItem(
|
||||
BuildContext context,
|
||||
AssetGenImage icon,
|
||||
String title,
|
||||
SettingsCubitType cubitType,
|
||||
) {
|
||||
return GestureDetector(
|
||||
onTap: () => _navigateToSection(context, cubitType),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
margin: EdgeInsets.zero,
|
||||
padding: EdgeInsets.symmetric(vertical: 16.r, horizontal: 12.r),
|
||||
child: Row(
|
||||
children: [
|
||||
icon.image(height: 24.h, width: 24.w),
|
||||
WSpace(8),
|
||||
AppTypography(title, type: Regular16px()),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Метод для навигации к разделу через Cubit
|
||||
void _navigateToSection(BuildContext context, SettingsCubitType cubitType) {
|
||||
switch (cubitType) {
|
||||
case SettingsCubitType.initial:
|
||||
context.read<SettingsCubit>().toInitialState();
|
||||
case SettingsCubitType.profile:
|
||||
context.read<SettingsCubit>().toProfileState();
|
||||
case SettingsCubitType.notifications:
|
||||
context.read<SettingsCubit>().toNotificationsState();
|
||||
case SettingsCubitType.faq:
|
||||
context.read<SettingsCubit>().toFaqState();
|
||||
case SettingsCubitType.about:
|
||||
context.read<SettingsCubit>().toAboutState();
|
||||
}
|
||||
}
|
||||
|
||||
/// Кнопка "Написать разработчику"
|
||||
Widget _buildContactDeveloperButton() {
|
||||
return PrimaryButton(
|
||||
child: AppTypography(
|
||||
'Написать разработчику',
|
||||
color: AppColors.white,
|
||||
type: Medium14px(),
|
||||
),
|
||||
onTap: () {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Перечисление типов состояний для SettingsCubit
|
||||
enum SettingsCubitType { initial, profile, notifications, faq, about }
|
||||
103
lib/screens/settings/states/notifications.dart
Normal file
103
lib/screens/settings/states/notifications.dart
Normal file
@@ -0,0 +1,103 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:remever/common/resources.dart';
|
||||
import 'package:remever/common/widgets/typography.dart';
|
||||
import 'package:remever/components/extensions/context.dart';
|
||||
import 'package:remever/screens/settings/cubit/settings_cubit.dart';
|
||||
|
||||
class NotificationsSettingsState extends StatelessWidget {
|
||||
const NotificationsSettingsState({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bg,
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 66.h,
|
||||
backgroundColor: AppColors.white,
|
||||
shadowColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: AppTypography('Уведомления', type: SemiBold20px()),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
context.read<SettingsCubit>().toInitialState();
|
||||
},
|
||||
icon: Icon(CupertinoIcons.left_chevron),
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16).r,
|
||||
child: Column(
|
||||
spacing: 10,
|
||||
children: [
|
||||
_buildInfoLine(
|
||||
context,
|
||||
'Напоминание о тренировке',
|
||||
'Начнешь тренировку вовремя для эффективного запоминания. Уведомления будут приходить в период с 9:00 до 23:00',
|
||||
),
|
||||
_buildInfoLine(
|
||||
context,
|
||||
'От разработчика',
|
||||
'Обновление приложения, скидки и акции',
|
||||
),
|
||||
_buildInfoLine(
|
||||
context,
|
||||
'Мои коллекции',
|
||||
'Появление новых карточек в избранных коллекциях и новых коллекций у любимых авторов',
|
||||
),
|
||||
_buildInfoLine(
|
||||
context,
|
||||
'Авторам коллекций',
|
||||
'Новые подписчики в ваших публичных коллекциях и предложенные ими карточки',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInfoLine(BuildContext context, String title, String subTitle) {
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)).r,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16).r,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
AppTypography(
|
||||
title,
|
||||
type: Regular16px(),
|
||||
color: Colors.black,
|
||||
),
|
||||
AppTypography(
|
||||
subTitle,
|
||||
type: Regular12px(),
|
||||
color: AppColors.disabled,
|
||||
maxLines: 99,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
CupertinoSwitch(
|
||||
value: true,
|
||||
onChanged: (value) {},
|
||||
activeTrackColor: AppColors.primary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
130
lib/screens/settings/states/profile.dart
Normal file
130
lib/screens/settings/states/profile.dart
Normal file
@@ -0,0 +1,130 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:remever/common/resources.dart';
|
||||
import 'package:remever/common/widgets/typography.dart';
|
||||
import 'package:remever/common/widgets/wspace.dart';
|
||||
import 'package:remever/components/extensions/context.dart';
|
||||
import 'package:remever/gen/assets.gen.dart';
|
||||
import 'package:remever/screens/settings/cubit/settings_cubit.dart';
|
||||
import 'package:remever/common/functions.dart';
|
||||
|
||||
class ProfileSettingsState extends StatelessWidget {
|
||||
const ProfileSettingsState({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bg,
|
||||
appBar: _buildAppBar(context),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.all(16.r),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 410.h,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
HSpace(32),
|
||||
_buildAvatar(),
|
||||
HSpace(12),
|
||||
_buildInfoLine(
|
||||
context,
|
||||
Assets.icons.settingsName,
|
||||
'Антон Городецкий',
|
||||
Colors.black,
|
||||
() {},
|
||||
),
|
||||
_buildDivider(),
|
||||
_buildInfoLine(
|
||||
context,
|
||||
Assets.icons.settingsMail,
|
||||
'anton.gorod@gmail.com',
|
||||
Colors.black,
|
||||
() {},
|
||||
),
|
||||
_buildDivider(),
|
||||
_buildInfoLine(
|
||||
context,
|
||||
Assets.icons.settingsPhone,
|
||||
'+7 900 123 45 67',
|
||||
Colors.black,
|
||||
() {},
|
||||
),
|
||||
_buildDivider(thickness: 3),
|
||||
_buildInfoLine(
|
||||
context,
|
||||
Assets.icons.settingsTrash,
|
||||
'Удалить профиль',
|
||||
AppColors.danger,
|
||||
() {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// AppBar экрана профиля
|
||||
AppBar _buildAppBar(BuildContext context) {
|
||||
return AppBar(
|
||||
toolbarHeight: 66.h,
|
||||
backgroundColor: AppColors.white,
|
||||
shadowColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: AppTypography('Профиль', type: SemiBold20px()),
|
||||
leading: IconButton(
|
||||
onPressed: () => context.read<SettingsCubit>().toInitialState(),
|
||||
icon: const Icon(CupertinoIcons.left_chevron),
|
||||
color: Colors.black,
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () => showInfoToast('Тут будет выход'),
|
||||
icon: Assets.icons.settingsExit.image(height: 24.h, width: 24.w),
|
||||
color: Colors.black,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Аватар пользователя
|
||||
Widget _buildAvatar() {
|
||||
return CircleAvatar(
|
||||
backgroundImage: Assets.images.imgCard.provider(),
|
||||
radius: 82.r,
|
||||
);
|
||||
}
|
||||
|
||||
/// Общий элемент информации
|
||||
Widget _buildInfoLine(
|
||||
BuildContext context,
|
||||
AssetGenImage icon,
|
||||
String title,
|
||||
Color color,
|
||||
void Function()? onTap,
|
||||
) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.r),
|
||||
child: Row(
|
||||
children: [
|
||||
icon.image(height: 20.h, width: 20.w),
|
||||
WSpace(12),
|
||||
AppTypography(title, type: Medium16px(), color: color),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Переиспользуемый разделитель
|
||||
Widget _buildDivider({double thickness = 1}) {
|
||||
return Divider(height: 1, thickness: thickness);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user