feat(diary): wakeup, retire, mood, comment

This commit is contained in:
mso7nueh
2025-03-24 17:37:47 +03:00
parent fcdc57493d
commit a871dd8951
21 changed files with 767 additions and 165 deletions

View File

@@ -1,6 +1,10 @@
include: package:flutter_lints/flutter.yaml
linter:
rules:
- require_trailing_commas
formatter:
page_width: 80
analyzer:
exclude:

8
assets/icons/mood_1.svg Normal file
View File

@@ -0,0 +1,8 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 15C30 23.2842 23.2842 30 15 30C6.71583 30 0 23.2842 0 15C0 6.71583 6.71583 0 15 0C23.2842 0 30 6.71583 30 15Z" fill="#FFCC4D"/>
<path d="M18.3353 22.5C18.3353 24.8025 16.8428 25 15.002 25C13.1603 25 11.6686 24.8025 11.6686 22.5C11.6686 20.1992 13.1603 17.5 15.002 17.5C16.8428 17.5 18.3353 20.1992 18.3353 22.5ZM25.002 12.5C24.8986 12.5 24.7936 12.4809 24.6928 12.44C20.3353 10.6975 18.5495 8.07253 18.4753 7.96169C18.2195 7.57836 18.3228 7.06086 18.7061 6.80586C19.0886 6.55086 19.6036 6.65253 19.8603 7.03419C19.8761 7.05669 21.4686 9.35503 25.3111 10.8917C25.7386 11.0634 25.947 11.5475 25.7761 11.975C25.6453 12.3017 25.332 12.5 25.002 12.5ZM5.00195 12.5C4.67112 12.5 4.35862 12.3017 4.22779 11.9759C4.05695 11.5484 4.26445 11.0634 4.69195 10.8925C8.53529 9.35586 10.1278 7.05753 10.1436 7.03503C10.4003 6.65503 10.9178 6.55419 11.2995 6.81003C11.6803 7.06669 11.7836 7.58086 11.5286 7.96253C11.4545 8.07336 9.66862 10.6984 5.31195 12.4409C5.21029 12.4809 5.10529 12.5 5.00195 12.5Z" fill="#664500"/>
<path d="M20.0013 13.3334H23.3346V29.1667L20.0013 29.1284V13.3334ZM6.66797 29.1667L10.0013 29.1284V13.3334H6.66797V29.1667Z" fill="#5DADEC"/>
<path d="M12.499 14.9998C12.374 14.9998 12.2465 14.9714 12.1274 14.9123C9.2007 13.4489 6.2357 14.8973 6.20654 14.9123C5.79404 15.1198 5.29404 14.9506 5.0882 14.5398C4.88237 14.1281 5.04904 13.6273 5.4607 13.4214C5.61237 13.3464 9.20904 11.5906 12.8732 13.4214C13.2849 13.6273 13.4515 14.1281 13.2457 14.5398C13.099 14.8314 12.8049 14.9998 12.499 14.9998ZM24.1657 14.9998C24.0407 14.9998 23.9132 14.9714 23.794 14.9123C20.8665 13.4489 17.9024 14.8973 17.8732 14.9123C17.4615 15.1189 16.9615 14.9514 16.7549 14.5398C16.549 14.1281 16.7157 13.6273 17.1274 13.4214C17.279 13.3464 20.8782 11.5914 24.5399 13.4214C24.9515 13.6273 25.1182 14.1281 24.9124 14.5398C24.7657 14.8314 24.4715 14.9998 24.1657 14.9998Z" fill="#664500"/>
<path d="M15 30C23.2843 30 30 29.2538 30 28.3333C30 27.4128 23.2843 26.6666 15 26.6666C6.71573 26.6666 0 27.4128 0 28.3333C0 29.2538 6.71573 30 15 30Z" fill="#5DADEC"/>
<path d="M15 24.1667C16.3807 24.1667 17.5 23.4205 17.5 22.5C17.5 21.5796 16.3807 20.8334 15 20.8334C13.6193 20.8334 12.5 21.5796 12.5 22.5C12.5 23.4205 13.6193 24.1667 15 24.1667Z" fill="#E75A70"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

6
assets/icons/mood_2.svg Normal file
View File

@@ -0,0 +1,6 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 15C30 23.2842 23.2842 30 15 30C6.71583 30 0 23.2842 0 15C0 6.71583 6.71583 0 15 0C23.2842 0 30 6.71583 30 15Z" fill="#FFCC4D"/>
<path d="M14.9987 17.5C11.9795 17.5 9.9762 17.1484 7.4987 16.6667C6.93286 16.5575 5.83203 16.6667 5.83203 18.3334C5.83203 21.6667 9.6612 25.8334 14.9987 25.8334C20.3354 25.8334 24.1654 21.6667 24.1654 18.3334C24.1654 16.6667 23.0645 16.5567 22.4987 16.6667C20.0212 17.1484 18.0179 17.5 14.9987 17.5Z" fill="#664500"/>
<path d="M7.5 18.3334C7.5 18.3334 10 19.1667 15 19.1667C20 19.1667 22.5 18.3334 22.5 18.3334C22.5 18.3334 20.8333 21.6667 15 21.6667C9.16667 21.6667 7.5 18.3334 7.5 18.3334Z" fill="white"/>
<path d="M13.0686 3.67752L9.28363 4.34502L7.33363 0.800858C7.11863 0.410024 6.67697 0.200858 6.2403 0.277525C5.80113 0.355025 5.45947 0.703358 5.39113 1.14336L4.7703 5.14086L0.9853 5.80836C0.539467 5.88669 0.1953 6.24586 0.134467 6.69502C0.0736333 7.14419 0.3103 7.58086 0.7203 7.77586L4.11197 9.38586L3.48863 13.3959C3.41947 13.8425 3.64613 14.2825 4.04947 14.4867C4.19863 14.5617 4.35863 14.5975 4.5178 14.5975C4.7903 14.5975 5.05947 14.4909 5.2603 14.2875L8.18697 11.32L11.952 13.1075C12.3603 13.3009 12.847 13.21 13.157 12.8809C13.467 12.5517 13.5286 12.0609 13.3111 11.665L11.3545 8.10836L13.992 5.43502C14.3103 5.11252 14.3828 4.62086 14.1728 4.21919C13.9611 3.81752 13.512 3.60002 13.0686 3.67752ZM16.932 3.67752L20.717 4.34502L22.667 0.800858C22.882 0.410024 23.3236 0.200858 23.7603 0.277525C24.1986 0.355025 24.5403 0.703358 24.6086 1.14336L25.2295 5.14086L29.0145 5.80836C29.4611 5.88669 29.8053 6.24502 29.8653 6.69419C29.9253 7.14336 29.6895 7.58002 29.2795 7.77502L25.8878 9.38502L26.5111 13.395C26.5803 13.8417 26.3536 14.2817 25.9503 14.4859C25.8011 14.5609 25.6411 14.5967 25.482 14.5967C25.2095 14.5967 24.9403 14.49 24.7395 14.2867L21.8128 11.3192L18.0478 13.1067C17.6395 13.3 17.1528 13.2092 16.8428 12.88C16.5328 12.5509 16.4711 12.06 16.6886 11.6642L18.6453 8.10836L16.0078 5.43502C15.6895 5.11252 15.617 4.62086 15.827 4.21919C16.0395 3.81752 16.4886 3.60002 16.932 3.67752Z" fill="#E95F28"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

