From a3ef313e7ca7cc6d8845206804f32cc02bf1a46b Mon Sep 17 00:00:00 2001 From: Vitalij Date: Wed, 2 Apr 2025 21:52:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=BA=D0=B0=D1=80=D1=82=D0=BE=D1=87=D0=BA=D0=B8=20=D0=B2=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BB=D0=BB=D0=B5=D0=BA=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/screens/create_card/create_screen.dart | 381 ++++++++++----------- 1 file changed, 190 insertions(+), 191 deletions(-) diff --git a/lib/screens/create_card/create_screen.dart b/lib/screens/create_card/create_screen.dart index 2a47fc4..06a0832 100644 --- a/lib/screens/create_card/create_screen.dart +++ b/lib/screens/create_card/create_screen.dart @@ -1,6 +1,4 @@ import 'dart:io'; -import 'dart:math'; - import 'package:auto_route/auto_route.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; @@ -34,68 +32,82 @@ class CreateScreen extends StatefulWidget { class _CreateScreenState extends State { CreateTicketDto _dto = CreateTicketDto(); - void _pickImage(bool isQuestion) async { - final result = await FilePicker.platform.pickFiles(); + // Constants for spacing and dimensions + static const double _horizontalPadding = 16; + static const double _verticalSpacing = 16; + Future _pickImage(bool isQuestion) async { + final result = await FilePicker.platform.pickFiles(); if (result == null || result.files.isEmpty) { showErrorToast('Файл не выбран'); return; } - final filePath = result.files.single.path; - if (filePath == null) { showErrorToast('Не удалось получить путь к файлу'); - return; } - final file = File(filePath); final bytes = await file.readAsBytes(); - - _dto = - isQuestion - ? _dto.copyWith(questionImage: bytes) - : _dto.copyWith(answerImage: bytes); - - safeSetState(() {}); + safeSetState(() { + _dto = + isQuestion + ? _dto.copyWith(questionImage: bytes) + : _dto.copyWith(answerImage: bytes); + }); } void _onCollectionTap() { - { - context.pushRoute( - CollectionSearchRoute( - onCollectionSelect: (collection) { - safeSetState(() => _dto = _dto.copyWith(collection: collection)); - }, - ), - ); - } + context.pushRoute( + CollectionSearchRoute( + onCollectionSelect: (collection) { + safeSetState(() => _dto = _dto.copyWith(collection: collection)); + }, + ), + ); } - void _onCreateTap() async { + Future _onCreateTap() async { if (_dto.collection == null || _dto.answer == null || _dto.question == null) { showErrorToast('Необходимо заполнить все поля'); return; } - await getIt().createTicket(_dto); - context.pushRoute(CollectionRoute()); + safeSetState(() => _dto = CreateTicketDto()); + + final tabsRouter = context.tabsRouter; + tabsRouter.setActiveIndex(3); } - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: AppColors.gray_bg, - appBar: _buildAppBar(), - body: _buildMain(context), + void _openFullScreenField({ + required String title, + required String? content, + required void Function(String?) onEditingComplete, + }) { + context.pushRoute( + CrudCollectionFullscreenField( + title: title, + hint: '', + height: 313, + content: content, + onEditingComplete: onEditingComplete, + ), ); } - AppBar _buildAppBar() { + void _updateDto(String value, bool isQuestion) { + safeSetState(() { + _dto = + isQuestion + ? _dto.copyWith(question: value) + : _dto.copyWith(answer: value); + }); + } + + PreferredSizeWidget _buildAppBar() { return AppBar( toolbarHeight: 66.h, backgroundColor: AppColors.white, @@ -111,65 +123,47 @@ class _CreateScreenState extends State { Widget _buildMain(BuildContext context) { return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16).r, + padding: EdgeInsets.symmetric(horizontal: _horizontalPadding).r, child: Column( - children: [ + children: [ Expanded( child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const HSpace(16), + children: [ + const HSpace(_verticalSpacing), _filters(), - const HSpace(16), - AppTypography('Коллекция', type: Medium16px()), - const HSpace(4), - _buildCollection(context), - const HSpace(16), - AppTypography('Вопрос', type: Medium16px()), - const HSpace(4), - CrudTicket( - onTextTap: () { - context.pushRoute( - CrudCollectionFullscreenField( - title: 'Вопрос', - hint: '', - height: 313, - content: _dto.question, - onEditingComplete: (res) { - safeSetState(() { - _dto = _dto.copyWith(question: res); - }); - }, - ), - ); - }, - onImageTap: () => _pickImage(true), - isQuestion: true, - dto: _dto, + const HSpace(_verticalSpacing), + _buildSection('Коллекция', _buildCollection(context)), + const HSpace(_verticalSpacing), + _buildSection( + 'Вопрос', + CrudTicket( + onTextTap: + () => _openFullScreenField( + title: 'Вопрос', + content: _dto.question, + onEditingComplete: (res) => _updateDto(res!, true), + ), + onImageTap: () => _pickImage(true), + isQuestion: true, + dto: _dto, + ), ), - const HSpace(16), - AppTypography('Ответ', type: Medium16px()), - const HSpace(4), - CrudTicket( - onTextTap: () { - context.pushRoute( - CrudCollectionFullscreenField( - title: 'Ответ', - hint: '', - height: 313, - content: _dto.answer, - onEditingComplete: (res) { - safeSetState(() { - _dto = _dto.copyWith(answer: res); - }); - }, - ), - ); - }, - onImageTap: () => _pickImage(false), - isQuestion: false, - dto: _dto, + const HSpace(_verticalSpacing), + _buildSection( + 'Ответ', + CrudTicket( + onTextTap: + () => _openFullScreenField( + title: 'Ответ', + content: _dto.answer, + onEditingComplete: (res) => _updateDto(res!, false), + ), + onImageTap: () => _pickImage(false), + isQuestion: false, + dto: _dto, + ), ), revertCard(), ], @@ -183,91 +177,20 @@ class _CreateScreenState extends State { ); } - Widget revertCard() { - return SizedBox( - height: 52.h, - child: Row( - children: [ - Center( - child: Assets.icons.typeFlip2.image(height: 20.h, width: 20.w), - ), - const WSpace(2), - Flexible( - fit: FlexFit.tight, - child: AppTypography( - 'Создать карточку-наоборот', - type: Medium16px(), - ), - ), - SizedBox( - height: 20.h, - width: 36.w, - child: FittedBox( - fit: BoxFit.contain, - child: CupertinoSwitch( - activeTrackColor: AppColors.primary, - value: _dto.needRevert ?? false, - onChanged: (bool value) { - safeSetState(() { - _dto = _dto.copyWith(needRevert: value); - }); - }, - ), - ), - ), - ], - ), - ); - } - - Widget _filters() { - return AppDebug( - builder: (context, isDebug) { - if (!isDebug) return SizedBox(); - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - _buildFilterButton(AppColors.gray_bg, 'Запомнить', () {}), - _buildFilterButton(AppColors.white, 'Держать в фокусе', () {}), - ], - ); - }, - ); - } - - Widget _buildCreateButton() { - return PrimaryButton( - color: AppColors.primary, - child: AppTypography( - 'Создать карточку', - type: Medium14px(), - color: AppColors.white, - ), - onTap: () => _onCreateTap(), - ); - } - - /// - /// Построение кнопки фильтра - /// - Widget _buildFilterButton(Color color, String title, void Function()? onTap) { - return GestureDetector( - onTap: onTap, - child: Container( - width: 158.h, - height: 36.h, - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(16)).r, - color: color, - ), - child: Center(child: AppTypography(title, type: SemiBold14px())), - ), + Widget _buildSection(String title, Widget child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppTypography(title, type: Medium16px()), + const HSpace(4), + child, + ], ); } Widget _buildCollection(BuildContext context) { return GestureDetector( - onTap: () => _onCollectionTap(), + onTap: _onCollectionTap, child: Container( constraints: BoxConstraints(minHeight: 66.h, maxHeight: 84.h), decoration: BoxDecoration( @@ -277,38 +200,33 @@ class _CreateScreenState extends State { padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8).r, child: Wif( condition: _dto.collection != null, - builder: (context) { - return Row( - children: [_buildAvatar(), const WSpace(5), _buildInfo()], - ); - }, - fallback: (context) { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppTypography('Выберите коллекцию ', type: Bold14px()), - ], - ); - }, + builder: + (context) => Row( + children: [_buildAvatar(), const WSpace(5), _buildInfo()], + ), + fallback: + (context) => Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppTypography('Выберите коллекцию', type: Bold14px()), + ], + ), ), ), ); } - /// - /// Построение основной информации - /// Widget _buildInfo() { return SizedBox( width: 230.w, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, - children: [ + children: [ _buildTitle(), const HSpace(4), Row( - children: [ + children: [ Assets.icons.typeCards.image( height: 18.h, width: 18.w, @@ -329,9 +247,6 @@ class _CreateScreenState extends State { ); } - /// - /// Название коллекции - /// Widget _buildTitle() { return AppTypography( _dto.collection!.title, @@ -341,15 +256,11 @@ class _CreateScreenState extends State { ); } - /// - /// Обложка коллекции - /// Widget _buildAvatar() { return SizedBox.square( dimension: 50.r, child: DecoratedBox( decoration: BoxDecoration(shape: BoxShape.circle, color: AppColors.bg), - child: Wif( condition: _dto.collection?.image != null, builder: @@ -367,4 +278,92 @@ class _CreateScreenState extends State { ), ); } + + Widget revertCard() { + return SizedBox( + height: 52.h, + child: Row( + children: [ + Center( + child: Assets.icons.typeFlip2.image(height: 20.h, width: 20.w), + ), + const WSpace(2), + Flexible( + fit: FlexFit.tight, + child: AppTypography( + 'Создать карточку-наоборот', + type: Medium16px(), + ), + ), + SizedBox( + height: 20.h, + width: 36.w, + child: FittedBox( + fit: BoxFit.contain, + child: CupertinoSwitch( + activeTrackColor: AppColors.primary, + value: _dto.needRevert ?? false, + onChanged: + (value) => safeSetState( + () => _dto = _dto.copyWith(needRevert: value), + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildCreateButton() { + return PrimaryButton( + color: AppColors.primary, + onTap: _onCreateTap, + child: AppTypography( + 'Создать карточку', + type: Medium14px(), + color: AppColors.white, + ), + ); + } + + Widget _filters() { + return AppDebug( + builder: (context, isDebug) { + if (!isDebug) return const SizedBox(); + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildFilterButton(AppColors.gray_bg, 'Запомнить', () {}), + const WSpace(10), + _buildFilterButton(AppColors.white, 'Держать в фокусе', () {}), + ], + ); + }, + ); + } + + Widget _buildFilterButton(Color color, String title, VoidCallback onTap) { + return GestureDetector( + onTap: onTap, + child: Container( + width: 158.h, + height: 36.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16).r, + color: color, + ), + child: Center(child: AppTypography(title, type: SemiBold14px())), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.gray_bg, + appBar: _buildAppBar(), + body: _buildMain(context), + ); + } }