Обновлен проект. Добавлена БД
This commit is contained in:
@@ -1,12 +1,377 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:remever/common/functions.dart';
|
||||
import 'package:remever/common/resources.dart';
|
||||
import 'package:remever/common/toast.dart';
|
||||
import 'package:remever/common/widgets/bottom_safe_space.dart';
|
||||
import 'package:remever/common/widgets/typography.dart';
|
||||
import 'package:remever/common/widgets/w_if.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/router.gr.dart';
|
||||
import 'package:remever/screens/crud_collection/widgets/crud_collection_field.dart';
|
||||
import 'package:remever/screens/dialogs/alert_dialog.dart';
|
||||
import 'package:remever/screens/dialogs/tags_dialog.dart';
|
||||
import 'package:remever/widgets/primary_button.dart';
|
||||
|
||||
import '../../../components/extensions/state.dart';
|
||||
|
||||
enum CrudType { CREATE, EDIT }
|
||||
|
||||
@RoutePage()
|
||||
class CrudCollection extends StatelessWidget {
|
||||
const CrudCollection({super.key});
|
||||
class CrudCollectionScreen extends StatefulWidget {
|
||||
const CrudCollectionScreen({super.key, this.crudType = CrudType.CREATE});
|
||||
|
||||
final CrudType crudType;
|
||||
|
||||
@override
|
||||
State<CrudCollectionScreen> createState() => _CrudCollectionScreenState();
|
||||
}
|
||||
|
||||
class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
|
||||
/// Флаг публичности коллекции
|
||||
bool _isPublic = false;
|
||||
|
||||
/// Смена публичности
|
||||
void _setPublic(bool public) {
|
||||
safeSetState(() => _isPublic = public);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder(color: Colors.blue);
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.gray_bg,
|
||||
appBar: _buildAppBar(context),
|
||||
body: _buildMainBody(context),
|
||||
);
|
||||
}
|
||||
|
||||
/// Основное тело экрана
|
||||
Widget _buildMainBody(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16).r,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
const HSpace(16),
|
||||
_buildPhotoAndTitle(context),
|
||||
const HSpace(16),
|
||||
..._buildDescription(context),
|
||||
const HSpace(16),
|
||||
_buildPublickSwitch(),
|
||||
const HSpace(16),
|
||||
AnimatedOpacity(
|
||||
opacity: _isPublic ? 1 : 0,
|
||||
duration: const Duration(seconds: 1),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
..._buildTagButton(),
|
||||
const HSpace(16),
|
||||
_buildTagsList(),
|
||||
const HSpace(47),
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildCreateBtn(context),
|
||||
const BottomSafeSpace(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
///Кнопка создания
|
||||
Widget _buildCreateBtn(BuildContext context) {
|
||||
return PrimaryButton(
|
||||
height: 52,
|
||||
onTap: () {
|
||||
if (true) {
|
||||
Toast.showDismissible(
|
||||
'Для создания публичной коллекции добавьте описание и тэги',
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// context.read<HomeCubit>().toCollection();
|
||||
},
|
||||
color: AppColors.primary,
|
||||
child: AppTypography(
|
||||
widget.crudType == CrudType.CREATE
|
||||
? 'Создать коллекцию'
|
||||
: 'Сохранить изменения',
|
||||
type: Regular14px(),
|
||||
color: Colors.white,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Построение списка тегов
|
||||
Widget _buildTagsList() {
|
||||
return SizedBox(
|
||||
height: 68.h,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Wrap(
|
||||
runSpacing: 8.r,
|
||||
spacing: 8.r,
|
||||
children: List<Widget>.generate(6, (int index) {
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(6)).r,
|
||||
color: const Color(0xFFFFE4E6),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
AppTypography(
|
||||
'tag $index',
|
||||
type: Regular14px(),
|
||||
height: 0.95,
|
||||
color: AppColors.danger,
|
||||
),
|
||||
const WSpace(8),
|
||||
Center(
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
size: 14.r,
|
||||
color: AppColors.danger,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
const WSpace(9),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
showCuperModalBottomSheet(
|
||||
context: context,
|
||||
height: 270.h,
|
||||
builder: (BuildContext context) => const TagsDialog(),
|
||||
);
|
||||
},
|
||||
child: AppTypography(
|
||||
'+13',
|
||||
type: Medium16px(),
|
||||
color: AppColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Построение кнопки добавления тега
|
||||
List<Widget> _buildTagButton() {
|
||||
return <Widget>[
|
||||
AppTypography('Тэги', type: SemiBold14px()),
|
||||
const HSpace(4),
|
||||
CrudCollectionField(
|
||||
height: 42,
|
||||
width: 348,
|
||||
hint: 'Добавить тэг',
|
||||
// onTap: () => context.pushRoute(const AddTagsRoute()),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
/// Построение свитчера на публичность коллекции
|
||||
Widget _buildPublickSwitch() {
|
||||
return GestureDetector(
|
||||
onTap: () => _setPublic(!_isPublic),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
SizedBox.square(
|
||||
dimension: 20.r,
|
||||
child: Assets.icons.typePublic.image(color: AppColors.primary),
|
||||
),
|
||||
const WSpace(2),
|
||||
Flexible(
|
||||
fit: FlexFit.tight,
|
||||
child: AppTypography(
|
||||
'Публичная коллекция',
|
||||
type: Medium16px(),
|
||||
color: AppColors.primary,
|
||||
),
|
||||
),
|
||||
const WSpace(2),
|
||||
SizedBox(
|
||||
height: 20.h,
|
||||
width: 36.w,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.contain,
|
||||
child: CupertinoSwitch(
|
||||
activeTrackColor: AppColors.primary,
|
||||
value: _isPublic,
|
||||
onChanged: _setPublic,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Построение блока с описанием
|
||||
List<Widget> _buildDescription(BuildContext context) {
|
||||
return <Widget>[
|
||||
AppTypography('Описание', type: SemiBold14px()),
|
||||
const HSpace(4),
|
||||
CrudCollectionField(
|
||||
height: 110,
|
||||
width: 348,
|
||||
hint: 'Добавить описание',
|
||||
onTap: () {
|
||||
context.pushRoute(
|
||||
CrudCollectionFullscreenField(title: 'Описание', height: 333),
|
||||
);
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
/// Построение блока фото и заголовка
|
||||
Widget _buildPhotoAndTitle(BuildContext context) {
|
||||
return Row(
|
||||
children: <Widget>[_buildPhoto(), const WSpace(8), _buildTitle(context)],
|
||||
);
|
||||
}
|
||||
|
||||
/// Построение поля для ввода заголовка
|
||||
Widget _buildTitle(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
AppTypography('Название', type: SemiBold14px()),
|
||||
const HSpace(4),
|
||||
CrudCollectionField(
|
||||
height: 91,
|
||||
width: 225,
|
||||
hint: 'Добавить название',
|
||||
onTap: () {
|
||||
context.pushRoute(
|
||||
CrudCollectionFullscreenField(
|
||||
title: 'Название',
|
||||
hint: 'Максимальное количество символов - 250',
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Построение обложки
|
||||
Widget _buildPhoto() {
|
||||
return SizedBox.square(
|
||||
dimension: 115.r,
|
||||
child: DecoratedBox(
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
gradient: LinearGradient(
|
||||
colors: <Color>[Color(0xFFB6AAFE), Color(0xFFDBD7F4)],
|
||||
begin: Alignment.bottomLeft,
|
||||
end: Alignment.topRight,
|
||||
),
|
||||
),
|
||||
child: SizedBox.square(
|
||||
dimension: 32.r,
|
||||
child: Center(
|
||||
child: Assets.icons.typePhoto.image(
|
||||
height: 32.h,
|
||||
width: 32.w,
|
||||
color: AppColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Построение шапки
|
||||
AppBar _buildAppBar(BuildContext context) {
|
||||
return AppBar(
|
||||
toolbarHeight: 56.h,
|
||||
backgroundColor: AppColors.white,
|
||||
shadowColor: Colors.transparent,
|
||||
leading: IconButton(
|
||||
onPressed: () async {
|
||||
if (widget.crudType == CrudType.EDIT) {
|
||||
final bool? res = await showCuperModalBottomSheet(
|
||||
context: context,
|
||||
height: 262.h,
|
||||
builder:
|
||||
(BuildContext context) => const AlertInfoDialog(
|
||||
title: 'Вы хотите сбросить все внесенные изменения?',
|
||||
acceptTitle: 'Да, сбросить',
|
||||
declineTitle: 'Нет, оставить',
|
||||
),
|
||||
);
|
||||
|
||||
if (res != null && res) context.back();
|
||||
} else {
|
||||
context.back();
|
||||
}
|
||||
},
|
||||
icon: const Icon(CupertinoIcons.left_chevron, color: Colors.black),
|
||||
),
|
||||
centerTitle: true,
|
||||
title: GestureDetector(
|
||||
onLongPress: () => context.pushRoute(const SandboxRoute()),
|
||||
child: AppTypography(
|
||||
widget.crudType == CrudType.CREATE
|
||||
? 'Создать коллекцию'
|
||||
: 'Редактировать',
|
||||
type: SemiBold20px(),
|
||||
color: AppColors.body_text,
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
Wif(
|
||||
condition: widget.crudType == CrudType.EDIT,
|
||||
builder: (BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 16).r,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
showCuperModalBottomSheet(
|
||||
context: context,
|
||||
height: 262.h,
|
||||
builder:
|
||||
(BuildContext context) => const AlertInfoDialog(
|
||||
title: 'Вы хотите сбросить все внесенные изменения?',
|
||||
acceptTitle: 'Да, сбросить',
|
||||
declineTitle: 'Нет, оставить',
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Assets.icons.typeTrash.image(
|
||||
height: 24.h,
|
||||
width: 24.w,
|
||||
color: AppColors.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user