10
assets/icons/retire.svg Normal file
View File

@@ -0,0 +1,10 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_4416_49941)">
<path d="M8.75535 15.5792C7.63577 15.5792 6.58588 15.3668 5.60567 14.942C4.62532 14.5171 3.77023 13.9398 3.04041 13.21C2.31058 12.4801 1.73325 11.625 1.30841 10.6447C0.883564 9.66448 0.671143 8.61459 0.671143 7.49501C0.671143 5.87662 1.10897 4.39838 1.98462 3.06027C2.86013 1.72202 4.04441 0.744692 5.53746 0.128271C5.80314 0.0159904 6.05444 0.0357096 6.29135 0.187429C6.52827 0.339008 6.64784 0.554657 6.65009 0.834376C6.66735 2.00574 6.89598 3.12231 7.33598 4.18406C7.77584 5.24595 8.40876 6.18982 9.23472 7.01564C10.0605 7.8416 11.0017 8.47318 12.0581 8.91038C13.1145 9.34771 14.2284 9.57501 15.3998 9.59227C15.7108 9.59438 15.9391 9.71311 16.0848 9.94848C16.2307 10.1839 16.2474 10.4387 16.1351 10.7129C15.5013 12.1974 14.5175 13.3796 13.1836 14.2594C11.8498 15.1393 10.3737 15.5792 8.75535 15.5792ZM8.75535 14.3161C9.99044 14.3161 11.1343 14.0073 12.1869 13.3897C13.2396 12.7722 14.0676 11.9231 14.6711 10.8424C13.4641 10.7301 12.3203 10.4235 11.2396 9.92259C10.1589 9.42167 9.19044 8.74315 8.3343 7.88701C7.47816 7.03087 6.79746 6.06378 6.2922 4.98574C5.78693 3.90771 5.48518 2.76518 5.38693 1.55817C4.30623 2.16167 3.46062 2.99325 2.85009 4.0529C2.23956 5.11255 1.9343 6.25992 1.9343 7.49501C1.9343 9.38974 2.59746 11.0003 3.92377 12.3266C5.25009 13.6529 6.86062 14.3161 8.75535 14.3161Z" fill="#6D6F71"/>
</g>
<defs>
<clipPath id="clip0_4416_49941">
<rect width="16" height="16" fill="white" transform="translate(0.25)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

10
assets/icons/wakeup.svg Normal file
View File

