From 5e65118ab47aec051bc4b89a8c3b6ba12e92bed6 Mon Sep 17 00:00:00 2001 From: Vitalij Date: Mon, 16 Jun 2025 22:21:23 +0300 Subject: [PATCH] =?UTF-8?q?feature(settings):=20=D0=92=D0=B5=D1=80=D1=81?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dart_tool/package_config.json | 2 +- .flutter-plugins-dependencies | 2 +- assets/icons/settings_about.png | Bin 0 -> 1282 bytes assets/icons/settings_exit.png | Bin 0 -> 746 bytes assets/icons/settings_faq.png | Bin 0 -> 1331 bytes assets/icons/settings_mail.png | Bin 0 -> 811 bytes assets/icons/settings_name.png | Bin 0 -> 1391 bytes assets/icons/settings_notification.png | Bin 0 -> 1174 bytes assets/icons/settings_phone.png | Bin 0 -> 759 bytes assets/icons/settings_profile.png | Bin 0 -> 1477 bytes assets/icons/settings_share.png | Bin 0 -> 954 bytes assets/icons/settings_trash.png | Bin 0 -> 639 bytes lib/gen/assets.gen.dart | 50 ++ lib/i18n/strings.g.dart | 2 +- .../settings/cubit/settings_cubit.dart | 29 + .../cubit/settings_cubit.freezed.dart | 713 ++++++++++++++++++ .../settings/cubit/settings_state.dart | 10 + lib/screens/settings/settings_screen.dart | 40 +- lib/screens/settings/states/about.dart | 81 ++ lib/screens/settings/states/faq.dart | 92 +++ lib/screens/settings/states/initial.dart | 136 ++++ .../settings/states/notifications.dart | 103 +++ lib/screens/settings/states/profile.dart | 130 ++++ 23 files changed, 1386 insertions(+), 4 deletions(-) create mode 100644 assets/icons/settings_about.png create mode 100644 assets/icons/settings_exit.png create mode 100644 assets/icons/settings_faq.png create mode 100644 assets/icons/settings_mail.png create mode 100644 assets/icons/settings_name.png create mode 100644 assets/icons/settings_notification.png create mode 100644 assets/icons/settings_phone.png create mode 100644 assets/icons/settings_profile.png create mode 100644 assets/icons/settings_share.png create mode 100644 assets/icons/settings_trash.png create mode 100644 lib/screens/settings/cubit/settings_cubit.dart create mode 100644 lib/screens/settings/cubit/settings_cubit.freezed.dart create mode 100644 lib/screens/settings/cubit/settings_state.dart create mode 100644 lib/screens/settings/states/about.dart create mode 100644 lib/screens/settings/states/faq.dart create mode 100644 lib/screens/settings/states/initial.dart create mode 100644 lib/screens/settings/states/notifications.dart create mode 100644 lib/screens/settings/states/profile.dart diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json index 6a79b0d..5ec4839 100644 --- a/.dart_tool/package_config.json +++ b/.dart_tool/package_config.json @@ -1130,7 +1130,7 @@ "languageVersion": "3.7" } ], - "generated": "2025-06-16T17:17:10.994308Z", + "generated": "2025-06-16T19:03:33.328096Z", "generator": "pub", "generatorVersion": "3.7.0", "flutterRoot": "file:///Users/vitalijnecitajlo/fvm/versions/3.29.0", diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 733bb28..7ea77c9 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/fluttertoast-8.2.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false},{"name":"flutter_displaymode","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_displaymode-0.6.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_plugin_android_lifecycle","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.27/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/fluttertoast-8.2.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_android-2.2.16/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_macos","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_linux","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":false,"dependencies":["url_launcher_linux"],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_linux","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_windows","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":true,"dependencies":["url_launcher_windows"],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_windows","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.4/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_web","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/fluttertoast-8.2.12/","dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","dependencies":["url_launcher_web"],"dev_dependency":false},{"name":"url_launcher_web","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/url_launcher_web-2.4.0/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"file_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"flutter_displaymode","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"fluttertoast","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"share_plus","dependencies":["url_launcher_web","url_launcher_windows","url_launcher_linux"]},{"name":"sqlite3_flutter_libs","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2025-06-16 20:17:09.466652","version":"3.29.0","swift_package_manager_enabled":{"ios":false,"macos":false}} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/fluttertoast-8.2.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false},{"name":"flutter_displaymode","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_displaymode-0.6.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_plugin_android_lifecycle","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.27/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/fluttertoast-8.2.12/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_android-2.2.16/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_macos","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_linux","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":false,"dependencies":["url_launcher_linux"],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_linux","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_windows","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","native_build":true,"dependencies":["url_launcher_windows"],"dev_dependency":false},{"name":"sqlite3_flutter_libs","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/sqlite3_flutter_libs-0.5.32/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_windows","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.4/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"file_picker","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/file_picker-10.0.0/","dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_web","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false},{"name":"fluttertoast","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/fluttertoast-8.2.12/","dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/package_info_plus-8.3.0/","dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/share_plus-10.1.4/","dependencies":["url_launcher_web"],"dev_dependency":false},{"name":"url_launcher_web","path":"/Users/vitalijnecitajlo/.pub-cache/hosted/pub.dev/url_launcher_web-2.4.0/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"file_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"flutter_displaymode","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"fluttertoast","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"share_plus","dependencies":["url_launcher_web","url_launcher_windows","url_launcher_linux"]},{"name":"sqlite3_flutter_libs","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2025-06-16 22:03:31.911393","version":"3.29.0","swift_package_manager_enabled":{"ios":false,"macos":false}} \ No newline at end of file diff --git a/assets/icons/settings_about.png b/assets/icons/settings_about.png new file mode 100644 index 0000000000000000000000000000000000000000..3d4ae071f18570f224e9d989c95f706f22ebb369 GIT binary patch literal 1282 zcmV+d1^xPoP)#38Ew}&|Sqv9HX1qCrEmNBqxY`g4idpeS#>P)^Qe8cLkc*$_>;T z5J-`@w#eyw!@n^(q=!F(7S#tBB5BU>eQ(~pzX8@*l&}G;edV{csF z9{W7s`*Zieb{;DNY%<|BJh~icBlqtua8Ot9!rVke_TWi?e+T{Kr z@L9yM=xS5#t65Ioo6vF+zp3^}@VA^6a5SYf}4Mo-=iTMjezn0SOVDVI6?CjtOFB)D1;l9 zYZahKo_e07MAcCwAfo7p`bGM3pha;DU-esgkFFqbKe-f+1p(dr$VC>^ zRtU8MoYwsISFw;P5?G|UIJ19>6(UY+2GN~4ttk-D6EP0ozfe@gia?Ge?N~UF?@aHQ z-KaqNauDJLR)Bm>^7|)uVtUU=;NJy~VObF^3$`_hkwCs8B41otmzr=HDZq~ekbl$} z%N3li{i>RzG!n->nPk@wpKN)xNU#zp8b6>m;)6Ox5t|NqLhFjKvauDn|1OXOwHh6> zCNMP74yiDDSv96I7g9M5b;!~O)Mnvc5taZ`2k^TfYwMK3syA9_`vJ#dlUgku9a3yR z@;G2}2e2Q{Z{0+*BA`B!BY~EEeTMOzfieMSfj!$g+M0m+AfL!c^}&JmSP`jnY{c`B zXXE&?n-k`c&8AKzSc`!AxVf*NOg3c=QX%^{C0<$H5@MiEX@sh`S?GRl+?<}jIx7iQ zof1e;MWhCNlHjn-IYVOt3Dg0FLt1szVc*DNh)=6CA^(2DZ5OmeYXUmBZ*#dp=`Wc~ s=w$nZ+bh(e;4`pUSDtH)HP(pmAD(jnPMsNz)HkTRi)2e-k)||& zCvPwWY%8mo8OQ)&jCEbVFE_z`o6aS z-AQ6Tj`0p1+)!!`K|@;dL;OS9A_OKuu$+U2NCjZXWFy`(T+kHh91x+CwpC@AGPFQ3 z%ovO|^UVAT6;Lh!Czuoe0RM!E<2xLQaslZ0BIbf4u-nT%HP}Z_s&SXM4z{%vQTBlsNC^ zcFi`KX+K&C5S3}(c|ypX^e&la-Q zh69??mK`wKJrOn+qK%DVr``J*tnaQtGo%8-_1&DdyF$PjZVb2ghS6mPef=j4Z>v3A zYM^*^S}d=xqbWWXEhxUq*uP&XSz<5sfuoEFRhjDGb3l~M{{8Z8@}4@&XQxLLe&A?m cXlPK&1Biy&j-z?Yy8r+H07*qoM6N<$f;$FECjbBd literal 0 HcmV?d00001 diff --git a/assets/icons/settings_faq.png b/assets/icons/settings_faq.png new file mode 100644 index 0000000000000000000000000000000000000000..d1f2e378fa492b6d703c762dde7db6e7413fc3cd GIT binary patch literal 1331 zcmV-31bZx0%Rx7!j^VYP7vt?rcMy+1hP+H=>(=Wfov~kvI`K&;t?h{ zVC+CrOwP2cn)B)5r>A>n48wpQK!{ECr>eU?ueyP+_`DEk8N0s(J$%4G0$u5$s}@Nx zkpfZ2L-fbr{unKy6$N&;0v32rN*qwLThV<&i;k%O`RglxgobFOfD&BdcM@iRdWdNJ z@te2)DQcpY0{erYd-EPI`0I*)PiWRqNc=-)Gf|63GADr_>2IHu?X3_Z6!&m=@s}UL z5zY#*jVDtCC=0@7aV7*t7ngo$8vp3$pie$Ar2g9r%0%=zay2U_1=7V?_--+QIQ=%3 zN29SnahYqkPaDx8pCJ>}fA`=WTwHCR+0J9Fz>1w`fe)KHA}b;{5a_4j3HVhfnZZhd z)aI{|E<%GM5z``Lcbi>>6-rFJd$@1o6CNyZ^G+ReFPpqg;Tb#^&nf19!05`U3KEs5 zR6r#rfnnArM?G#+_zX%3fy1oLp_#*U)woIpXeV+fV~2fp=|96K0^2_11=!YKU;0nI4o;!bWZPV_m_SW^&3QoL zPwo2?I6`NX%%g0>DG9x&HP20bjSA=)k$H&=B}l{RAQ#G#N2TVI(+3K}#)8SH0Gk3A z+-b8*l%SFw<`aA6vePyZE+xT=ag||I%pGw)IdK~sj?VahrtJTWHsCqe%r;||CT)_g#zlDlFFAs`j`VRAzCjL`LNvPm~GVyP^8k#UE^t%2XAo>@1)$9NRBx9g1+;KGG!;JuWs+L{q76w*z_d6O4PMk57S zc#0xc4-xA?HO65RB^rg%4e*s|349R{snD3<-=$|(Hmf=J>FRSdLGvgyuYJ4X8+u~3 peCOrY&W(6Z;w~DR&{uqJd<2Ve11|<-VeDW`K~#7F?O028 z+AtKoGRdSPx`LP$gnR~_6%9%mk`t;n=js>V;G1$9qKz*}x-0`{|2(NWQR=4b^j}$&XLSj+}xm z1n#x(7-B2<=Gs2Ry`k)wKd}{La!urq*aFQ6>T_o!e-u@4nm;pw9HABL2{>Tt z#vJpM4tRjLoS}ffFPNl3`84>$=kG4J%g`;hMwT z!;YZlwglwkK*}dqy4>_5pb)tXtYs5)IdMJ?WoZXQeO|R&HTSYxBuTKisFNZp#*n$~~>fodGeRy=p5L;n@TYw8N50suMzkNxY7b^@W8FtC){}OKf9; zh!a&m)XPq=H62%OEthUgFp6ywGqAAd_@@X4+apMvATLlDWTt73;GQ6r;9epmC=6?Q ziJZW>G&o*Dg!g_(P?v@j>cY&yW$2t9h{`Q<2iqp$W{HaONnC?Z$&5_ZKQB=pTSV=ZV^4m;fvS&LcPgD|-o>Jr$=zzR zs0OGySq;XHpypP^I{W$xEi_nQw4;6IK7CX#ofb1q*2n65ife2{b0$YWX{nwBJ4;LY z!8aaFD1O#i%=QMd6>myGjaQB%s<}$*Z4IhWX6t?3DsbvC*AT@?uN16_T85_i p))VSE#)x&JyQyY8;DG-ce*o&W?JtI#AFcoZ002ovPDHLkV1hrmaDD&) literal 0 HcmV?d00001 diff --git a/assets/icons/settings_name.png b/assets/icons/settings_name.png new file mode 100644 index 0000000000000000000000000000000000000000..16b678c89abea786b95e713e35c0cd66a3447621 GIT binary patch literal 1391 zcmV-#1(5oQP)vS2~C0{7UzsGm}T7xV{aQh;~9RSxa}LN;G~x zqhJ^ZQ>sI7XEXdn+1BJ>!TrnYU`P*uH?P7jPWLes;Aupni|Zh$_I0Wa>9%U**i|?) zdihY~7$ex7fW~<2yp4D3^(N-7prpZVtPD2M*U9lfO}BIzc+2G)g(Xc&I=c86oM{|X z=igx;w-l1<{Mh7llCaB9q&a!mi2+#3nH-Cl}U$7Qa4Jz#w5Hop7PYfKyk}v$$%KUGOzjS}c+8f3G z#54$NTHYZROLF0O$IGGsBlW3Y;G_k$@tKMi9K0dK@mB9_MDP?c)1t&Yh+sl_`LI}t zz`-y?2xSJkF*B?VHiyZlwj2un{5y!}<}h$^l5(_|+QJvipilELwF86hk_GIxD&!dM zETMO%{%Y=GvDn#;gYS0U03R5W1@mDqe<9j78I0$zG**U4>*zbM3r`aq+oXgpSei}V zSY@Pn!FmLl8;yCBC&Wh1V`hXe*M9hzJkY^jhzMA-f{awEZe06H_y|4*ld{f>Zi=F)a~vk~x>~Gv*BeL&f4uQ0Q8214=&XkHw zMOf@!&0WmH1%HcO2U4AB{z7I!I;sl8=W$#-m%2F!IswrWXf(oV$9O+cecK%3K+LaJ zJ?x~D8SR+}V(zzkKj!ABr(V$sD>Z3_{TXN2`1yWrU=Cf9j^Vuf{J}(r=5Qv4>!@$8 zVnd?9nG)%7T}1qy68!Iu&Po&BT7o%JA{0+u&N8s5+C>!XHe#8}Yk$v{`Pg#OVgt4} z!ZSP^XnppURdQTUV2M6%5&j_Fa+SHHvDSf^%;;u4p~0ebES-CfYk+* zCid`u;&I%hcEfouWlTEmJZNfrM(BNMuYVD$f zXYB0WZ_o^ORGn;O9XXMUz=LJ4f$`q;tw26UNr(VV?u*N07Y=*19L@6)An)>cT((;8 zx^538G3UF40ofm)5b6B>#^gCjp+ni+k=&p^%-CjPCIQX?Xhs^UPUrVE%n5Wzj8jT_ zXI&>Zm`Q*-P0YS%&13czqI7aw)g!qk6PW~t$$ON6(en00APdVMx;PxIuo4HVE4RIk ztmjjcdN!i4j~}XTNfMz9scEzDaM@cU=|$OqzZBqln&OeV0yOy87xV0&)ZiKK_uQ8v zk>LET93zNDNZ&$YOn_!%8z&5zNN@%jr+`!fV!RJIh-n8FgNOs?LWoqsY$5Fi5$MXO z%r1=$dg%(b+8sUhtteRO{=JXbc`z;oue2Nj68%E?A8Y@l#mnl04{>?&&Ws!dI)svwCm< z+X`S0NF1Oo$s+GHnuyxefRAE(XV+~Y16tbXDn;YaqK_9+|CCq;6g)d5VQ%YqzFgw2 zlE;b6V=pa#@^+Hsv1ZwY$-y&>sS-RO9vF~*?BH#4IlxVmM{;8;kVI_U o(RqrJ^xh(+jCs7vIsO;?130ILbjc
    h($07*qoM6N<$f;QF|qW}N^ literal 0 HcmV?d00001 diff --git a/assets/icons/settings_phone.png b/assets/icons/settings_phone.png new file mode 100644 index 0000000000000000000000000000000000000000..d36e37a91f8a22f57159116e4fbd198e96d30e59 GIT binary patch literal 759 zcmVM<9Vp-4!n&Ea3zVCkQ86`>1Hca=&aZjd>`NL5t{ z8m8}2CPBy^4+R`4;*$`bu|59h`Mu{iz>y<0V7Brrq@ zvU3DDFj|3>d#11<&>c=?su$S>y$=d}OPWL}$RAH+2M+KIH+|CtvTktl2MstvD{wTC zzR-wdapE4*#n#4{Pm&0qHg1J1ZZvgs#69Rp>ZD5ME_yss8si%|gkut`84?$lR$L(1 zBl`d(3S^6|e31);KAr&2Hh}!DNq-?9ZCoG1F;;;b6cjMs<%K|}T2ys7#9H#lREnxc zgDC;qdfeb~p;;p7;KtUtZR@F<_5NKglgwUc_ zB7<(4`CADrQ+btr0fm3%SU{F+Bw3QJ_WLIWtC!L(ZWX$fK#fS=s-`YK*50c8V!j-g zw>~sNXM8KWx-M&wY~s@~H=`3JPCxV;Y({tGjVh!T$58N{m()jn*AA=&4nN4J?P`)R zwrn3Mi{3Rt+KJbjH@CLnI$v*Oi&7AuHp@Io;_j$D_z!XXg4)R5Ng#85D|_BOPHBmq z&gq9-yLlgbq(+~sRP45+w7&PKqH8LE_bM=E3!%m=5OWZLF&xdbb#+?g9eqc0@UU-& p^vN*A0-sM7xN=$i9y#(X`3pb{)u6Dbh-d%+002ovPDHLkV1h?QJ|qAD literal 0 HcmV?d00001 diff --git a/assets/icons/settings_profile.png b/assets/icons/settings_profile.png new file mode 100644 index 0000000000000000000000000000000000000000..178b79635763c9089a6b0e7d1fa503b6fb7344af GIT binary patch literal 1477 zcmV;$1v>hPP)5VS9AP7ref!wG;B1WsV*1o5MRhZ(=Ev>})itaAe^ zSrP39yZ5VckKOik&z}vuQurjxc29S8RabTW4bc;x@MA;JimaXYB50w^TF z?yKOP>C}aw4hWs+wQIgFV@VDCd~2X}cJa|aqMXPj0GrIWuk-;Y?=39vI3sz~?U%FR zy;|Uo*CK5$3etZ*BEQr3hgmdo39!2r+|WezF_`ed<+b0T6=3gG(13S3#sRrBV=TP5 z_Wi82PS%9TY&7QC6*?n&xhm!vUD&^r+%9>0T z*rend1#_B^bae5_KeMf|3b6MJ?DIPXq=-E<^V5AN_u_`MAc*_$v+X`uO-O!+pPxU8 z(}!lBq4qe?hN|Bx5idpq6-F9>3SHt-pW3Id=Z zg?*j`9SmtoFGT^S^J$hoQh$EJN+r_ggH-9S!LDXONn*;lg#C{S6IDGRSA%=W1q61-(5bN_dk1jx+6|3l=8#M4R6n2i4U zF(Dj1CMEBr=?<`c#*19C0GF`_0h@UvunAmWE+tGz%zFr9_>P}xn>4s~ zK=pRaDF&r5&U3&#XS#K5PvgB)dsj7P!^JrX4X|rOPBV-b%1IKHSO}l*J4y>`$OR`S z5aa|J32|CIJRhjJ8=OLbac?n!=O8v7(LNb~z2EBdOm5rkMg>iiC|0xSRN0?%g@&Jr zWG_k$BpoBTwfLhFKF_dGXC3wRRX-WXqD+_cyh?;*fKh;d?rE+Dg^ik%Eu_3C?i-GP zAm|NIPT<~zyyo)S+qad9d214DO}w)ioZ(?p8`{t6L~uQeBk|CM`;FM7ROT7wIu6Wm zM7Qf>YG?I(lFbBrMQ9bkLtg*WT6Ec_#kKQ{UM|y!&4Z%N1Zyf0;*_|M*M_Q0IL*r} zi$&%cSw83k+eFEnBWAA7i_OHow|Y6 zIf|u2%85b(M4KBr$r^^7is(@|hKk0nGDYLd5zIM4fNWC%6c&Jy($_BqK6OOolRWPO z3~S3H79@Igl#+T|z^|jupCjs*VLZlC0_ceBdSV{jIdD~TU>XEDxR`DXI<_DDm${Q z6uv8<9G)k~8jix%uRqph-1=Mz>}|;!d2k$OBLwQVch#OZyDjT9uEsqh&Uyd-cu1la z+4kvy9P^|?(SMOmL{5I*Ti0RR3RPuQz#+wYxzDi>(Kx?G5=g2R_qOE$(2HGyTZ}ed zQI9KHoCl9oBMbwr^)^~@wh=#uBZ*qn5p{R*6-PHs%SK8VN+5|^j3lIMPtG5W`uwwi zmcS%x(MOBcozWMmBO_?*z$9wXxBZl*^RBPai7C{gi5xIMVAg6eZ43}FIvDHt(mt#^ z2L#&a5txNqOdA6PIIg)!@i>uMq$Hk;5MuCA=nuzMi=4zx2XcQ)#umO=V`w3Z2(4JP z7%gP*j@AL)lLlg?L=v@FDM`~=!H-Bqz7(q@$bRP_B?2T>i>|$JHIex~sc^dC#McxK z$(KiOO)9<7KrQlklTMpaYH@Ezo}#~(W78&_Mb+zE_eR~YGH^=6!_XU>g%y0|uv(bj zDE~*G7u6zigAas~@5EyCMz#4dWp6Z70t`Q_Bn?g8`Hx+E9+po`;)8*|%Cl|IX=g=k zGVcrdQpI#Hmc7wsZ!|d;zBf9t+MS2qXn;x7Zmzvi9g?Ws+O_7Qvp<^+=)B(ohcn#>L%B;W+tCm`7%Bo<_WSeqLpH}DbQ23Z1m6xFsN z5W2DHCJ_REQtWoQ(*3LYSq5spI0Q%d?@kY_!cs@VH5xw>8ulk}pa}TA(krKwoNszSIJJsRjDtCXm*Y}G6Hx|KP#CF(Wb Zjt77avKEuKvH<`9002ovPDHLkV1fab9nSy& literal 0 HcmV?d00001 diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart index b0fcf60..872fcdc 100644 --- a/lib/gen/assets.gen.dart +++ b/lib/gen/assets.gen.dart @@ -21,6 +21,46 @@ class $AssetsIconsGen { /// File path: assets/icons/mail.png AssetGenImage get mail => const AssetGenImage('assets/icons/mail.png'); + /// File path: assets/icons/settings_about.png + AssetGenImage get settingsAbout => + const AssetGenImage('assets/icons/settings_about.png'); + + /// File path: assets/icons/settings_exit.png + AssetGenImage get settingsExit => + const AssetGenImage('assets/icons/settings_exit.png'); + + /// File path: assets/icons/settings_faq.png + AssetGenImage get settingsFaq => + const AssetGenImage('assets/icons/settings_faq.png'); + + /// File path: assets/icons/settings_mail.png + AssetGenImage get settingsMail => + const AssetGenImage('assets/icons/settings_mail.png'); + + /// File path: assets/icons/settings_name.png + AssetGenImage get settingsName => + const AssetGenImage('assets/icons/settings_name.png'); + + /// File path: assets/icons/settings_notification.png + AssetGenImage get settingsNotification => + const AssetGenImage('assets/icons/settings_notification.png'); + + /// File path: assets/icons/settings_phone.png + AssetGenImage get settingsPhone => + const AssetGenImage('assets/icons/settings_phone.png'); + + /// File path: assets/icons/settings_profile.png + AssetGenImage get settingsProfile => + const AssetGenImage('assets/icons/settings_profile.png'); + + /// File path: assets/icons/settings_share.png + AssetGenImage get settingsShare => + const AssetGenImage('assets/icons/settings_share.png'); + + /// File path: assets/icons/settings_trash.png + AssetGenImage get settingsTrash => + const AssetGenImage('assets/icons/settings_trash.png'); + /// File path: assets/icons/type=arrow_down.png AssetGenImage get typeArrowDown => const AssetGenImage('assets/icons/type=arrow_down.png'); @@ -221,6 +261,16 @@ class $AssetsIconsGen { back, call, mail, + settingsAbout, + settingsExit, + settingsFaq, + settingsMail, + settingsName, + settingsNotification, + settingsPhone, + settingsProfile, + settingsShare, + settingsTrash, typeArrowDown, typeBack, typeBold, diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index ad70738..d08ccee 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -6,7 +6,7 @@ /// Locales: 2 /// Strings: 20 (10 per locale) /// -/// Built on 2025-06-16 at 17:17 UTC +/// Built on 2025-06-16 at 19:03 UTC // coverage:ignore-file // ignore_for_file: type=lint, unused_import diff --git a/lib/screens/settings/cubit/settings_cubit.dart b/lib/screens/settings/cubit/settings_cubit.dart new file mode 100644 index 0000000..666ed86 --- /dev/null +++ b/lib/screens/settings/cubit/settings_cubit.dart @@ -0,0 +1,29 @@ +import 'package:bloc/bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'settings_state.dart'; +part 'settings_cubit.freezed.dart'; + +class SettingsCubit extends Cubit { + SettingsCubit() : super(SettingsState.initial()); + + Future toInitialState() async { + emit(SettingsState.initial()); + } + + Future toProfileState() async { + emit(SettingsState.profile()); + } + + Future toNotificationsState() async { + emit(SettingsState.notifications()); + } + + Future toFaqState() async { + emit(SettingsState.faq()); + } + + Future toAboutState() async { + emit(SettingsState.about()); + } +} diff --git a/lib/screens/settings/cubit/settings_cubit.freezed.dart b/lib/screens/settings/cubit/settings_cubit.freezed.dart new file mode 100644 index 0000000..2b321b5 --- /dev/null +++ b/lib/screens/settings/cubit/settings_cubit.freezed.dart @@ -0,0 +1,713 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'settings_cubit.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', +); + +/// @nodoc +mixin _$SettingsState { + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function() profile, + required TResult Function() notifications, + required TResult Function() faq, + required TResult Function() about, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? initial, + TResult? Function()? profile, + TResult? Function()? notifications, + TResult? Function()? faq, + TResult? Function()? about, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function()? profile, + TResult Function()? notifications, + TResult Function()? faq, + TResult Function()? about, + required TResult orElse(), + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_Profile value) profile, + required TResult Function(_Notifications value) notifications, + required TResult Function(_Faq value) faq, + required TResult Function(_About value) about, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Initial value)? initial, + TResult? Function(_Profile value)? profile, + TResult? Function(_Notifications value)? notifications, + TResult? Function(_Faq value)? faq, + TResult? Function(_About value)? about, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_Profile value)? profile, + TResult Function(_Notifications value)? notifications, + TResult Function(_Faq value)? faq, + TResult Function(_About value)? about, + required TResult orElse(), + }) => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SettingsStateCopyWith<$Res> { + factory $SettingsStateCopyWith( + SettingsState value, + $Res Function(SettingsState) then, + ) = _$SettingsStateCopyWithImpl<$Res, SettingsState>; +} + +/// @nodoc +class _$SettingsStateCopyWithImpl<$Res, $Val extends SettingsState> + implements $SettingsStateCopyWith<$Res> { + _$SettingsStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SettingsState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc +abstract class _$$InitialImplCopyWith<$Res> { + factory _$$InitialImplCopyWith( + _$InitialImpl value, + $Res Function(_$InitialImpl) then, + ) = __$$InitialImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$InitialImplCopyWithImpl<$Res> + extends _$SettingsStateCopyWithImpl<$Res, _$InitialImpl> + implements _$$InitialImplCopyWith<$Res> { + __$$InitialImplCopyWithImpl( + _$InitialImpl _value, + $Res Function(_$InitialImpl) _then, + ) : super(_value, _then); + + /// Create a copy of SettingsState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$InitialImpl implements _Initial { + const _$InitialImpl(); + + @override + String toString() { + return 'SettingsState.initial()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$InitialImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function() profile, + required TResult Function() notifications, + required TResult Function() faq, + required TResult Function() about, + }) { + return initial(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? initial, + TResult? Function()? profile, + TResult? Function()? notifications, + TResult? Function()? faq, + TResult? Function()? about, + }) { + return initial?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function()? profile, + TResult Function()? notifications, + TResult Function()? faq, + TResult Function()? about, + required TResult orElse(), + }) { + if (initial != null) { + return initial(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_Profile value) profile, + required TResult Function(_Notifications value) notifications, + required TResult Function(_Faq value) faq, + required TResult Function(_About value) about, + }) { + return initial(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Initial value)? initial, + TResult? Function(_Profile value)? profile, + TResult? Function(_Notifications value)? notifications, + TResult? Function(_Faq value)? faq, + TResult? Function(_About value)? about, + }) { + return initial?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_Profile value)? profile, + TResult Function(_Notifications value)? notifications, + TResult Function(_Faq value)? faq, + TResult Function(_About value)? about, + required TResult orElse(), + }) { + if (initial != null) { + return initial(this); + } + return orElse(); + } +} + +abstract class _Initial implements SettingsState { + const factory _Initial() = _$InitialImpl; +} + +/// @nodoc +abstract class _$$ProfileImplCopyWith<$Res> { + factory _$$ProfileImplCopyWith( + _$ProfileImpl value, + $Res Function(_$ProfileImpl) then, + ) = __$$ProfileImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$ProfileImplCopyWithImpl<$Res> + extends _$SettingsStateCopyWithImpl<$Res, _$ProfileImpl> + implements _$$ProfileImplCopyWith<$Res> { + __$$ProfileImplCopyWithImpl( + _$ProfileImpl _value, + $Res Function(_$ProfileImpl) _then, + ) : super(_value, _then); + + /// Create a copy of SettingsState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$ProfileImpl implements _Profile { + const _$ProfileImpl(); + + @override + String toString() { + return 'SettingsState.profile()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$ProfileImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function() profile, + required TResult Function() notifications, + required TResult Function() faq, + required TResult Function() about, + }) { + return profile(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? initial, + TResult? Function()? profile, + TResult? Function()? notifications, + TResult? Function()? faq, + TResult? Function()? about, + }) { + return profile?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function()? profile, + TResult Function()? notifications, + TResult Function()? faq, + TResult Function()? about, + required TResult orElse(), + }) { + if (profile != null) { + return profile(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_Profile value) profile, + required TResult Function(_Notifications value) notifications, + required TResult Function(_Faq value) faq, + required TResult Function(_About value) about, + }) { + return profile(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Initial value)? initial, + TResult? Function(_Profile value)? profile, + TResult? Function(_Notifications value)? notifications, + TResult? Function(_Faq value)? faq, + TResult? Function(_About value)? about, + }) { + return profile?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_Profile value)? profile, + TResult Function(_Notifications value)? notifications, + TResult Function(_Faq value)? faq, + TResult Function(_About value)? about, + required TResult orElse(), + }) { + if (profile != null) { + return profile(this); + } + return orElse(); + } +} + +abstract class _Profile implements SettingsState { + const factory _Profile() = _$ProfileImpl; +} + +/// @nodoc +abstract class _$$NotificationsImplCopyWith<$Res> { + factory _$$NotificationsImplCopyWith( + _$NotificationsImpl value, + $Res Function(_$NotificationsImpl) then, + ) = __$$NotificationsImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$NotificationsImplCopyWithImpl<$Res> + extends _$SettingsStateCopyWithImpl<$Res, _$NotificationsImpl> + implements _$$NotificationsImplCopyWith<$Res> { + __$$NotificationsImplCopyWithImpl( + _$NotificationsImpl _value, + $Res Function(_$NotificationsImpl) _then, + ) : super(_value, _then); + + /// Create a copy of SettingsState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$NotificationsImpl implements _Notifications { + const _$NotificationsImpl(); + + @override + String toString() { + return 'SettingsState.notifications()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$NotificationsImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function() profile, + required TResult Function() notifications, + required TResult Function() faq, + required TResult Function() about, + }) { + return notifications(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? initial, + TResult? Function()? profile, + TResult? Function()? notifications, + TResult? Function()? faq, + TResult? Function()? about, + }) { + return notifications?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function()? profile, + TResult Function()? notifications, + TResult Function()? faq, + TResult Function()? about, + required TResult orElse(), + }) { + if (notifications != null) { + return notifications(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_Profile value) profile, + required TResult Function(_Notifications value) notifications, + required TResult Function(_Faq value) faq, + required TResult Function(_About value) about, + }) { + return notifications(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Initial value)? initial, + TResult? Function(_Profile value)? profile, + TResult? Function(_Notifications value)? notifications, + TResult? Function(_Faq value)? faq, + TResult? Function(_About value)? about, + }) { + return notifications?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_Profile value)? profile, + TResult Function(_Notifications value)? notifications, + TResult Function(_Faq value)? faq, + TResult Function(_About value)? about, + required TResult orElse(), + }) { + if (notifications != null) { + return notifications(this); + } + return orElse(); + } +} + +abstract class _Notifications implements SettingsState { + const factory _Notifications() = _$NotificationsImpl; +} + +/// @nodoc +abstract class _$$FaqImplCopyWith<$Res> { + factory _$$FaqImplCopyWith(_$FaqImpl value, $Res Function(_$FaqImpl) then) = + __$$FaqImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$FaqImplCopyWithImpl<$Res> + extends _$SettingsStateCopyWithImpl<$Res, _$FaqImpl> + implements _$$FaqImplCopyWith<$Res> { + __$$FaqImplCopyWithImpl(_$FaqImpl _value, $Res Function(_$FaqImpl) _then) + : super(_value, _then); + + /// Create a copy of SettingsState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$FaqImpl implements _Faq { + const _$FaqImpl(); + + @override + String toString() { + return 'SettingsState.faq()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$FaqImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function() profile, + required TResult Function() notifications, + required TResult Function() faq, + required TResult Function() about, + }) { + return faq(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? initial, + TResult? Function()? profile, + TResult? Function()? notifications, + TResult? Function()? faq, + TResult? Function()? about, + }) { + return faq?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function()? profile, + TResult Function()? notifications, + TResult Function()? faq, + TResult Function()? about, + required TResult orElse(), + }) { + if (faq != null) { + return faq(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_Profile value) profile, + required TResult Function(_Notifications value) notifications, + required TResult Function(_Faq value) faq, + required TResult Function(_About value) about, + }) { + return faq(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Initial value)? initial, + TResult? Function(_Profile value)? profile, + TResult? Function(_Notifications value)? notifications, + TResult? Function(_Faq value)? faq, + TResult? Function(_About value)? about, + }) { + return faq?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_Profile value)? profile, + TResult Function(_Notifications value)? notifications, + TResult Function(_Faq value)? faq, + TResult Function(_About value)? about, + required TResult orElse(), + }) { + if (faq != null) { + return faq(this); + } + return orElse(); + } +} + +abstract class _Faq implements SettingsState { + const factory _Faq() = _$FaqImpl; +} + +/// @nodoc +abstract class _$$AboutImplCopyWith<$Res> { + factory _$$AboutImplCopyWith( + _$AboutImpl value, + $Res Function(_$AboutImpl) then, + ) = __$$AboutImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$AboutImplCopyWithImpl<$Res> + extends _$SettingsStateCopyWithImpl<$Res, _$AboutImpl> + implements _$$AboutImplCopyWith<$Res> { + __$$AboutImplCopyWithImpl( + _$AboutImpl _value, + $Res Function(_$AboutImpl) _then, + ) : super(_value, _then); + + /// Create a copy of SettingsState + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$AboutImpl implements _About { + const _$AboutImpl(); + + @override + String toString() { + return 'SettingsState.about()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$AboutImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function() profile, + required TResult Function() notifications, + required TResult Function() faq, + required TResult Function() about, + }) { + return about(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function()? initial, + TResult? Function()? profile, + TResult? Function()? notifications, + TResult? Function()? faq, + TResult? Function()? about, + }) { + return about?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function()? profile, + TResult Function()? notifications, + TResult Function()? faq, + TResult Function()? about, + required TResult orElse(), + }) { + if (about != null) { + return about(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_Profile value) profile, + required TResult Function(_Notifications value) notifications, + required TResult Function(_Faq value) faq, + required TResult Function(_About value) about, + }) { + return about(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Initial value)? initial, + TResult? Function(_Profile value)? profile, + TResult? Function(_Notifications value)? notifications, + TResult? Function(_Faq value)? faq, + TResult? Function(_About value)? about, + }) { + return about?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_Profile value)? profile, + TResult Function(_Notifications value)? notifications, + TResult Function(_Faq value)? faq, + TResult Function(_About value)? about, + required TResult orElse(), + }) { + if (about != null) { + return about(this); + } + return orElse(); + } +} + +abstract class _About implements SettingsState { + const factory _About() = _$AboutImpl; +} diff --git a/lib/screens/settings/cubit/settings_state.dart b/lib/screens/settings/cubit/settings_state.dart new file mode 100644 index 0000000..77b732c --- /dev/null +++ b/lib/screens/settings/cubit/settings_state.dart @@ -0,0 +1,10 @@ +part of 'settings_cubit.dart'; + +@freezed +class SettingsState with _$SettingsState { + const factory SettingsState.initial() = _Initial; + const factory SettingsState.profile() = _Profile; + const factory SettingsState.notifications() = _Notifications; + const factory SettingsState.faq() = _Faq; + const factory SettingsState.about() = _About; +} diff --git a/lib/screens/settings/settings_screen.dart b/lib/screens/settings/settings_screen.dart index 88be885..ad6761d 100644 --- a/lib/screens/settings/settings_screen.dart +++ b/lib/screens/settings/settings_screen.dart @@ -1,5 +1,20 @@ import 'package:auto_route/auto_route.dart'; +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/screens/settings/states/about.dart'; +import 'package:remever/screens/settings/states/faq.dart'; +import 'package:remever/screens/settings/states/initial.dart'; +import 'package:remever/screens/settings/states/notifications.dart'; +import 'package:remever/screens/settings/states/profile.dart'; +import 'package:remever/widgets/primary_button.dart'; @RoutePage() class SettingsScreen extends StatelessWidget { @@ -7,6 +22,29 @@ class SettingsScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return const Placeholder(color: Colors.red); + return BlocProvider( + create: (BuildContext context) => SettingsCubit(), + child: _buildMain(), + ); + } + + /// + /// Построение основного блока + /// + Widget _buildMain() { + return PopScope( + canPop: false, + child: BlocBuilder( + builder: (BuildContext context, state) { + return state.when( + initial: () => InitialSettingsState(), + profile: () => ProfileSettingsState(), + notifications: () => NotificationsSettingsState(), + faq: () => FaqSettingsState(), + about: () => AboutSettingsState(), + ); + }, + ), + ); } } diff --git a/lib/screens/settings/states/about.dart b/lib/screens/settings/states/about.dart new file mode 100644 index 0000000..14789d8 --- /dev/null +++ b/lib/screens/settings/states/about.dart @@ -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().toInitialState(); + }, + icon: Icon(CupertinoIcons.left_chevron), + color: Colors.black, + ), + actions: [ + 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, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/settings/states/faq.dart b/lib/screens/settings/states/faq.dart new file mode 100644 index 0000000..5fc698c --- /dev/null +++ b/lib/screens/settings/states/faq.dart @@ -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().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), + ), + ], + ); + } +} diff --git a/lib/screens/settings/states/initial.dart b/lib/screens/settings/states/initial.dart new file mode 100644 index 0000000..82bc426 --- /dev/null +++ b/lib/screens/settings/states/initial.dart @@ -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().toInitialState(); + case SettingsCubitType.profile: + context.read().toProfileState(); + case SettingsCubitType.notifications: + context.read().toNotificationsState(); + case SettingsCubitType.faq: + context.read().toFaqState(); + case SettingsCubitType.about: + context.read().toAboutState(); + } + } + + /// Кнопка "Написать разработчику" + Widget _buildContactDeveloperButton() { + return PrimaryButton( + child: AppTypography( + 'Написать разработчику', + color: AppColors.white, + type: Medium14px(), + ), + onTap: () {}, + ); + } +} + +/// Перечисление типов состояний для SettingsCubit +enum SettingsCubitType { initial, profile, notifications, faq, about } diff --git a/lib/screens/settings/states/notifications.dart b/lib/screens/settings/states/notifications.dart new file mode 100644 index 0000000..ff70502 --- /dev/null +++ b/lib/screens/settings/states/notifications.dart @@ -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().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, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/settings/states/profile.dart b/lib/screens/settings/states/profile.dart new file mode 100644 index 0000000..a3385c2 --- /dev/null +++ b/lib/screens/settings/states/profile.dart @@ -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().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); + } +} -- 2.49.1