@@ -0,0 +1,10 @@
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_4416_49934)">
<path d="M9.24976 3.44577C9.07576 3.44577 8.93006 3.38699 8.81265 3.26945C8.6951 3.15177 8.63633 3.00599 8.63633 2.83213V1.03847C8.63633 0.864608 8.69517 0.718903 8.81285 0.601358C8.93053 0.483676 9.07631 0.424835 9.25017 0.424835C9.42417 0.424835 9.56987 0.483676 9.68728 0.601358C9.80483 0.718903 9.8636 0.864608 9.8636 1.03847V2.83213C9.8636 3.00599 9.80476 3.15177 9.68708 3.26945C9.5694 3.38699 9.42362 3.44577 9.24976 3.44577ZM13.1742 5.07579C13.0609 4.96261 13.0055 4.82236 13.0081 4.65504C13.0107 4.48772 13.0686 4.34058 13.1819 4.21363L14.4297 2.93768C14.5528 2.81072 14.699 2.74724 14.8682 2.74724C15.0374 2.74724 15.1861 2.81127 15.3141 2.93931C15.4315 3.05672 15.4902 3.19984 15.4902 3.36865C15.4902 3.53761 15.4309 3.68134 15.3123 3.79984L14.0363 5.07579C13.9178 5.19443 13.7741 5.25374 13.6051 5.25374C13.4363 5.25374 13.2927 5.19443 13.1742 5.07579ZM15.4178 9.61363C15.244 9.61363 15.0982 9.55479 14.9805 9.43711C14.863 9.31943 14.8042 9.17365 14.8042 8.99979C14.8042 8.82579 14.863 8.68009 14.9805 8.56268C15.0982 8.44513 15.244 8.38636 15.4178 8.38636H17.2115C17.3853 8.38636 17.5311 8.4452 17.6486 8.56288C17.7663 8.68056 17.8251 8.82633 17.8251 9.0002C17.8251 9.1742 17.7663 9.3199 17.6486 9.43731C17.5311 9.55486 17.3853 9.61363 17.2115 9.61363H15.4178ZM9.24976 17.5752C9.07576 17.5752 8.93006 17.5163 8.81265 17.3986C8.6951 17.2811 8.63633 17.1354 8.63633 16.9615V15.1756C8.63633 15.0018 8.69517 14.8561 8.81285 14.7385C8.93053 14.6208 9.07631 14.562 9.25017 14.562C9.42417 14.562 9.56987 14.6208 9.68728 14.7385C9.80483 14.8561 9.8636 15.0018 9.8636 15.1756V16.9615C9.8636 17.1354 9.80476 17.2811 9.68708 17.3986C9.5694 17.5163 9.42362 17.5752 9.24976 17.5752ZM4.47158 5.07579L3.18765 3.82029C3.06069 3.6977 2.99721 3.54954 2.99721 3.37581C2.99721 3.20222 3.06069 3.05618 3.18765 2.93768C3.30615 2.82436 3.45158 2.7677 3.62394 2.7677C3.7963 2.7677 3.93826 2.82436 4.0498 2.93768L5.33374 4.22161C5.44705 4.33315 5.50371 4.47511 5.50371 4.64747C5.50371 4.81984 5.4476 4.96261 5.33537 5.07579C5.21292 5.18911 5.07008 5.24577 4.90685 5.24577C4.74349 5.24577 4.5984 5.18911 4.47158 5.07579ZM14.4376 15.0623L13.1819 13.7864C13.0686 13.6594 13.0107 13.5123 13.0081 13.3449C13.0055 13.1776 13.0603 13.0374 13.1725 12.9242C13.2848 12.8109 13.4251 12.7542 13.5935 12.7542C13.7618 12.7542 13.9094 12.8135 14.0363 12.932L15.3123 14.1877C15.4341 14.3009 15.4928 14.4432 15.4886 14.6148C15.4844 14.7863 15.4249 14.9355 15.31 15.0623C15.1847 15.1893 15.0359 15.2527 14.8635 15.2527C14.691 15.2527 14.5491 15.1893 14.4376 15.0623ZM1.28844 9.61363C1.11458 9.61363 0.968873 9.55479 0.851327 9.43711C0.733646 9.31943 0.674805 9.17365 0.674805 8.99979C0.674805 8.82579 0.733646 8.68009 0.851327 8.56268C0.968873 8.44513 1.11458 8.38636 1.28844 8.38636H3.0821C3.25596 8.38636 3.40174 8.4452 3.51942 8.56288C3.63696 8.68056 3.69574 8.82633 3.69574 9.0002C3.69574 9.1742 3.63696 9.3199 3.51942 9.43731C3.40174 9.55486 3.25596 9.61363 3.0821 9.61363H1.28844ZM3.19542 15.0623C3.0821 14.9438 3.02415 14.7988 3.02155 14.6272C3.01896 14.4558 3.07433 14.3135 3.18765 14.2002L4.45583 12.932C4.57433 12.8135 4.71594 12.7542 4.88067 12.7542C5.04526 12.7542 5.19103 12.8129 5.31799 12.9303C5.44494 13.0584 5.50842 13.2061 5.50842 13.3734C5.50842 13.5407 5.44494 13.6878 5.31799 13.8146L4.07026 15.0623C3.9433 15.1893 3.79365 15.2527 3.62128 15.2527C3.44892 15.2527 3.30696 15.1893 3.19542 15.0623ZM9.25181 13.5C8.00231 13.5 6.93962 13.0627 6.06376 12.188C5.1879 11.3134 4.74996 10.2513 4.74996 9.00183C4.74996 7.75234 5.18728 6.68965 6.06192 5.81379C6.93656 4.93793 7.99862 4.49999 9.24812 4.49999C10.4976 4.49999 11.5603 4.93731 12.4362 5.81195C13.312 6.68659 13.75 7.74865 13.75 8.99815C13.75 10.2477 13.3126 11.3103 12.438 12.1862C11.5634 13.0621 10.5013 13.5 9.25181 13.5ZM9.24996 12.2727C10.15 12.2727 10.9204 11.9523 11.5613 11.3114C12.2022 10.6704 12.5227 9.89999 12.5227 8.99999C12.5227 8.09999 12.2022 7.32954 11.5613 6.68863C10.9204 6.04772 10.15 5.72727 9.24996 5.72727C8.34996 5.72727 7.57951 6.04772 6.9386 6.68863C6.29769 7.32954 5.97724 8.09999 5.97724 8.99999C5.97724 9.89999 6.29769 10.6704 6.9386 11.3114C7.57951 11.9523 8.34996 12.2727 9.24996 12.2727Z" fill="#6D6F71"/>
</g>
<defs>
<clipPath id="clip0_4416_49934">
<rect width="18" height="18" fill="white" transform="translate(0.25)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -80,8 +80,10 @@ class CustomTextFormField extends StatelessWidget {
final TextAlignVertical? textAlignVertical;
final bool hasError;
final bool enabled;
// final TextAlign
final bool readOnly;
@override
Widget build(BuildContext context) {
return Align(
@@ -97,11 +99,7 @@ class CustomTextFormField extends StatelessWidget {
controller: controller,
focusNode: focusNode ?? null,
autofocus: autofocus,
style: TextStyle(
fontSize: 16,
color: Colors.black,
fontWeight: FontWeight.w500,
),
style: TextStyle(fontSize: 16, color: Colors.black, fontWeight: FontWeight.w500),
obscureText: obscureText!,
textInputAction: textInputAction,
maxLines: maxLines,
@@ -112,40 +110,26 @@ class CustomTextFormField extends StatelessWidget {
counter: counter,
suffixText: suffixText,
hintText: hintText ?? "",
hintStyle: TextStyle(
fontSize: 16,
color: Colors.grey.shade400,
fontWeight: FontWeight.w500,
),
hintStyle: hintStyle ?? TextStyle(fontSize: 16, color: Color(0xFF323F4B).withAlpha((255 / 2).toInt()), fontWeight: FontWeight.w500),
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF323F4B),
),
suffixStyle: textStyle ?? TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xFF323F4B)),
suffixIconConstraints: suffixConstraints,
isDense: false,
contentPadding: EdgeInsets.symmetric(vertical: 16, horizontal: 12),
fillColor: Color(0xFFF6F6F6),
filled: true,
border: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none,
),
enabledBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none,
),
focusedBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none,
),
border:
borderDecoration ??
OutlineInputBorder(borderRadius: BorderRadius.circular(20), borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none),
enabledBorder:
borderDecoration ??
OutlineInputBorder(borderRadius: BorderRadius.circular(20), borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none),
focusedBorder:
borderDecoration ??
OutlineInputBorder(borderRadius: BorderRadius.circular(20), borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none),
),
keyboardType: keyboardType,
validator: validator,

View File

@@ -4,12 +4,9 @@ part 'finish_diary_day_model.freezed.dart';
part 'finish_diary_day_model.g.dart';
@freezed
@Freezed()
class FinishDiaryDayModel with _$FinishDiaryDayModel {
const factory FinishDiaryDayModel({
required String wakeUp,
required String retire,
}) = _FinishDiaryDayModel;
const factory FinishDiaryDayModel({required String wakeUp, required String retire, @JsonKey(includeIfNull: false) String? comment}) = _FinishDiaryDayModel;
factory FinishDiaryDayModel.fromJson(Map<String, Object?> json) => _$FinishDiaryDayModelFromJson(json);
factory FinishDiaryDayModel.fromJson(Map<String, dynamic> json) => _$FinishDiaryDayModelFromJson(json);
}

View File

@@ -23,6 +23,8 @@ FinishDiaryDayModel _$FinishDiaryDayModelFromJson(Map<String, dynamic> json) {
mixin _$FinishDiaryDayModel {
String get wakeUp => throw _privateConstructorUsedError;
String get retire => throw _privateConstructorUsedError;
@JsonKey(includeIfNull: false)
String? get comment => throw _privateConstructorUsedError;
/// Serializes this FinishDiaryDayModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@@ -41,7 +43,11 @@ abstract class $FinishDiaryDayModelCopyWith<$Res> {
$Res Function(FinishDiaryDayModel) then,
) = _$FinishDiaryDayModelCopyWithImpl<$Res, FinishDiaryDayModel>;
@useResult
$Res call({String wakeUp, String retire});
$Res call({
String wakeUp,
String retire,
@JsonKey(includeIfNull: false) String? comment,
});
}
/// @nodoc
@@ -58,7 +64,11 @@ class _$FinishDiaryDayModelCopyWithImpl<$Res, $Val extends FinishDiaryDayModel>
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({Object? wakeUp = null, Object? retire = null}) {
$Res call({
Object? wakeUp = null,
Object? retire = null,
Object? comment = freezed,
}) {
return _then(
_value.copyWith(
wakeUp:
@@ -71,6 +81,11 @@ class _$FinishDiaryDayModelCopyWithImpl<$Res, $Val extends FinishDiaryDayModel>
? _value.retire
: retire // ignore: cast_nullable_to_non_nullable
as String,
comment:
freezed == comment
? _value.comment
: comment // ignore: cast_nullable_to_non_nullable
as String?,
)
as $Val,
);
@@ -86,7 +101,11 @@ abstract class _$$FinishDiaryDayModelImplCopyWith<$Res>
) = __$$FinishDiaryDayModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({String wakeUp, String retire});
$Res call({
String wakeUp,
String retire,
@JsonKey(includeIfNull: false) String? comment,
});
}
/// @nodoc
@@ -102,7 +121,11 @@ class __$$FinishDiaryDayModelImplCopyWithImpl<$Res>
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({Object? wakeUp = null, Object? retire = null}) {
$Res call({
Object? wakeUp = null,
Object? retire = null,
Object? comment = freezed,
}) {
return _then(
_$FinishDiaryDayModelImpl(
wakeUp:
@@ -115,6 +138,11 @@ class __$$FinishDiaryDayModelImplCopyWithImpl<$Res>
? _value.retire
: retire // ignore: cast_nullable_to_non_nullable
as String,
comment:
freezed == comment
? _value.comment
: comment // ignore: cast_nullable_to_non_nullable
as String?,
),
);
}
@@ -123,7 +151,11 @@ class __$$FinishDiaryDayModelImplCopyWithImpl<$Res>
/// @nodoc
@JsonSerializable()
class _$FinishDiaryDayModelImpl implements _FinishDiaryDayModel {
const _$FinishDiaryDayModelImpl({required this.wakeUp, required this.retire});
const _$FinishDiaryDayModelImpl({
required this.wakeUp,
required this.retire,
@JsonKey(includeIfNull: false) this.comment,
});
factory _$FinishDiaryDayModelImpl.fromJson(Map<String, dynamic> json) =>
_$$FinishDiaryDayModelImplFromJson(json);
@@ -132,10 +164,13 @@ class _$FinishDiaryDayModelImpl implements _FinishDiaryDayModel {
final String wakeUp;
@override
final String retire;
@override
@JsonKey(includeIfNull: false)
final String? comment;
@override
String toString() {
return 'FinishDiaryDayModel(wakeUp: $wakeUp, retire: $retire)';
return 'FinishDiaryDayModel(wakeUp: $wakeUp, retire: $retire, comment: $comment)';
}
@override
@@ -144,12 +179,13 @@ class _$FinishDiaryDayModelImpl implements _FinishDiaryDayModel {
(other.runtimeType == runtimeType &&
other is _$FinishDiaryDayModelImpl &&
(identical(other.wakeUp, wakeUp) || other.wakeUp == wakeUp) &&
(identical(other.retire, retire) || other.retire == retire));
(identical(other.retire, retire) || other.retire == retire) &&
(identical(other.comment, comment) || other.comment == comment));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType, wakeUp, retire);
int get hashCode => Object.hash(runtimeType, wakeUp, retire, comment);
/// Create a copy of FinishDiaryDayModel
/// with the given fields replaced by the non-null parameter values.
@@ -172,6 +208,7 @@ abstract class _FinishDiaryDayModel implements FinishDiaryDayModel {
const factory _FinishDiaryDayModel({
required final String wakeUp,
required final String retire,
@JsonKey(includeIfNull: false) final String? comment,
}) = _$FinishDiaryDayModelImpl;
factory _FinishDiaryDayModel.fromJson(Map<String, dynamic> json) =
@@ -181,6 +218,9 @@ abstract class _FinishDiaryDayModel implements FinishDiaryDayModel {
String get wakeUp;
@override
String get retire;
@override
@JsonKey(includeIfNull: false)
String? get comment;
/// Create a copy of FinishDiaryDayModel
/// with the given fields replaced by the non-null parameter values.

View File

@@ -11,8 +11,13 @@ _$FinishDiaryDayModelImpl _$$FinishDiaryDayModelImplFromJson(
) => _$FinishDiaryDayModelImpl(
wakeUp: json['wakeUp'] as String,
retire: json['retire'] as String,
comment: json['comment'] as String?,
);
Map<String, dynamic> _$$FinishDiaryDayModelImplToJson(
_$FinishDiaryDayModelImpl instance,
) => <String, dynamic>{'wakeUp': instance.wakeUp, 'retire': instance.retire};
) => <String, dynamic>{
'wakeUp': instance.wakeUp,
'retire': instance.retire,
if (instance.comment case final value?) 'comment': value,
};

View File

@@ -17,10 +17,7 @@ class DiaryCubit extends Cubit<DiaryState> {
final DiaryRepository diaryRepository;
final GlossaryRepository glossaryRepository;
DiaryCubit({
required this.diaryRepository,
required this.glossaryRepository,
}) : super(const DiaryState.loading()) {
DiaryCubit({required this.diaryRepository, required this.glossaryRepository}) : super(const DiaryState.loading()) {
today = DateTime.now();
selectedDay = today;
}
@@ -56,16 +53,8 @@ class DiaryCubit extends Cubit<DiaryState> {
}
}
finishDiaryDay({
required int diaryId,
required String wakeUp,
required String retire,
}) async {
await diaryRepository.finishDiaryDay(
diaryId: diaryId,
wakeUp: wakeUp,
retire: retire,
);
finishDiaryDay({required int diaryId, required String wakeUp, required String retire, String? comment}) async {
await diaryRepository.finishDiaryDay(diaryId: diaryId, wakeUp: wakeUp, retire: retire, comment: comment);
await fetchDiary();
}
@@ -126,55 +115,23 @@ class DiaryCubit extends Cubit<DiaryState> {
await fetchDiary();
}
markEaten({
required int diaryId,
required int mealId,
required int portionId,
}) async {
await diaryRepository.markEaten(
diaryId: diaryId,
mealId: mealId,
portionId: portionId,
);
markEaten({required int diaryId, required int mealId, required int portionId}) async {
await diaryRepository.markEaten(diaryId: diaryId, mealId: mealId, portionId: portionId);
await fetchDiary();
}
unmarkEaten({
required int diaryId,
required int mealId,
required int portionId,
}) async {
await diaryRepository.unmarkEaten(
diaryId: diaryId,
mealId: mealId,
portionId: portionId,
);
unmarkEaten({required int diaryId, required int mealId, required int portionId}) async {
await diaryRepository.unmarkEaten(diaryId: diaryId, mealId: mealId, portionId: portionId);
await fetchDiary();
}
restore({
required int diaryId,
required int mealId,
required int portionId,
}) async {
await diaryRepository.restore(
diaryId: diaryId,
mealId: mealId,
portionId: portionId,
);
restore({required int diaryId, required int mealId, required int portionId}) async {
await diaryRepository.restore(diaryId: diaryId, mealId: mealId, portionId: portionId);
await fetchDiary();
}
deleteProductFromMeal({
required int diaryId,
required int mealId,
required int portionId,
}) async {
await diaryRepository.deleteProductFromMeal(
diaryId: diaryId,
mealId: mealId,
portionId: portionId,
);
deleteProductFromMeal({required int diaryId, required int mealId, required int portionId}) async {
await diaryRepository.deleteProductFromMeal(diaryId: diaryId, mealId: mealId, portionId: portionId);
await fetchDiary();
}
@@ -182,27 +139,13 @@ class DiaryCubit extends Cubit<DiaryState> {
return await glossaryRepository.getGlossaryListByQuery(query);
}
uploadPhotos({
required List<File> files,
required int diaryId,
}) async {
await diaryRepository.uploadPhotos(
files: await ImageCompressUtility.compressFilesList(files),
diaryId: diaryId,
mealId: selectedMeal,
);
uploadPhotos({required List<File> files, required int diaryId}) async {
await diaryRepository.uploadPhotos(files: await ImageCompressUtility.compressFilesList(files), diaryId: diaryId, mealId: selectedMeal);
await fetchDiary();
}
deletePhoto({
required DiaryPhotoModel photo,
required int diaryId,
}) async {
await diaryRepository.deletePhoto(
photo: photo,
diaryId: diaryId,
mealId: selectedMeal,
);
deletePhoto({required DiaryPhotoModel photo, required int diaryId}) async {
await diaryRepository.deletePhoto(photo: photo, diaryId: diaryId, mealId: selectedMeal);
await fetchDiary();
}
@@ -214,39 +157,37 @@ class DiaryCubit extends Cubit<DiaryState> {
required double carbohydrates,
}) async {
try {
return await diaryRepository.sendProductToModeration(
name: name,
energy: energy,
proteins: proteins,
fats: fats,
carbohydrates: carbohydrates,
);
return await diaryRepository.sendProductToModeration(name: name, energy: energy, proteins: proteins, fats: fats, carbohydrates: carbohydrates);
} catch (e, stackTrace) {
log(e.toString(), stackTrace: stackTrace);
}
return null;
}
fillTime({
required int diaryId,
required String time,
}) async {
await diaryRepository.fillTime(
diaryId: diaryId,
mealId: selectedMeal,
time: time,
);
fillTime({required int diaryId, required String time}) async {
await diaryRepository.fillTime(diaryId: diaryId, mealId: selectedMeal, time: time);
await fetchDiary();
}
fillSatiety({
required int diaryId,
required int satiety,
}) async {
await diaryRepository.fillSatiety(
diaryId: diaryId,
mealId: selectedMeal,
satiety: satiety,
);
fillWakeup({required int diaryId, required String time}) async {
await diaryRepository.fillWakeup(diaryId: diaryId, time: time);
await fetchDiary();
}
fillRetire({required int diaryId, required String time}) async {
await diaryRepository.fillRetire(diaryId: diaryId, time: time);
await fetchDiary();
}
fillSatiety({required int diaryId, required int satiety}) async {
await diaryRepository.fillSatiety(diaryId: diaryId, mealId: selectedMeal, satiety: satiety);
}
fillMood({required int diaryId, required int mood}) async {
await diaryRepository.fillMood(diaryId: diaryId, mealId: selectedMeal, mood: mood);
}
fillComment(String comment) {
emit((state as DiaryStateLoaded).copyWith(diary: (state as DiaryStateLoaded).diary.copyWith(comment: comment)));
}
}

View File

@@ -7,8 +7,10 @@ import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/calendar_widget.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/calories_chart_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/comment_for_consultant_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/finish_day_button_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/meal_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/wakeup_and_retire_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -46,8 +48,12 @@ class _DiaryScreenState extends State<DiaryScreen> {
children: [
CalendarWidget(),
if (state is DiaryStateLoading) const Loader(),
if (state is DiaryStateLoaded) WakeupAndRetireWidget(),
const SizedBox(height: 12),
if (state is DiaryStateLoaded) MealWidget(),
CaloriesChartWidget(),
if (state is DiaryStateLoaded) CaloriesChartWidget(),
const SizedBox(height: 12),
if (state is DiaryStateLoaded) CommentForConsultantWidget(),
if (state is DiaryStateLoaded && state.diary.closed == 0)
Padding(
padding: const EdgeInsets.only(top: 12),

View File

@@ -0,0 +1,44 @@
import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class CommentForConsultantWidget extends StatefulWidget {
const CommentForConsultantWidget({super.key});
@override
State<CommentForConsultantWidget> createState() => _CommentForConsultantWidgetState();
}
class _CommentForConsultantWidgetState extends State<CommentForConsultantWidget> {
@override
Widget build(BuildContext context) {
return Material(
borderRadius: BorderRadius.circular(20),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Дополнительная информация для консультанта',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF323F4B), height: 1),
),
const SizedBox(height: 12),
CustomTextFormField(
onChanged: (value) {
EasyDebounce.debounce('client-typing', Duration(seconds: 3), () => context.read<DiaryCubit>().fillComment(value));
},
hintText: 'Укажите дополнительную информацию',
minLines: 4,
maxLines: 4,
),
],
),
),
);
}
}

View File

@@ -7,10 +7,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
class FinishDayButtonWidget extends StatefulWidget {
final DiaryDayModel diaryDay;
const FinishDayButtonWidget({
super.key,
required this.diaryDay,
});
const FinishDayButtonWidget({super.key, required this.diaryDay});
@override
State<FinishDayButtonWidget> createState() => _FinishDayButtonWidgetState();
@@ -20,30 +17,22 @@ class _FinishDayButtonWidgetState extends State<FinishDayButtonWidget> {
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => context.read<DiaryCubit>().finishDiaryDay(
onTap:
() => context.read<DiaryCubit>().finishDiaryDay(
diaryId: widget.diaryDay.id,
wakeUp: widget.diaryDay.wakeup.toString(),
retire: widget.diaryDay.retire.toString(),
comment: widget.diaryDay.comment.isEmpty ? null : widget.diaryDay.comment,
),
borderRadius: BorderRadius.circular(20),
child: Ink(
padding: EdgeInsets.symmetric(horizontal: 8),
width: MediaQuery.of(context).size.width - 16,
decoration: BoxDecoration(
color: appTheme.blueA400,
borderRadius: BorderRadius.circular(20),
),
decoration: BoxDecoration(color: appTheme.blueA400, borderRadius: BorderRadius.circular(20)),
child: Container(
padding: EdgeInsets.all(16),
alignment: Alignment.center,
child: Text(
'Закончить день',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
child: Text('Закончить день', style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600)),
),
),
);

View File

@@ -1,5 +1,6 @@
import 'package:eatvio_app/features/diary/presentation/widgets/add_product_button_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/meal_button_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/mood_rating_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/photo_gallery_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/products_list_widget.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/satiety_rating_widget.dart';
@@ -53,6 +54,8 @@ class _MealWidgetState extends State<MealWidget> {
PhotoGalleryWidget(),
const SizedBox(height: 12),
SatietyRatingWidget(),
const SizedBox(height: 12),
MoodRatingWidget(),
],
),
),

View File

@@ -0,0 +1,199 @@
import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_svg/flutter_svg.dart';
class MoodRatingWidget extends StatefulWidget {
@override
State<MoodRatingWidget> createState() => _MoodRatingWidgetState();
}
class _MoodRatingWidgetState extends State<MoodRatingWidget> {
late double currentSelectedRating;
bool isFirstFetch = true;
@override
Widget build(BuildContext context) {
return BlocBuilder<DiaryCubit, DiaryState>(
builder: (BuildContext context, DiaryState state) {
if (state is DiaryStateLoaded) {
if (isFirstFetch) {
currentSelectedRating = state.diary.meals[state.selectedMeal - 1].mood.toDouble() + 1;
isFirstFetch = false;
}
return Padding(
padding: const EdgeInsets.only(top: 24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Ваше настроение после приёма пищи',
style: TextStyle(
fontSize: 16,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SvgPicture.asset(
'assets/icons/mood_1.svg',
height: 32,
width: 32,
),
RatingBar.builder(
initialRating: state.diary.meals[state.selectedMeal - 1].mood.toDouble() + 1,
itemCount: 6,
itemSize: MediaQuery.of(context).size.width / 6 - (124 / 6),
updateOnDrag: true,
itemBuilder: (context, index) {
switch (index) {
case 0:
return Container(
width: MediaQuery.of(context).size.width / 6,
height: 24,
margin: currentSelectedRating == 1 ? EdgeInsets.symmetric(horizontal: 2) : null,
decoration: BoxDecoration(
color: Color(0xFFC82222),
border: currentSelectedRating == 1
? Border.all(
width: 2,
color: Color(0xFFAA3333),
strokeAlign: BorderSide.strokeAlignOutside,
)
: null,
borderRadius: currentSelectedRating == 1
? BorderRadius.horizontal(
left: Radius.circular(8),
right: Radius.circular(2),
)
: BorderRadius.horizontal(
left: Radius.circular(8),
),
),
);
case 1:
return Container(
width: MediaQuery.of(context).size.width / 6,
height: 24,
margin: currentSelectedRating == 2 ? EdgeInsets.symmetric(horizontal: 2) : null,
decoration: BoxDecoration(
color: Color(0xFFFF3E3E),
border: currentSelectedRating == 2
? Border.all(
width: 2,
color: Color(0xFF550000),
strokeAlign: BorderSide.strokeAlignOutside,
)
: null,
borderRadius: currentSelectedRating == 2 ? BorderRadius.circular(2) : null,
),
);
case 2:
return Container(
width: MediaQuery.of(context).size.width / 6,
height: 24,
margin: currentSelectedRating == 3 ? EdgeInsets.symmetric(horizontal: 2) : null,
decoration: BoxDecoration(
color: Color(0xFFF8C926),
border: currentSelectedRating == 3
? Border.all(
width: 2,
color: Color(0xFF8C5D00),
strokeAlign: BorderSide.strokeAlignOutside,
)
: null,
borderRadius: currentSelectedRating == 3 ? BorderRadius.circular(2) : null,
),
);
case 3:
return Container(
width: MediaQuery.of(context).size.width / 6,
height: 24,
margin: currentSelectedRating == 4 ? EdgeInsets.symmetric(horizontal: 2) : null,
decoration: BoxDecoration(
color: Color(0xFFFFF3BF),
border: currentSelectedRating == 4
? Border.all(
width: 2,
color: Color(0xFFB5911B),
strokeAlign: BorderSide.strokeAlignOutside,
)
: null,
borderRadius: currentSelectedRating == 4 ? BorderRadius.circular(2) : null,
),
);
case 4:
return Container(
width: MediaQuery.of(context).size.width / 6,
height: 24,
margin: currentSelectedRating == 5 ? EdgeInsets.symmetric(horizontal: 2) : null,
decoration: BoxDecoration(
color: Color(0xFF62E833),
border: currentSelectedRating == 5
? Border.all(
width: 2,
color: Color(0xFF276918),
strokeAlign: BorderSide.strokeAlignOutside,
)
: null,
borderRadius: currentSelectedRating == 5 ? BorderRadius.circular(2) : null,
),
);
default:
return Container(
width: MediaQuery.of(context).size.width / 6,
height: 24,
margin: currentSelectedRating == 6 ? EdgeInsets.symmetric(horizontal: 2) : null,
decoration: BoxDecoration(
color: Color(0xFF4DCE20),
border: currentSelectedRating == 6
? Border.all(
width: 2,
color: Color(0xFF184D12),
strokeAlign: BorderSide.strokeAlignOutside,
)
: null,
borderRadius: currentSelectedRating == 6
? BorderRadius.horizontal(
left: Radius.circular(2),
right: Radius.circular(8),
)
: BorderRadius.horizontal(
right: Radius.circular(8),
),
),
);
}
},
onRatingUpdate: (value) {
setState(() {
currentSelectedRating = value;
});
EasyDebounce.debounce(
'change-satiety',
Duration(milliseconds: 250),
() {
context.read<DiaryCubit>().fillMood(diaryId: state.diary.id, mood: currentSelectedRating.toInt() - 1);
},
);
},
),
SvgPicture.asset(
'assets/icons/mood_2.svg',
height: 32,
width: 32,
),
],
),
],
),
);
}
return const SizedBox.shrink();
},
);
}
}

View File

@@ -21,7 +21,7 @@ class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
builder: (BuildContext context, DiaryState state) {
if (state is DiaryStateLoaded) {
if (isFirstFetch) {
currentSelectedRating = state.diary.meals[state.selectedMeal - 1].satiety.toDouble();
currentSelectedRating = state.diary.meals[state.selectedMeal - 1].satiety.toDouble() + 1;
isFirstFetch = false;
}
return Padding(
@@ -44,7 +44,7 @@ class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
width: 32,
),
RatingBar.builder(
initialRating: state.diary.meals[state.selectedMeal - 1].satiety.toDouble(),
initialRating: state.diary.meals[state.selectedMeal - 1].satiety.toDouble() + 1,
itemCount: 6,
itemSize: MediaQuery.of(context).size.width / 6 - (124 / 6),
updateOnDrag: true,
@@ -176,7 +176,7 @@ class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
'change-satiety',
Duration(milliseconds: 250),
() {
context.read<DiaryCubit>().fillSatiety(diaryId: state.diary.id, satiety: currentSelectedRating.toInt());
context.read<DiaryCubit>().fillSatiety(diaryId: state.diary.id, satiety: currentSelectedRating.toInt() - 1);
},
);
},

View File

@@ -0,0 +1,229 @@
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../../../core/theme/theme_helper.dart';
class WakeupAndRetireWidget extends StatefulWidget {
const WakeupAndRetireWidget({super.key});
@override
State<WakeupAndRetireWidget> createState() => _WakeupAndRetireWidgetState();
}
class _WakeupAndRetireWidgetState extends State<WakeupAndRetireWidget> {
late final DiaryCubit diaryCubit;
DateTime wakeup = DateTime.now().copyWith(hour: 6, minute: 30);
DateTime retire = DateTime.now().copyWith(hour: 22, minute: 30);
@override
void initState() {
super.initState();
diaryCubit = context.read<DiaryCubit>();
}
showTimePicker(int diaryId, bool isWakeup) {
showModalBottomSheet<void>(
context: context,
useRootNavigator: true,
builder:
(context) => SizedBox(
height: MediaQuery.of(context).copyWith().size.height / 3,
child: Column(
children: [
Expanded(
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.time,
use24hFormat: true,
initialDateTime: DateTime.now(),
onDateTimeChanged: (newTime) {
if (isWakeup) {
wakeup = newTime;
} else {
retire = newTime;
}
},
),
),
InkWell(
onTap: () {
Navigator.of(context).pop();
if (isWakeup) {
diaryCubit.fillWakeup(
diaryId: diaryId,
time:
'${wakeup.hour.toString().padLeft(2, '0')}:${wakeup.minute.toString().padLeft(2, '0')}:00',
);
} else {
diaryCubit.fillRetire(
diaryId: diaryId,
time:
'${retire.hour.toString().padLeft(2, '0')}:${retire.minute.toString().padLeft(2, '0')}:00',
);
}
},
borderRadius: BorderRadius.circular(20),
child: Ink(
width: MediaQuery.of(context).size.width - 16,
height: 52,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: appTheme.blueA400,
),
child: Center(
child: Text(
'Сохранить',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
),
),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return BlocBuilder<DiaryCubit, DiaryState>(
builder: (context, state) {
if (state is DiaryStateLoaded) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Row(
children: [
Expanded(
child: Material(
borderRadius: BorderRadius.circular(12),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 12,
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset('assets/icons/wakeup.svg'),
const SizedBox(width: 8),
Text(
'Подъём',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
height: 1,
),
),
],
),
const SizedBox(height: 8),
InkWell(
onTap: () => showTimePicker(state.diary.id, true),
borderRadius: BorderRadius.circular(100),
child: Ink(
height: 32,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: Color(0xFFF1F2F6),
),
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text(
state.diary.wakeup.toString().substring(
0,
state.diary.wakeup.toString().length - 3,
),
style: TextStyle(
color: Color(0xFF6D6F71),
fontSize: 17,
fontWeight: FontWeight.w500,
),
),
),
),
),
],
),
),
),
),
const SizedBox(width: 8),
Expanded(
child: Material(
borderRadius: BorderRadius.circular(12),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 12,
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset('assets/icons/retire.svg'),
const SizedBox(width: 8),
Text(
'Уход ко сну',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
height: 1,
),
),
],
),
const SizedBox(height: 8),
InkWell(
onTap: () => showTimePicker(state.diary.id, false),
borderRadius: BorderRadius.circular(100),
child: Ink(
height: 32,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: Color(0xFFF1F2F6),
),
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text(
state.diary.retire.toString().substring(
0,
state.diary.retire.toString().length - 3,
),
style: TextStyle(
color: Color(0xFF6D6F71),
fontSize: 17,
fontWeight: FontWeight.w500,
),
),
),
),
),
],
),
),
),
),
],
),
);
} else {
return SizedBox.shrink();
}
},
);
}
}

View File

@@ -158,12 +158,14 @@ class DiaryRepository {
required int diaryId,
required String wakeUp,
required String retire,
String? comment,
}) async {
return await diaryService.finishDiaryDay(
diary: diaryId,
finishDiaryDayModel: FinishDiaryDayModel(
wakeUp: wakeUp,
retire: retire,
comment: comment
),
);
}
@@ -202,6 +204,22 @@ class DiaryRepository {
}
}
Future<void> fillMood({
required int diaryId,
required int mealId,
required int mood,
}) async {
try {
return await diaryService.fillMood(
diary: diaryId,
typeNo: mealId,
mood: mood,
);
} catch (e) {
rethrow;
}
}
Future<void> fillTime({
required int diaryId,
required int mealId,
@@ -217,4 +235,32 @@ class DiaryRepository {
rethrow;
}
}
Future<void> fillWakeup({
required int diaryId,
required String time,
}) async {
try {
return await diaryService.fillWakeup(
diary: diaryId,
wakeUp: time,
);
} catch (e) {
rethrow;
}
}
Future<void> fillRetire({
required int diaryId,
required String time,
}) async {
try {
return await diaryService.fillRetire(
diary: diaryId,
retire: time,
);
} catch (e) {
rethrow;
}
}
}

View File

@@ -91,7 +91,7 @@ abstract class DiaryService {
@POST('/api/diary/{diary}/finishDay')
Future<void> finishDiaryDay({
@Path('diary') required int diary,
@Body() required FinishDiaryDayModel finishDiaryDayModel,
@Body(nullToAbsent: true) required FinishDiaryDayModel finishDiaryDayModel,
});
@POST('/api/diary/{diary}/meals/{type_no}/satiety/fill')
@@ -101,6 +101,13 @@ abstract class DiaryService {
@Field() required int satiety,
});
@POST('/api/diary/{diary}/meals/{type_no}/mood/fill')
Future<void> fillMood({
@Path('diary') required int diary,
@Path('type_no') required int typeNo,
@Field() required int mood,
});
@POST('/api/diary/{diary}/meals/{type_no}/time/fill')
Future<void> fillTime({
@Path('diary') required int diary,
@@ -108,6 +115,18 @@ abstract class DiaryService {
@Field() required String time,
});
@POST('/api/diary/{diary}/wakeUp/fill')
Future<void> fillWakeup({
@Path('diary') required int diary,
@Field() required String wakeUp,
});
@POST('/api/diary/{diary}/retire/fill')
Future<void> fillRetire({
@Path('diary') required int diary,
@Field() required String retire,
});
@POST('/api/diary/product_nutritional_values/sendToModeration')
Future<GlossaryModerationModel> sendProductToModeration({
@Body() required Map<String, dynamic> data,

View File

@@ -366,6 +366,29 @@ class _DiaryService implements DiaryService {
await _dio.fetch<void>(_options);
}
@override
Future<void> fillMood({
required int diary,
required int typeNo,
required int mood,
}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = {'mood': mood};
final _options = _setStreamType<void>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'/api/diary/${diary}/meals/${typeNo}/mood/fill',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
await _dio.fetch<void>(_options);
}
@override
Future<void> fillTime({
required int diary,
@@ -389,6 +412,44 @@ class _DiaryService implements DiaryService {
await _dio.fetch<void>(_options);
}
@override
Future<void> fillWakeup({required int diary, required String wakeUp}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = {'wakeUp': wakeUp};
final _options = _setStreamType<void>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'/api/diary/${diary}/wakeUp/fill',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
await _dio.fetch<void>(_options);
}
@override
Future<void> fillRetire({required int diary, required String retire}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = {'retire': retire};
final _options = _setStreamType<void>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'/api/diary/${diary}/retire/fill',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
await _dio.fetch<void>(_options);
}
@override
Future<GlossaryModerationModel> sendProductToModeration({
required Map<String, dynamic> data,

View File

@@ -73,6 +73,7 @@ dev_dependencies:
json_serializable: ^6.9.4
retrofit_generator: ^9.1.9
mockito: ^5.4.5
flutter_lints: ^5.0.0
flutter_test:
sdk: flutter