├── linux ├── .gitignore ├── main.cc ├── flutter │ ├── generated_plugin_registrant.h │ ├── generated_plugin_registrant.cc │ └── generated_plugins.cmake └── my_application.h ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── 100.png │ │ │ ├── 102.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 128.png │ │ │ ├── 144.png │ │ │ ├── 152.png │ │ │ ├── 16.png │ │ │ ├── 167.png │ │ │ ├── 172.png │ │ │ ├── 180.png │ │ │ ├── 196.png │ │ │ ├── 20.png │ │ │ ├── 216.png │ │ │ ├── 256.png │ │ │ ├── 29.png │ │ │ ├── 32.png │ │ │ ├── 40.png │ │ │ ├── 48.png │ │ │ ├── 50.png │ │ │ ├── 512.png │ │ │ ├── 55.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 64.png │ │ │ ├── 66.png │ │ │ ├── 72.png │ │ │ ├── 76.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 88.png │ │ │ ├── 92.png │ │ │ ├── 1024.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── LaunchBackground.imageset │ │ │ ├── background.png │ │ │ ├── darkbackground.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ └── GoogleService-Info.plist ├── Runner.xcodeproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── firebase_app_id_file.json ├── RunnerTests │ └── RunnerTests.swift └── .gitignore ├── lib ├── domain │ ├── entities │ │ ├── account │ │ │ ├── wallats.dart │ │ │ ├── account_entity.dart │ │ │ └── orders.dart │ │ ├── payment │ │ │ └── payment_entity.dart │ │ └── product │ │ │ ├── product_entity.dart │ │ │ └── product_detail_entity.dart │ └── usecases │ │ ├── user │ │ ├── user_usecases.dart │ │ ├── delete_user_profile_usecase.dart │ │ ├── get_user_profile_by_id_usecase.dart │ │ ├── save_user_profile_usecase.dart │ │ └── update_user_profile_usecase.dart │ │ ├── favourites │ │ ├── favourites_usecases.dart │ │ ├── clear_favourites_products_usecase.dart │ │ ├── get_favourites_products_usecase.dart │ │ ├── delete_favourite_product_usecase.dart │ │ └── add_favourite_product_usecase.dart │ │ ├── base_usecase.dart │ │ ├── usecases.dart │ │ ├── auth │ │ ├── sign_out_usecase.dart │ │ ├── reset_password_usecase.dart │ │ ├── updata_email_usecase.dart │ │ ├── sign_with_facebook_usecase.dart │ │ ├── sign_with_google_usecase.dart │ │ ├── reauthenticate_user_usecase.dart │ │ ├── login_usecase.dart │ │ └── sign_up_usecase.dart │ │ ├── storage │ │ └── upload_image_usecase.dart │ │ ├── detail │ │ └── get_product_detail_by_id.dart │ │ ├── home │ │ └── get_home_products_usecase.dart │ │ ├── payment │ │ └── create_payment_intent_usecase.dart │ │ ├── search │ │ └── get_product_by_search_usecase.dart │ │ └── category │ │ └── get_products_by_filter_usecase.dart ├── controllers │ ├── on_boarding │ │ └── on_boarding_state.dart │ ├── main │ │ └── main_state.dart │ ├── checkout │ │ └── checkout_state.dart │ ├── rating │ │ └── rating_cubit.dart │ ├── app │ │ └── app_state.dart │ ├── splash │ │ └── splash_state.dart │ ├── map │ │ └── map_state.dart │ ├── favourite │ │ └── favourite_state.dart │ ├── payment │ │ └── payment_state.dart │ ├── auth │ │ └── auth_state.dart │ ├── profile │ │ └── profile_state.dart │ ├── address │ │ └── address_state.dart │ ├── cart │ │ └── cart_state.dart │ ├── filter │ │ ├── filter_state.dart │ │ └── filter_cubit.dart │ ├── home │ │ └── home_state.dart │ ├── bloc_observer │ │ └── my_bloc_observer.dart │ ├── user │ │ └── user_state.dart │ ├── search │ │ └── search_state.dart │ ├── category_product │ │ └── category_product_state.dart │ ├── product_detail │ │ ├── product_detail_state.dart │ │ └── product_detail_cubit.dart │ ├── theme │ │ └── theme_cubit.dart │ └── controllers.dart ├── core │ ├── utils │ │ ├── utils.dart │ │ ├── values.dart │ │ └── constants.dart │ ├── errors │ │ ├── failure.dart │ │ └── exceptions.dart │ ├── extensions │ │ ├── media_query_extension.dart │ │ ├── theme_extension.dart │ │ └── string_extension.dart │ ├── network_info │ │ └── network_info.dart │ └── functions │ │ └── state_renderer.dart ├── data │ ├── data_source │ │ ├── data_sources.dart │ │ ├── storage_remote_data_soruce.dart │ │ ├── payment_remote_data_source.dart │ │ ├── user_remote_data_source.dart │ │ ├── local_data_source.dart │ │ └── favourites_remote_data_source.dart │ ├── local │ │ └── location │ │ │ ├── location_service.dart │ │ │ └── location_service_impl.dart │ ├── remote │ │ ├── remote.dart │ │ ├── payment │ │ │ └── payment_service.dart │ │ ├── product │ │ │ └── product_service.dart │ │ ├── auth │ │ │ └── auth_service.dart │ │ └── firebase_storage │ │ │ └── storage_service.dart │ ├── repository │ │ ├── repositories.dart │ │ └── firebase_storage_repository_impl.dart │ ├── mappers │ │ └── payment_mappers.dart │ ├── models │ │ └── product │ │ │ ├── product_response.dart │ │ │ ├── product_model.dart │ │ │ └── product_detail_model.dart │ └── network │ │ └── dio_factory.dart ├── view │ ├── payment │ │ └── payment_screen.dart │ ├── home │ │ ├── pages │ │ │ ├── home_page.dart │ │ │ ├── profile_page.dart │ │ │ └── catalog_page.dart │ │ └── widgets │ │ │ ├── profile │ │ │ ├── custom_profile_appbar.dart │ │ │ ├── profile_body_section.dart │ │ │ └── custom_drop_menu.dart │ │ │ ├── main │ │ │ ├── menu_widget.dart │ │ │ └── custom_advanced_drawer.dart │ │ │ └── catalog │ │ │ └── catalog_appbar.dart │ ├── widgets │ │ ├── common │ │ │ ├── shimmer_effect.dart │ │ │ ├── custom_buttons.dart │ │ │ ├── custom_appbar.dart │ │ │ └── custom_elevated_button.dart │ │ ├── state_renderer │ │ │ ├── empty_state.dart │ │ │ └── loading │ │ │ │ ├── full_screen_loading_state.dart │ │ │ │ ├── loading_indicator_listview.dart │ │ │ │ └── loading_product_category_girdview.dart │ │ └── product │ │ │ └── product_card_listview.dart │ ├── settings │ │ └── settings_screen.dart │ ├── notifications │ │ └── notifications_screen.dart │ ├── views.dart │ ├── cart │ │ ├── cart_screen.dart │ │ └── widgets │ │ │ └── cart_body_section.dart │ ├── favourite │ │ ├── favourite_screen.dart │ │ └── widgets │ │ │ ├── favourite_body_section.dart │ │ │ └── favourites_products_girdview.dart │ ├── delivery │ │ ├── widgets │ │ │ └── map │ │ │ │ └── build_map.dart │ │ └── pages │ │ │ ├── delivery_address_screen.dart │ │ │ └── custom_google_map.dart │ ├── auth │ │ └── widgets │ │ │ ├── or_divider.dart │ │ │ ├── google_and_facebook_login.dart │ │ │ └── login_signup_logo_section.dart │ ├── search │ │ ├── widgets │ │ │ └── search_products_girdview.dart │ │ └── search_page.dart │ ├── on_boarding │ │ └── widget │ │ │ └── on_boarding_pageview.dart │ └── categories │ │ └── widgets │ │ └── category_body_section.dart └── config │ ├── language │ └── language_manager.dart │ └── services │ └── permissions.dart ├── macos ├── Flutter │ ├── Flutter-Debug.xcconfig │ └── Flutter-Release.xcconfig ├── Runner │ ├── Configs │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ ├── Warnings.xcconfig │ │ └── AppInfo.xcconfig │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_64.png │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_256.png │ │ │ └── app_icon_512.png │ ├── AppDelegate.swift │ ├── Release.entitlements │ ├── DebugProfile.entitlements │ ├── MainFlutterWindow.swift │ └── Info.plist ├── .gitignore ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcodeproj │ └── project.xcworkspace │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── RunnerTests │ └── RunnerTests.swift ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png └── manifest.json ├── assets ├── images │ └── app_icon.png ├── fonts │ ├── Cairo-Bold.ttf │ ├── Cairo-Medium.ttf │ ├── Cairo-Regular.ttf │ ├── Cairo-SemiBold.ttf │ ├── Montserrat-Bold.ttf │ ├── Montserrat-Thin.ttf │ ├── Montserrat-Italic.ttf │ ├── Montserrat-Medium.ttf │ ├── Montserrat-Regular.ttf │ └── Montserrat-SemiBold.ttf ├── icons │ ├── arrow_right.svg │ ├── right_arrow.svg │ ├── mines.svg │ ├── search.svg │ ├── double_arrow.svg │ ├── menu.svg │ ├── check.svg │ ├── dark_mode.svg │ ├── notifications.svg │ ├── trible_arrow.svg │ ├── profile.svg │ ├── facebook.svg │ ├── plus.svg │ ├── info.svg │ ├── Info_square.svg │ ├── profile_border.svg │ ├── update.svg │ ├── home_fill.svg │ ├── shopping_cart.svg │ ├── home.svg │ ├── logout.svg │ ├── heart.svg │ ├── buy_fill.svg │ ├── lock.svg │ ├── filter.svg │ ├── google_map.svg │ ├── heart_border.svg │ ├── document.svg │ ├── star.svg │ ├── edit.svg │ ├── email.svg │ ├── bag.svg │ ├── wallet.svg │ ├── mastercard.svg │ ├── notification.svg │ ├── visa.svg │ └── buy.svg └── jsons │ └── loading.json ├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── drawable │ │ │ │ │ ├── background.png │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ ├── background.png │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable-night │ │ │ │ │ ├── background.png │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable-night-v21 │ │ │ │ │ ├── background.png │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values-v31 │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-night-v31 │ │ │ │ │ └── styles.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ └── kotlin │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── fashion_app │ │ │ │ └── MainActivity.kt │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── google-services.json ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle └── build.gradle ├── windows ├── runner │ ├── resources │ │ └── app_icon.ico │ ├── resource.h │ ├── utils.h │ ├── runner.exe.manifest │ ├── flutter_window.h │ └── main.cpp ├── .gitignore └── flutter │ ├── generated_plugin_registrant.h │ ├── generated_plugins.cmake │ └── generated_plugin_registrant.cc ├── .gitignore ├── .metadata └── test └── widget_test.dart /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /lib/domain/entities/account/wallats.dart: -------------------------------------------------------------------------------- 1 | class Wallats {} 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/web/icons/Icon-512.png -------------------------------------------------------------------------------- /assets/images/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/images/app_icon.png -------------------------------------------------------------------------------- /assets/fonts/Cairo-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Cairo-Bold.ttf -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /assets/fonts/Cairo-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Cairo-Medium.ttf -------------------------------------------------------------------------------- /assets/fonts/Cairo-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Cairo-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/Cairo-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Cairo-SemiBold.ttf -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /assets/fonts/Montserrat-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Montserrat-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/Montserrat-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Montserrat-Thin.ttf -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /assets/fonts/Montserrat-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Montserrat-Italic.ttf -------------------------------------------------------------------------------- /assets/fonts/Montserrat-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Montserrat-Medium.ttf -------------------------------------------------------------------------------- /assets/fonts/Montserrat-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Montserrat-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/Montserrat-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/assets/fonts/Montserrat-SemiBold.ttf -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/drawable/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/drawable-v21/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/drawable-night/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-v21/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/android/app/src/main/res/drawable-night-v21/background.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aymanattieh77/fashion-app/HEAD/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png -------------------------------------------------------------------------------- /lib/controllers/on_boarding/on_boarding_state.dart: -------------------------------------------------------------------------------- 1 | part of 'on_boarding_cubit.dart'; 2 | 3 | @immutable 4 | abstract class OnBoardingState {} 5 | 6 | class OnBoardingInitial extends OnBoardingState {} 7 | -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/controllers/main/main_state.dart: -------------------------------------------------------------------------------- 1 | part of 'main_cubit.dart'; 2 | 3 | @immutable 4 | abstract class MainState {} 5 | 6 | class MainInitial extends MainState {} 7 | 8 | class MainNavigationBarChange extends MainState {} 9 | -------------------------------------------------------------------------------- /lib/domain/usecases/user/user_usecases.dart: -------------------------------------------------------------------------------- 1 | export 'delete_user_profile_usecase.dart'; 2 | export 'save_user_profile_usecase.dart'; 3 | export 'update_user_profile_usecase.dart'; 4 | export 'get_user_profile_by_id_usecase.dart'; 5 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/controllers/checkout/checkout_state.dart: -------------------------------------------------------------------------------- 1 | part of 'checkout_cubit.dart'; 2 | 3 | abstract class CheckoutState {} 4 | 5 | class CheckoutInitial extends CheckoutState {} 6 | 7 | class ChangePaymentMethod extends CheckoutState {} 8 | -------------------------------------------------------------------------------- /lib/controllers/rating/rating_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | 3 | class RatingCubit extends Cubit { 4 | RatingCubit() : super(0.0); 5 | 6 | void setRating(double rating) => emit(rating); 7 | } 8 | -------------------------------------------------------------------------------- /lib/core/utils/utils.dart: -------------------------------------------------------------------------------- 1 | export 'assets.dart'; 2 | export 'colors.dart'; 3 | export 'style.dart'; 4 | export '../functions/function.dart'; 5 | export 'strings.dart'; 6 | export '../extensions/string_extension.dart'; 7 | export 'constants.dart'; 8 | -------------------------------------------------------------------------------- /lib/controllers/app/app_state.dart: -------------------------------------------------------------------------------- 1 | part of 'app_cubit.dart'; 2 | 3 | abstract class AppState extends Equatable { 4 | const AppState(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class AppInitial extends AppState {} 11 | -------------------------------------------------------------------------------- /lib/domain/usecases/favourites/favourites_usecases.dart: -------------------------------------------------------------------------------- 1 | export 'add_favourite_product_usecase.dart'; 2 | export 'clear_favourites_products_usecase.dart'; 3 | export 'get_favourites_products_usecase.dart'; 4 | export 'delete_favourite_product_usecase.dart'; 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 6 | -------------------------------------------------------------------------------- /assets/icons/arrow_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/right_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/controllers/splash/splash_state.dart: -------------------------------------------------------------------------------- 1 | part of 'splash_cubit.dart'; 2 | 3 | abstract class SplashState extends Equatable { 4 | const SplashState(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class SplashInitial extends SplashState {} 11 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/fashion_app/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.fashion_app 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | import io.flutter.embedding.android.FlutterFragmentActivity 5 | 6 | class MainActivity: FlutterFragmentActivity() { 7 | } 8 | -------------------------------------------------------------------------------- /lib/controllers/map/map_state.dart: -------------------------------------------------------------------------------- 1 | part of 'map_cubit.dart'; 2 | 3 | abstract class MapState { 4 | const MapState(); 5 | } 6 | 7 | class LocationInitial extends MapState {} 8 | 9 | class LocationInfo extends MapState {} 10 | 11 | class LocationMarker extends MapState {} 12 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lib/data/data_source/data_sources.dart: -------------------------------------------------------------------------------- 1 | export 'address_remote_data_source.dart'; 2 | export 'favourites_remote_data_source.dart'; 3 | export 'local_data_source.dart'; 4 | export 'payment_remote_data_source.dart'; 5 | export 'user_remote_data_source.dart'; 6 | export 'product_remote_data_source.dart'; 7 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-night/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/firebase_app_id_file.json: -------------------------------------------------------------------------------- 1 | { 2 | "file_generated_by": "FlutterFire CLI", 3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", 4 | "GOOGLE_APP_ID": "1:489509362219:ios:e4c61a39b0123f0d04286e", 5 | "FIREBASE_PROJECT_ID": "chatme-f8dd8", 6 | "GCM_SENDER_ID": "489509362219" 7 | } -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/controllers/favourite/favourite_state.dart: -------------------------------------------------------------------------------- 1 | part of 'favourite_cubit.dart'; 2 | 3 | abstract class FavouriteState {} 4 | 5 | class FavouriteInitial extends FavouriteState {} 6 | 7 | class FavouriteFailure extends FavouriteState {} 8 | 9 | class FavouriteLoading extends FavouriteState {} 10 | 11 | class FavouriteSuccess extends FavouriteState {} 12 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /assets/icons/mines.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /macos/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import FlutterMacOS 2 | import Cocoa 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /lib/data/local/location/location_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:geocoding/geocoding.dart'; 2 | import 'package:geolocator/geolocator.dart'; 3 | 4 | abstract class LocationService { 5 | Future getMyCurrnetLocation(); 6 | Future?> getLocationInfromation( 7 | double latitude, double longitude); 8 | Future openLocationPageSettings(); 9 | } 10 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /lib/controllers/payment/payment_state.dart: -------------------------------------------------------------------------------- 1 | part of 'payment_cubit.dart'; 2 | 3 | abstract class PaymentState extends Equatable { 4 | const PaymentState(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class PaymentInitial extends PaymentState {} 11 | 12 | class PaymentSuccess extends PaymentState {} 13 | 14 | class PaymentFailure extends PaymentState {} 15 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /assets/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /lib/data/remote/remote.dart: -------------------------------------------------------------------------------- 1 | export 'auth/auth_service.dart'; 2 | export 'auth/auth_service_impl.dart'; 3 | export 'firebase_database/firebase_address_service.dart'; 4 | export 'firebase_database/firebase_favourite_service.dart'; 5 | export 'firebase_database/firebase_user_service.dart'; 6 | export 'payment/payment_service.dart'; 7 | export 'product/product_service.dart'; 8 | export 'firebase_storage/storage_service.dart'; 9 | -------------------------------------------------------------------------------- /assets/icons/double_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /lib/controllers/auth/auth_state.dart: -------------------------------------------------------------------------------- 1 | part of 'auth_cubit.dart'; 2 | 3 | @immutable 4 | abstract class AuthState {} 5 | 6 | class AuthInitial extends AuthState {} 7 | 8 | class AuthChange extends AuthState {} 9 | 10 | class AuthLoading extends AuthState {} 11 | 12 | class AuthFailure extends AuthState { 13 | final String message; 14 | AuthFailure(this.message); 15 | } 16 | 17 | class AuthSuccess extends AuthState {} 18 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/domain/usecases/base_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | import 'package:fashion_app/core/errors/failure.dart'; 4 | 5 | abstract class BaseUsecase { 6 | Future> call(Parameters parameters); 7 | } 8 | 9 | class NoParameters extends Equatable { 10 | const NoParameters(); 11 | @override 12 | List get props => []; 13 | } 14 | -------------------------------------------------------------------------------- /assets/icons/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /lib/controllers/profile/profile_state.dart: -------------------------------------------------------------------------------- 1 | part of 'profile_cubit.dart'; 2 | 3 | abstract class ProfileState extends Equatable { 4 | const ProfileState(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class ProfileInitial extends ProfileState {} 11 | 12 | class ProfileFailure extends ProfileState {} 13 | 14 | class ProfileUpdated extends ProfileState {} 15 | 16 | class ProfileReAuthenticate extends ProfileState {} 17 | -------------------------------------------------------------------------------- /lib/core/errors/failure.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | abstract class Failure extends Equatable { 4 | final String message; 5 | const Failure(this.message); 6 | @override 7 | List get props => [message]; 8 | } 9 | 10 | class FirebaseFailure extends Failure { 11 | const FirebaseFailure(super.message); 12 | } 13 | 14 | class LocalFailure extends Failure { 15 | const LocalFailure(super.message); 16 | } 17 | -------------------------------------------------------------------------------- /lib/data/repository/repositories.dart: -------------------------------------------------------------------------------- 1 | export 'auth_repository_impl.dart'; 2 | export 'category_product_repository.dart'; 3 | export 'firebase_address_repository_impl.dart'; 4 | export 'firebase_favourites_repository_impl.dart'; 5 | export 'firebase_user_repository_impl.dart'; 6 | export 'product_detail_repository.dart'; 7 | export 'home_product_repository.dart'; 8 | export 'search_product_repository.dart'; 9 | export 'payment_repository_impl.dart'; 10 | -------------------------------------------------------------------------------- /lib/controllers/address/address_state.dart: -------------------------------------------------------------------------------- 1 | part of 'address_cubit.dart'; 2 | 3 | abstract class AddressState {} 4 | 5 | class AddressInitial extends AddressState {} 6 | 7 | class AddressLoading extends AddressState {} 8 | 9 | class AddressFailure extends AddressState { 10 | final String message; 11 | AddressFailure(this.message); 12 | } 13 | 14 | class AddressUpdated extends AddressState {} 15 | 16 | class AddressLoaded extends AddressState {} 17 | -------------------------------------------------------------------------------- /lib/controllers/cart/cart_state.dart: -------------------------------------------------------------------------------- 1 | part of 'cart_cubit.dart'; 2 | 3 | abstract class CartState extends Equatable { 4 | const CartState(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class CartInitial extends CartState {} 11 | 12 | class AddToCart extends CartState {} 13 | 14 | class RemoveFromCart extends CartState {} 15 | 16 | class IncreaseCount extends CartState {} 17 | 18 | class DecreaseCount extends CartState {} 19 | -------------------------------------------------------------------------------- /lib/view/payment/payment_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/view/payment/widgets/payment_body_section.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class PaymentSuccessfullyScreen extends StatelessWidget { 5 | const PaymentSuccessfullyScreen({super.key}); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | return const Scaffold( 10 | body: SafeArea(child: PaymentBodySection()), 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/controllers/filter/filter_state.dart: -------------------------------------------------------------------------------- 1 | part of 'filter_cubit.dart'; 2 | 3 | @immutable 4 | abstract class FilterState {} 5 | 6 | class FilterInitial extends FilterState {} 7 | 8 | class FilterChangeCategoryTab extends FilterState {} 9 | 10 | class FilterPriceSilderChange extends FilterState {} 11 | 12 | class FilterDistanceSilderChange extends FilterState {} 13 | 14 | class FilterClear extends FilterState {} 15 | 16 | class FilterApply extends FilterState {} 17 | -------------------------------------------------------------------------------- /lib/controllers/home/home_state.dart: -------------------------------------------------------------------------------- 1 | part of 'home_cubit.dart'; 2 | 3 | @immutable 4 | abstract class HomeState {} 5 | 6 | class HomeInitial extends HomeState {} 7 | 8 | class CategoryProductTapChange extends HomeState {} 9 | 10 | class HomeProductLoading extends HomeState {} 11 | 12 | class HomeProductsFailure extends HomeState { 13 | final String message; 14 | HomeProductsFailure(this.message); 15 | } 16 | 17 | class HomeProductLoaded extends HomeState {} 18 | -------------------------------------------------------------------------------- /lib/controllers/bloc_observer/my_bloc_observer.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | 5 | class MyBlocObserver extends BlocObserver { 6 | @override 7 | void onChange(BlocBase bloc, Change change) { 8 | super.onChange(bloc, change); 9 | log(change.toString()); 10 | } 11 | 12 | @override 13 | void onCreate(BlocBase bloc) { 14 | super.onCreate(bloc); 15 | 16 | log(bloc.toString()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/domain/usecases/usecases.dart: -------------------------------------------------------------------------------- 1 | export 'auth/auth_usecase.dart'; 2 | export 'category/get_products_by_filter_usecase.dart'; 3 | export 'detail/get_product_detail_by_id.dart'; 4 | export 'favourites/favourites_usecases.dart'; 5 | export 'home/get_home_products_usecase.dart'; 6 | export 'payment/create_payment_intent_usecase.dart'; 7 | export 'search/get_product_by_search_usecase.dart'; 8 | export 'user/user_usecases.dart'; 9 | export 'storage/upload_image_usecase.dart'; 10 | -------------------------------------------------------------------------------- /lib/core/errors/exceptions.dart: -------------------------------------------------------------------------------- 1 | class ServerException implements Exception { 2 | final String message; 3 | ServerException({ 4 | required this.message, 5 | }); 6 | } 7 | 8 | class AuthException implements Exception { 9 | final String message; 10 | AuthException({ 11 | required this.message, 12 | }); 13 | } 14 | 15 | class FireException implements Exception { 16 | final String message; 17 | FireException({ 18 | required this.message, 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/controllers/user/user_state.dart: -------------------------------------------------------------------------------- 1 | part of 'user_cubit.dart'; 2 | 3 | abstract class UserState extends Equatable { 4 | const UserState(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class UserInitial extends UserState {} 11 | 12 | class UserFailure extends UserState {} 13 | 14 | class UserCreated extends UserState {} 15 | 16 | class UserUpdated extends UserState {} 17 | 18 | class UserDeleted extends UserState {} 19 | 20 | class UserLoaded extends UserState {} 21 | -------------------------------------------------------------------------------- /assets/icons/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/core/utils/values.dart: -------------------------------------------------------------------------------- 1 | abstract class AppPadding { 2 | static const p5 = 5.0; 3 | static const p15 = 15.0; 4 | static const p20 = 20.0; 5 | static const p50 = 50.0; 6 | } 7 | 8 | abstract class AppSizes { 9 | static const s5 = 5.0; 10 | static const s10 = 10.0; 11 | static const s15 = 15.0; 12 | static const s20 = 20.0; 13 | static const s24 = 24.0; 14 | static const s30 = 30.0; 15 | static const s50 = 50.0; 16 | static const s55 = 50.0; 17 | static const s100 = 100.0; 18 | } 19 | -------------------------------------------------------------------------------- /assets/icons/dark_mode.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "background.png", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "appearances" : [ 9 | { 10 | "appearance" : "luminosity", 11 | "value" : "dark" 12 | } 13 | ], 14 | "filename" : "darkbackground.png", 15 | "idiom" : "universal" 16 | } 17 | ], 18 | "info" : { 19 | "author" : "xcode", 20 | "version" : 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /assets/icons/notifications.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/view/home/pages/home_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/view/home/widgets/home/custom_home_appbar.dart'; 4 | import 'package:fashion_app/view/home/widgets/home/home_body_section.dart'; 5 | 6 | class HomePage extends StatelessWidget { 7 | const HomePage({super.key}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return const Scaffold( 12 | appBar: CustomHomeAppbar(), 13 | body: HomeBodySection(), 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchImage.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "LaunchImage@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "LaunchImage@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/view/home/pages/profile_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/view/home/widgets/profile/custom_profile_appbar.dart'; 4 | import 'package:fashion_app/view/home/widgets/profile/profile_body_section.dart'; 5 | 6 | class ProfilePage extends StatelessWidget { 7 | const ProfilePage({super.key}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return const Scaffold( 12 | appBar: CustomProfileAppbar(), 13 | body: ProfileBodySection(), 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/domain/entities/account/account_entity.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/domain/entities/account/address.dart'; 2 | import 'package:fashion_app/domain/entities/account/orders.dart'; 3 | import 'package:fashion_app/domain/entities/account/user.dart'; 4 | 5 | class AccountEntity { 6 | final UserModel user; 7 | final List? address; 8 | final List? orders; 9 | final List? favourites; 10 | AccountEntity({ 11 | this.favourites, 12 | required this.user, 13 | this.address, 14 | this.orders, 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /lib/controllers/search/search_state.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | part of 'search_cubit.dart'; 3 | 4 | abstract class SearchState {} 5 | 6 | class SearchInitial extends SearchState {} 7 | 8 | class Searchloading extends SearchState {} 9 | 10 | class Searchloaded extends SearchState {} 11 | 12 | class Searchfailure extends SearchState { 13 | String message; 14 | Searchfailure(this.message); 15 | } 16 | 17 | class RecentSearchesClear extends SearchState {} 18 | 19 | class SaveRecentSearches extends SearchState {} 20 | -------------------------------------------------------------------------------- /lib/data/data_source/storage_remote_data_soruce.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:fashion_app/data/remote/firebase_storage/storage_service.dart'; 4 | 5 | abstract class StorageRemoteDataSource { 6 | Future uploadAnImage(File file); 7 | } 8 | 9 | class StorageRemoteDataSourceImpl implements StorageRemoteDataSource { 10 | final StorageService _service; 11 | StorageRemoteDataSourceImpl(this._service); 12 | @override 13 | Future uploadAnImage(File file) async { 14 | return await _service.uploadAnImage(file); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/controllers/category_product/category_product_state.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | part of 'category_product_cubit.dart'; 3 | 4 | abstract class CategoryProductState {} 5 | 6 | class CategoryProductInitial extends CategoryProductState {} 7 | 8 | class CategoryProductLoading extends CategoryProductState {} 9 | 10 | class CategoryProductLoaded extends CategoryProductState {} 11 | 12 | class CategoryProductFailure extends CategoryProductState { 13 | final String message; 14 | CategoryProductFailure(this.message); 15 | } 16 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | import GoogleMaps 4 | 5 | @UIApplicationMain 6 | @objc class AppDelegate: FlutterAppDelegate { 7 | override func application( 8 | _ application: UIApplication, 9 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 10 | ) -> Bool { 11 | GMSServices.provideAPIKey("AIzaSyAo4NxFrg5xWCfBNzeLD0ZVUADKatE4iMA") 12 | GeneratedPluginRegistrant.register(with: self) 13 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /assets/icons/trible_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /lib/view/widgets/common/shimmer_effect.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:shimmer/shimmer.dart' as sh; 3 | 4 | class ShimmerEffect extends StatelessWidget { 5 | const ShimmerEffect({super.key, required this.child, required this.enabled}); 6 | final Widget child; 7 | final bool enabled; 8 | @override 9 | Widget build(BuildContext context) { 10 | return sh.Shimmer.fromColors( 11 | baseColor: Colors.grey.shade300, 12 | highlightColor: Colors.grey.shade100, 13 | enabled: enabled, 14 | child: child, 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/domain/usecases/auth/sign_out_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 5 | 6 | class SignoutUsecase extends BaseUsecase { 7 | final AuthRepository _authRepository; 8 | SignoutUsecase(this._authRepository); 9 | @override 10 | Future> call(NoParameters parameters) async { 11 | return await _authRepository.signOutFirebase(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assets/icons/profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /lib/controllers/product_detail/product_detail_state.dart: -------------------------------------------------------------------------------- 1 | part of 'product_detail_cubit.dart'; 2 | 3 | abstract class ProductDetailState extends Equatable { 4 | const ProductDetailState(); 5 | 6 | @override 7 | List get props => []; 8 | } 9 | 10 | class ProductDetailInitial extends ProductDetailState {} 11 | 12 | class ProductDetailLoading extends ProductDetailState {} 13 | 14 | class ProductDetailLoaded extends ProductDetailState {} 15 | 16 | class ProductDetailFailure extends ProductDetailState { 17 | final String message; 18 | const ProductDetailFailure(this.message); 19 | } 20 | -------------------------------------------------------------------------------- /lib/domain/usecases/auth/reset_password_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 5 | 6 | class ResetPasswordUsecase extends BaseUsecase { 7 | final AuthRepository _authRepository; 8 | ResetPasswordUsecase(this._authRepository); 9 | @override 10 | Future> call(String parameters) async { 11 | return await _authRepository.resetPassword(parameters); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/view/home/pages/catalog_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/view/home/widgets/catalog/catalog_appbar.dart'; 4 | import 'package:fashion_app/view/home/widgets/catalog/catalog_body_section.dart'; 5 | 6 | class CatalogPage extends StatelessWidget { 7 | const CatalogPage({super.key}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return const DefaultTabController( 12 | length: 2, 13 | child: Scaffold( 14 | appBar: CatalogAppbar(), 15 | body: CatalogBodySection(), 16 | ), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/view/settings/settings_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/view/settings/widgets/settings_body_section.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:fashion_app/core/utils/utils.dart'; 5 | import 'package:fashion_app/view/widgets/common/custom_appbar.dart'; 6 | 7 | class SettingScreen extends StatelessWidget { 8 | const SettingScreen({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return const Scaffold( 13 | appBar: CustomAppbar(title: AppStrings.settings), 14 | body: SettingsBodySection(), 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /assets/icons/facebook.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/core/extensions/media_query_extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | extension MediaQueryExtensions on BuildContext { 4 | double fullWidth() { 5 | return MediaQuery.of(this).size.width; 6 | } 7 | 8 | double fullHeight() { 9 | return MediaQuery.of(this).size.height; 10 | } 11 | 12 | double setWidth(double value) { 13 | /// value must between 0.0 -1.0 14 | return MediaQuery.of(this).size.width * value; 15 | } 16 | 17 | double setHeight(double value) { 18 | /// value must between 0.0 -1.0 19 | return MediaQuery.of(this).size.height * value; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/core/network_info/network_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:internet_connection_checker/internet_connection_checker.dart'; 2 | 3 | abstract class NetworkInfo { 4 | Future get isConnected; 5 | Future get connectionStatus; 6 | } 7 | 8 | class NetworkInfoImpl implements NetworkInfo { 9 | final InternetConnectionChecker _checker; 10 | NetworkInfoImpl(this._checker); 11 | @override 12 | Future get isConnected async => _checker.hasConnection; 13 | 14 | @override 15 | Future get connectionStatus async => 16 | _checker.connectionStatus; 17 | } 18 | -------------------------------------------------------------------------------- /lib/domain/usecases/user/delete_user_profile_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 5 | 6 | class DeleteUserProfileUsecase extends BaseUsecase { 7 | final FirebaseUserRepository _repository; 8 | DeleteUserProfileUsecase(this._repository); 9 | @override 10 | Future> call(String parameters) async { 11 | return await _repository.deleteUserProfile(parameters); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/domain/usecases/auth/updata_email_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart' 4 | show AuthRepository; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class UpdateEmailUsecase extends BaseUsecase { 8 | final AuthRepository _authRepository; 9 | UpdateEmailUsecase(this._authRepository); 10 | @override 11 | Future> call(String parameters) async { 12 | return await _authRepository.updateEmail(parameters); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/config/language/language_manager.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const String arabic = 'ar'; 4 | const String english = 'en'; 5 | const String assetsPathLocalization = 'assets/translations'; 6 | 7 | const Locale arabicLocale = Locale('ar', 'SA'); 8 | const Locale englishLocale = Locale('en', 'US'); 9 | 10 | enum LanguageType { english, arabic } 11 | 12 | extension LanguageTypeExtension on LanguageType { 13 | String getValue() { 14 | switch (this) { 15 | case LanguageType.english: 16 | return english; 17 | case LanguageType.arabic: 18 | return arabic; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/data/mappers/payment_mappers.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/data/models/payment/payment_response.dart'; 2 | import 'package:fashion_app/domain/entities/payment/payment_entity.dart'; 3 | 4 | extension PaymentResponseEx on PaymentResponse { 5 | toDomain() { 6 | return PaymentEntity( 7 | id: id ?? "", 8 | object: object ?? "", 9 | amount: amount ?? 0, 10 | created: created ?? 0, 11 | currency: currency ?? "USD", 12 | status: status ?? "", 13 | clientSecret: clientSecret ?? "", 14 | customer: customer ?? "", 15 | ephemeralKey: ephemeralKey ?? ""); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/domain/entities/payment/payment_entity.dart: -------------------------------------------------------------------------------- 1 | class PaymentEntity { 2 | final String id; 3 | final String object; 4 | final int amount; 5 | final int created; 6 | final String currency; 7 | final String status; 8 | final String customer; 9 | final String ephemeralKey; 10 | final String clientSecret; 11 | PaymentEntity({ 12 | required this.customer, 13 | required this.ephemeralKey, 14 | required this.clientSecret, 15 | required this.id, 16 | required this.object, 17 | required this.amount, 18 | required this.created, 19 | required this.currency, 20 | required this.status, 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /lib/domain/usecases/storage/upload_image_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dartz/dartz.dart'; 4 | import 'package:fashion_app/core/errors/failure.dart'; 5 | import 'package:fashion_app/domain/repository/repositories.dart'; 6 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 7 | 8 | class UploadImageUsecase implements BaseUsecase { 9 | final FirebaseStorageRepository _repository; 10 | UploadImageUsecase(this._repository); 11 | 12 | @override 13 | Future> call(File parameters) async { 14 | return await _repository.uploadAnImage(parameters); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assets/icons/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/controllers/theme/theme_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/config/services/prefs.dart'; 2 | import 'package:fashion_app/config/services/service_locator.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | class ThemeCubit extends Cubit { 7 | ThemeCubit(super.initialState); 8 | 9 | final prefs = getIt(); 10 | 11 | changeTheme(bool val) { 12 | if (prefs.isDark()) { 13 | prefs.saveThemeMode(false); 14 | emit(ThemeMode.light); 15 | } else { 16 | prefs.saveThemeMode(true); 17 | emit(ThemeMode.dark); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/domain/usecases/favourites/clear_favourites_products_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 5 | 6 | class ClearFavouritesProductsUsecase extends BaseUsecase { 7 | final FirebaseFavouriteRepository _repository; 8 | ClearFavouritesProductsUsecase(this._repository); 9 | @override 10 | Future> call(String parameters) async { 11 | return await _repository.clearFavouritesProducts(parameters); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/view/widgets/common/custom_buttons.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/core/utils/colors.dart'; 4 | import 'package:fashion_app/view/widgets/common/text_utils.dart'; 5 | 6 | Widget customButton({required String label, required Function() press}) { 7 | return ElevatedButton( 8 | style: ElevatedButton.styleFrom( 9 | backgroundColor: AppColor.orange, 10 | shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20))), 11 | onPressed: press, 12 | child: TextUtils( 13 | text: label, 14 | color: AppColor.white, 15 | fontSize: 14, 16 | ), 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /lib/domain/usecases/auth/sign_with_facebook_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 5 | import 'package:firebase_auth/firebase_auth.dart'; 6 | 7 | class SignInWithFacebook extends BaseUsecase { 8 | final AuthRepository _authRepository; 9 | SignInWithFacebook(this._authRepository); 10 | 11 | @override 12 | Future> call(NoParameters parameters) async { 13 | return await _authRepository.signInWithFacebook(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/domain/usecases/auth/sign_with_google_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 5 | import 'package:firebase_auth/firebase_auth.dart'; 6 | 7 | class SignINWithGoogleUsecase extends BaseUsecase { 8 | final AuthRepository _authRepository; 9 | SignINWithGoogleUsecase(this._authRepository); 10 | @override 11 | Future> call(NoParameters parameters) async { 12 | return await _authRepository.signInWithGoogle(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = fashion_app 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.fashionApp 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2023 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /lib/domain/usecases/user/get_user_profile_by_id_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/entities/account/user.dart'; 4 | import 'package:fashion_app/domain/repository/repositories.dart'; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class GetUserProfileByIdUseCase extends BaseUsecase { 8 | final FirebaseUserRepository _repository; 9 | GetUserProfileByIdUseCase(this._repository); 10 | @override 11 | Future> call(String parameters) async { 12 | return await _repository.getUserProfileById(parameters); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/data/remote/payment/payment_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:fashion_app/core/utils/constants.dart'; 3 | import 'package:fashion_app/data/models/payment/payment_response.dart'; 4 | import 'package:retrofit/retrofit.dart'; 5 | 6 | part 'payment_service.g.dart'; 7 | 8 | @RestApi(baseUrl: AppConstants.stripeBaseUrl) 9 | abstract class PaymentService { 10 | factory PaymentService(Dio dio, {String? baseUrl}) = _PaymentService; 11 | 12 | @POST("/payment_intents") 13 | Future createPaymentIntent( 14 | @Body() Map body); 15 | 16 | @GET("/payment_intent/:{id}") 17 | Future retrievePaymentIntent(@Path("id") String id); 18 | } 19 | -------------------------------------------------------------------------------- /lib/view/notifications/notifications_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/utils/utils.dart'; 2 | import 'package:fashion_app/view/widgets/common/custom_appbar.dart'; 3 | import 'package:fashion_app/view/widgets/state_renderer/empty_state.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | class NotiFicationScreen extends StatelessWidget { 7 | const NotiFicationScreen({super.key}); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return const Scaffold( 12 | appBar: CustomAppbar(title: AppStrings.notification), 13 | body: EmptyState( 14 | icon: Icons.notifications_none, 15 | message: AppStrings.noNotificationsFound, 16 | )); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /lib/domain/usecases/detail/get_product_detail_by_id.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/entities/product/product_detail_entity.dart'; 4 | import 'package:fashion_app/domain/repository/repositories.dart'; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class GetProdcutDetailById implements BaseUsecase { 8 | final ProductDetailRepository _repository; 9 | GetProdcutDetailById(this._repository); 10 | @override 11 | Future> call(int parameters) async { 12 | return await _repository.getProdcutDetail(productId: parameters); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/view/home/widgets/profile/custom_profile_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/utils/values.dart'; 2 | import 'package:fashion_app/view/home/widgets/main/menu_widget.dart'; 3 | import 'package:fashion_app/view/home/widgets/profile/custom_drop_menu.dart'; 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | class CustomProfileAppbar extends StatelessWidget 8 | implements PreferredSizeWidget { 9 | const CustomProfileAppbar({super.key}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return AppBar( 14 | leading: const MenuIconWidget(), 15 | actions: const [CustomDropMenu()], 16 | ); 17 | } 18 | 19 | @override 20 | Size get preferredSize => const Size.fromHeight(AppSizes.s55); 21 | } 22 | -------------------------------------------------------------------------------- /lib/view/views.dart: -------------------------------------------------------------------------------- 1 | // export all app screens 2 | export 'auth/auth_screen.dart'; 3 | export 'splash/splash_screen.dart'; 4 | export 'checkout/checkout_screen.dart'; 5 | export 'on_boarding/on_boarding_screen.dart'; 6 | export 'home/home_screen.dart'; 7 | export 'favourite/favourite_screen.dart'; 8 | export 'notifications/notifications_screen.dart'; 9 | export 'delivery/pages/delivery_address_screen.dart'; 10 | export 'settings/settings_screen.dart'; 11 | export 'settings/profile_settings.dart'; 12 | export 'search/search_page.dart'; 13 | export 'product_details/product_details_screen.dart'; 14 | export 'categories/categories_screen.dart'; 15 | export 'cart/cart_screen.dart'; 16 | export 'about/about_screen.dart'; 17 | export 'payment/payment_screen.dart'; 18 | -------------------------------------------------------------------------------- /assets/icons/info.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/icons/Info_square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /assets/icons/profile_border.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /lib/domain/usecases/favourites/get_favourites_products_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/entities/account/favourites.dart'; 4 | import 'package:fashion_app/domain/repository/repositories.dart'; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class GetFavouritesProductsUsecase 8 | extends BaseUsecase, String> { 9 | final FirebaseFavouriteRepository _repository; 10 | GetFavouritesProductsUsecase(this._repository); 11 | @override 12 | Future>> call( 13 | String parameters) async { 14 | return await _repository.getFavourtiesProducts(parameters); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assets/icons/update.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/view/cart/cart_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/utils/utils.dart'; 2 | import 'package:fashion_app/view/cart/widgets/cart_body_section.dart'; 3 | import 'package:fashion_app/view/cart/widgets/checkout_and_subtotal.dart'; 4 | import 'package:fashion_app/view/widgets/common/custom_appbar.dart'; 5 | import 'package:flutter/material.dart'; 6 | 7 | class CartScreen extends StatelessWidget { 8 | const CartScreen({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return const Scaffold( 13 | appBar: CustomAppbar(title: AppStrings.myCart), 14 | body: CartBodySection(), 15 | floatingActionButton: CheckoutAndSubtotal(), 16 | floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/domain/usecases/auth/reauthenticate_user_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart' 4 | show AuthRepository; 5 | import 'package:fashion_app/domain/usecases/auth/login_usecase.dart'; 6 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 7 | 8 | class ReAuthenticatesUserUsecase extends BaseUsecase { 9 | final AuthRepository _authRepository; 10 | ReAuthenticatesUserUsecase(this._authRepository); 11 | @override 12 | Future> call(LoginUsecaseInputs parameters) async { 13 | return await _authRepository.reAuthenticatesUser( 14 | parameters.email, parameters.password); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/view/home/widgets/main/menu_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/controllers/main/main_cubit.dart'; 2 | import 'package:fashion_app/core/utils/assets.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | import 'package:flutter_svg/flutter_svg.dart'; 6 | 7 | class MenuIconWidget extends StatelessWidget { 8 | const MenuIconWidget({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return IconButton( 13 | onPressed: BlocProvider.of(context).handleMenuButtonPressed, 14 | icon: SvgPicture.asset( 15 | AssetsIconPath.menu, 16 | colorFilter: 17 | ColorFilter.mode(Theme.of(context).primaryColor, BlendMode.srcIn), 18 | ), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/core/extensions/theme_extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | import 'package:fashion_app/config/language/language_manager.dart'; 3 | import 'package:fashion_app/core/utils/colors.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | extension ThemeContextExtension on BuildContext { 7 | Color get primaryColor { 8 | return Theme.of(this).primaryColor; 9 | } 10 | 11 | Color get primaryColorLight { 12 | return Theme.of(this).primaryColorLight; 13 | } 14 | 15 | Color get scaffoldBackgroundColor { 16 | return Theme.of(this).scaffoldBackgroundColor; 17 | } 18 | 19 | bool get isDark { 20 | return Theme.of(this).scaffoldBackgroundColor == AppColor.blackBg; 21 | } 22 | 23 | bool get isRTL { 24 | return locale == arabicLocale; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.3.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath 'com.google.gms:google-services:4.3.15' 12 | 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | google() 19 | mavenCentral() 20 | } 21 | } 22 | 23 | rootProject.buildDir = '../build' 24 | subprojects { 25 | project.buildDir = "${rootProject.buildDir}/${project.name}" 26 | } 27 | subprojects { 28 | project.evaluationDependsOn(':app') 29 | } 30 | 31 | tasks.register("clean", Delete) { 32 | delete rootProject.buildDir 33 | } 34 | -------------------------------------------------------------------------------- /assets/icons/home_fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/view/widgets/state_renderer/empty_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/extensions/theme_extension.dart'; 2 | import 'package:fashion_app/view/widgets/common/text_utils.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class EmptyState extends StatelessWidget { 6 | const EmptyState({super.key, required this.icon, required this.message}); 7 | final IconData icon; 8 | final String message; 9 | @override 10 | Widget build(BuildContext context) { 11 | return Center( 12 | child: Column( 13 | crossAxisAlignment: CrossAxisAlignment.center, 14 | mainAxisAlignment: MainAxisAlignment.center, 15 | children: [ 16 | Icon(icon, color: context.primaryColor, size: 150), 17 | TextUtils(text: message, fontSize: 25) 18 | ], 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/view/widgets/state_renderer/loading/full_screen_loading_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:lottie/lottie.dart'; 3 | 4 | class FullScreenLoadingState extends StatelessWidget { 5 | const FullScreenLoadingState({ 6 | super.key, 7 | }); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Scaffold( 12 | body: SizedBox( 13 | width: double.infinity, 14 | height: double.infinity, 15 | child: Center( 16 | child: Column( 17 | crossAxisAlignment: CrossAxisAlignment.center, 18 | mainAxisAlignment: MainAxisAlignment.center, 19 | children: [ 20 | Lottie.asset('assets/jsons/loading.json'), 21 | ], 22 | ), 23 | ), 24 | ), 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/core/extensions/string_extension.dart: -------------------------------------------------------------------------------- 1 | extension ExtenString on String { 2 | bool get isValidEmail { 3 | final emailRegExp = RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+"); 4 | 5 | return emailRegExp.hasMatch(this); 6 | } 7 | 8 | bool get isVaildName { 9 | final nameRegExp = 10 | RegExp(r"^\s*([A-Za-z]{1,}([\.,] |[-']| ))+[A-Za-z]+\.?\s*$"); 11 | return nameRegExp.hasMatch(this); 12 | } 13 | 14 | bool get isVaildPassword { 15 | // final passwordRegExp = RegExp( 16 | // r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\><*~]).{8,}/pre>'); 17 | 18 | return length > 6; 19 | 20 | //return passwordRegExp.hasMatch(this); 21 | } 22 | 23 | bool get isValidPhone { 24 | final phoneRegExp = RegExp(r"^\+?0[0-9]{10}$"); 25 | return phoneRegExp.hasMatch(this); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/data/remote/product/product_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:fashion_app/core/utils/constants.dart'; 3 | import 'package:fashion_app/data/models/product/product_detail_model.dart'; 4 | import 'package:fashion_app/data/models/product/product_response.dart'; 5 | import 'package:retrofit/retrofit.dart'; 6 | 7 | part 'product_service.g.dart'; 8 | 9 | @RestApi(baseUrl: AppConstants.baseUrl) 10 | abstract class ProductService { 11 | factory ProductService(Dio dio, {String? baseUrl}) = _ProductService; 12 | 13 | @GET(AppConstants.productDetailEndPoint) 14 | Future getProdcutDetail({@Query('id') required int id}); 15 | 16 | @GET(AppConstants.productEndPoint) 17 | Future getProdcuts( 18 | {@Queries() required Map queriesParameters}); 19 | } 20 | -------------------------------------------------------------------------------- /assets/icons/shopping_cart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/data/repository/firebase_storage_repository_impl.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dartz/dartz.dart'; 4 | 5 | import 'package:fashion_app/core/errors/exceptions.dart'; 6 | import 'package:fashion_app/core/errors/failure.dart'; 7 | 8 | import 'package:fashion_app/data/data_source/storage_remote_data_soruce.dart'; 9 | 10 | import 'package:fashion_app/domain/repository/repositories.dart'; 11 | 12 | class FirebaseStorageRepositoryImpl implements FirebaseStorageRepository { 13 | final StorageRemoteDataSource _source; 14 | FirebaseStorageRepositoryImpl(this._source); 15 | @override 16 | Future> uploadAnImage(File file) async { 17 | try { 18 | return Right(await _source.uploadAnImage(file)); 19 | } on FireException catch (e) { 20 | return Left(FirebaseFailure(e.message)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/domain/usecases/auth/login_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart' 4 | show AuthRepository; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | import 'package:firebase_auth/firebase_auth.dart'; 7 | 8 | class LoginUsecase extends BaseUsecase { 9 | final AuthRepository _authRepository; 10 | LoginUsecase(this._authRepository); 11 | @override 12 | Future> call(LoginUsecaseInputs parameters) async { 13 | return await _authRepository.login(parameters.email, parameters.password); 14 | } 15 | } 16 | 17 | class LoginUsecaseInputs { 18 | final String email; 19 | final String password; 20 | LoginUsecaseInputs(this.email, this.password); 21 | } 22 | -------------------------------------------------------------------------------- /assets/icons/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/controllers/controllers.dart: -------------------------------------------------------------------------------- 1 | // export all app cubits 2 | 3 | export 'address/address_cubit.dart'; 4 | export 'app/app_cubit.dart'; 5 | export 'auth/auth_cubit.dart'; 6 | export 'cart/cart_cubit.dart'; 7 | export 'category_product/category_product_cubit.dart'; 8 | export 'checkout/checkout_cubit.dart'; 9 | export 'favourite/favourite_cubit.dart'; 10 | export 'filter/filter_cubit.dart'; 11 | export 'home/home_cubit.dart'; 12 | export 'main/main_cubit.dart'; 13 | export 'map/map_cubit.dart'; 14 | export 'on_boarding/on_boarding_cubit.dart'; 15 | export 'payment/payment_cubit.dart'; 16 | export 'product_detail/product_detail_cubit.dart'; 17 | export 'profile/profile_cubit.dart'; 18 | export 'search/search_cubit.dart'; 19 | export 'splash/splash_cubit.dart'; 20 | export 'theme/theme_cubit.dart'; 21 | export 'user/user_cubit.dart'; 22 | export 'rating/rating_cubit.dart'; 23 | -------------------------------------------------------------------------------- /lib/data/local/location/location_service_impl.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/data/local/location/location_service.dart'; 2 | import 'package:geocoding/geocoding.dart'; 3 | import 'package:geolocator/geolocator.dart'; 4 | 5 | class LocationServiceImpl implements LocationService { 6 | @override 7 | Future> getLocationInfromation( 8 | double latitude, double longitude) async { 9 | return await placemarkFromCoordinates( 10 | latitude, 11 | longitude, 12 | localeIdentifier: 'en', 13 | ); 14 | } 15 | 16 | @override 17 | Future getMyCurrnetLocation() async { 18 | return await Geolocator.getCurrentPosition( 19 | desiredAccuracy: LocationAccuracy.high, 20 | ); 21 | } 22 | 23 | @override 24 | Future openLocationPageSettings() async { 25 | await Geolocator.openLocationSettings(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/data/remote/auth/auth_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | 3 | abstract class AuthService { 4 | Future singUpFirebase(String username, String email, String password); 5 | Future loginFirebase(String email, String password); 6 | Future signOutFirebase(); 7 | Future signInWithGoogle(); 8 | Future signInWithFacebook(); 9 | Future verifyPhoneNumber(String phone); 10 | Future resetPassword(String email); 11 | Future sendEmailVerification(); 12 | Future updatePassword(String password); 13 | Future updateEmail(String newEmail); 14 | Future updateUsername(String username); 15 | Future updateProfileImage(String image); 16 | Future reAuthenticatesUser(String email, String password); 17 | User? get getUserProfile; 18 | String? get getUserId; 19 | } 20 | -------------------------------------------------------------------------------- /lib/domain/usecases/favourites/delete_favourite_product_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 5 | 6 | class DeleteFavouriteProductUsecase 7 | extends BaseUsecase { 8 | final FirebaseFavouriteRepository _repository; 9 | DeleteFavouriteProductUsecase(this._repository); 10 | @override 11 | Future> call(DeleteFavouriteInputs parameters) async { 12 | return await _repository.deleteFavouriteProduct( 13 | parameters.productId, parameters.userUid); 14 | } 15 | } 16 | 17 | class DeleteFavouriteInputs { 18 | int productId; 19 | String userUid; 20 | DeleteFavouriteInputs(this.productId, this.userUid); 21 | } 22 | -------------------------------------------------------------------------------- /lib/domain/usecases/user/save_user_profile_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/entities/account/user.dart'; 4 | import 'package:fashion_app/domain/repository/repositories.dart'; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class SaveUserProfileUsecase extends BaseUsecase { 8 | final FirebaseUserRepository _repository; 9 | SaveUserProfileUsecase(this._repository); 10 | @override 11 | Future> call(SaveUserInputs parameters) async { 12 | return await _repository.createUserProfile( 13 | parameters.userModel, parameters.userUid); 14 | } 15 | } 16 | 17 | class SaveUserInputs { 18 | UserModel userModel; 19 | String userUid; 20 | SaveUserInputs(this.userModel, this.userUid); 21 | } 22 | -------------------------------------------------------------------------------- /assets/icons/logout.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/domain/usecases/user/update_user_profile_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/entities/account/user.dart'; 4 | import 'package:fashion_app/domain/repository/repositories.dart'; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class UpdateUserProfileUsecase extends BaseUsecase { 8 | final FirebaseUserRepository _repository; 9 | UpdateUserProfileUsecase(this._repository); 10 | @override 11 | Future> call(UpdateUserInputs parameters) async { 12 | return await _repository.updateUserProfile( 13 | parameters.userModel, parameters.userUid); 14 | } 15 | } 16 | 17 | class UpdateUserInputs { 18 | UserModel userModel; 19 | String userUid; 20 | UpdateUserInputs(this.userModel, this.userUid); 21 | } 22 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | #include 11 | 12 | void fl_register_plugins(FlPluginRegistry* registry) { 13 | g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = 14 | fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); 15 | file_selector_plugin_register_with_registrar(file_selector_linux_registrar); 16 | g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = 17 | fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); 18 | flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | 46 | .env -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/domain/usecases/auth/sign_up_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 5 | import 'package:firebase_auth/firebase_auth.dart'; 6 | 7 | class SignUpUsecase extends BaseUsecase { 8 | final AuthRepository _authRepository; 9 | SignUpUsecase(this._authRepository); 10 | @override 11 | Future> call(SignUpUsecaseInputs parameters) async { 12 | return await _authRepository.signUp( 13 | parameters.username, parameters.email, parameters.password); 14 | } 15 | } 16 | 17 | class SignUpUsecaseInputs { 18 | final String username; 19 | final String email; 20 | final String password; 21 | 22 | SignUpUsecaseInputs(this.username, this.email, this.password); 23 | } 24 | -------------------------------------------------------------------------------- /lib/domain/usecases/home/get_home_products_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/repository/repositories.dart'; 4 | 5 | import '../../entities/product/product_entity.dart'; 6 | import '../base_usecase.dart'; 7 | 8 | class GetHomeProductsUsecase 9 | implements BaseUsecase, HomeProductsInputs> { 10 | final HomeRepository _repository; 11 | GetHomeProductsUsecase(this._repository); 12 | @override 13 | Future>> call( 14 | HomeProductsInputs parameters) async { 15 | return await _repository.getHomeProducts( 16 | categoryId: parameters.categoryId, offset: parameters.offset); 17 | } 18 | } 19 | 20 | class HomeProductsInputs { 21 | final int categoryId; 22 | final int offset; 23 | HomeProductsInputs(this.categoryId, this.offset); 24 | } 25 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | file_selector_linux 7 | flutter_secure_storage_linux 8 | ) 9 | 10 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 11 | ) 12 | 13 | set(PLUGIN_BUNDLED_LIBRARIES) 14 | 15 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 16 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 17 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 19 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 20 | endforeach(plugin) 21 | 22 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 23 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 24 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 25 | endforeach(ffi_plugin) 26 | -------------------------------------------------------------------------------- /assets/icons/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/view/cart/widgets/cart_body_section.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/controllers/cart/cart_cubit.dart'; 2 | import 'package:fashion_app/core/utils/strings.dart'; 3 | import 'package:fashion_app/view/cart/widgets/cart_listview.dart'; 4 | import 'package:fashion_app/view/widgets/state_renderer/empty_state.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_bloc/flutter_bloc.dart'; 7 | 8 | class CartBodySection extends StatelessWidget { 9 | const CartBodySection({super.key}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return BlocBuilder( 14 | builder: (context, state) { 15 | if (BlocProvider.of(context).carts.isEmpty) { 16 | return const EmptyState( 17 | icon: Icons.shopping_basket, message: AppStrings.cartIsEmpty); 18 | } 19 | return const CartListView(); 20 | }, 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /assets/icons/buy_fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lib/data/models/product/product_response.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/data/models/product/product_model.dart'; 2 | 3 | class ProductResponse { 4 | final String? categoryName; 5 | final int? itemCount; 6 | final List? products; 7 | ProductResponse({ 8 | this.categoryName, 9 | this.itemCount, 10 | this.products, 11 | }); 12 | 13 | factory ProductResponse.fromJson(Map json) { 14 | return ProductResponse( 15 | categoryName: 16 | json['categoryName'] != null ? json['categoryName'] as String : null, 17 | itemCount: json['itemCount'] != null ? json['itemCount'] as int : null, 18 | products: json['products'] != null 19 | ? List.from( 20 | (json['products'] as List).map( 21 | (x) => ProductModel.fromJson(x as Map), 22 | ), 23 | ) 24 | : null, 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/domain/usecases/favourites/add_favourite_product_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/entities/account/favourites.dart'; 4 | import 'package:fashion_app/domain/repository/repositories.dart'; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class AddFavouriteProductUsecase extends BaseUsecase { 8 | final FirebaseFavouriteRepository _repository; 9 | AddFavouriteProductUsecase(this._repository); 10 | @override 11 | Future> call(AddFavouriteInputs parameters) async { 12 | return await _repository.addFavouriteProduct( 13 | parameters.favouriteProduct, parameters.userUid); 14 | } 15 | } 16 | 17 | class AddFavouriteInputs { 18 | ProductsFavourite favouriteProduct; 19 | String userUid; 20 | AddFavouriteInputs(this.favouriteProduct, this.userUid); 21 | } 22 | -------------------------------------------------------------------------------- /assets/icons/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/icons/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /assets/icons/google_map.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/data/network/dio_factory.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:pretty_dio_logger/pretty_dio_logger.dart'; 4 | 5 | abstract class DioFactroy { 6 | Dio getDio([Map? headers]); 7 | } 8 | 9 | class DioFactroyImpl implements DioFactroy { 10 | @override 11 | Dio getDio([Map? headers]) { 12 | Dio dio; 13 | final baseOptions = BaseOptions( 14 | connectTimeout: const Duration(milliseconds: 1000 * 30), 15 | receiveTimeout: const Duration(milliseconds: 1000 * 30), 16 | sendTimeout: const Duration(milliseconds: 1000 * 30), 17 | receiveDataWhenStatusError: true, 18 | headers: headers, 19 | ); 20 | dio = Dio(baseOptions); 21 | if (kDebugMode) { 22 | dio.interceptors.add( 23 | PrettyDioLogger( 24 | responseBody: false, 25 | requestHeader: true, 26 | ), 27 | ); 28 | } 29 | return dio; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/controllers/product_detail/product_detail_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:fashion_app/domain/entities/product/product_detail_entity.dart'; 3 | import 'package:fashion_app/domain/usecases/detail/get_product_detail_by_id.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | part 'product_detail_state.dart'; 7 | 8 | class ProductDetailCubit extends Cubit { 9 | ProductDetailCubit(this._usecase) : super(ProductDetailInitial()); 10 | final GetProdcutDetailById _usecase; 11 | 12 | ProductDetailEntity? productDetailEntity; 13 | 14 | getProdcutDetailById(int productId) async { 15 | emit(ProductDetailLoading()); 16 | (await _usecase.call(productId)).fold( 17 | (failure) { 18 | emit(ProductDetailFailure(failure.message)); 19 | }, 20 | (productDetail) { 21 | productDetailEntity = productDetail; 22 | emit(ProductDetailLoaded()); 23 | }, 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/data/remote/firebase_storage/storage_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:fashion_app/core/errors/exceptions.dart'; 4 | import 'package:firebase_storage/firebase_storage.dart'; 5 | 6 | abstract class StorageService { 7 | Future uploadAnImage(File file); 8 | } 9 | 10 | class StorageServiceImpl implements StorageService { 11 | final storage = FirebaseStorage.instance; 12 | 13 | @override 14 | Future uploadAnImage(File file) async { 15 | try { 16 | Reference storageReference = storage 17 | .ref() 18 | .child('images/${DateTime.now().millisecondsSinceEpoch.toString()}'); 19 | UploadTask uploadTask = storageReference.putFile(file); 20 | TaskSnapshot taskSnapshot = await uploadTask; 21 | String imageUrl = await taskSnapshot.ref.getDownloadURL(); 22 | return imageUrl; 23 | } on FirebaseException catch (e) { 24 | throw FireException(message: e.message ?? e.toString()); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | file_selector_windows 7 | firebase_core 8 | flutter_secure_storage_windows 9 | geolocator_windows 10 | permission_handler_windows 11 | ) 12 | 13 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 14 | ) 15 | 16 | set(PLUGIN_BUNDLED_LIBRARIES) 17 | 18 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 19 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 20 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 21 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 23 | endforeach(plugin) 24 | 25 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 26 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 27 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 28 | endforeach(ffi_plugin) 29 | -------------------------------------------------------------------------------- /assets/icons/heart_border.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/view/home/widgets/profile/profile_body_section.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/core/utils/values.dart'; 4 | 5 | import 'package:fashion_app/view/home/widgets/profile/personal_information_section.dart'; 6 | import 'package:fashion_app/view/home/widgets/profile/profile_header_section.dart'; 7 | import 'package:fashion_app/view/home/widgets/profile/rating_order_progress_section.dart'; 8 | 9 | class ProfileBodySection extends StatelessWidget { 10 | const ProfileBodySection({super.key}); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return const SingleChildScrollView( 15 | child: Column( 16 | crossAxisAlignment: CrossAxisAlignment.start, 17 | children: [ 18 | ProfileHeaderSection(), 19 | SizedBox(height: AppSizes.s20), 20 | RatingOrderProgressSection(), 21 | SizedBox(height: AppSizes.s20), 22 | PersonalInformationSection(), 23 | ], 24 | ), 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /assets/icons/document.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 17 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 18 | - platform: android 19 | create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 20 | base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /lib/view/favourite/favourite_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/controllers/favourite/favourite_cubit.dart'; 2 | import 'package:fashion_app/core/utils/utils.dart'; 3 | import 'package:fashion_app/view/favourite/widgets/favourite_body_section.dart'; 4 | import 'package:fashion_app/view/widgets/common/custom_appbar.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_bloc/flutter_bloc.dart'; 7 | 8 | class FavouriteScreen extends StatefulWidget { 9 | const FavouriteScreen({super.key}); 10 | 11 | @override 12 | State createState() => _FavouriteScreenState(); 13 | } 14 | 15 | class _FavouriteScreenState extends State { 16 | @override 17 | void initState() { 18 | super.initState(); 19 | BlocProvider.of(context).getFavouritesProducts(); 20 | } 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return const Scaffold( 25 | appBar: CustomAppbar(title: AppStrings.myFavorites), 26 | body: FavouriteBodySection(), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assets/icons/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/view/widgets/common/custom_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/extensions/theme_extension.dart'; 2 | import 'package:fashion_app/config/routes/route_context.dart'; 3 | import 'package:fashion_app/core/utils/values.dart'; 4 | 5 | import 'package:fashion_app/view/widgets/common/text_utils.dart'; 6 | import 'package:flutter/material.dart'; 7 | 8 | class CustomAppbar extends StatelessWidget implements PreferredSizeWidget { 9 | const CustomAppbar({super.key, required this.title}); 10 | final String title; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return AppBar( 15 | leading: IconButton( 16 | onPressed: () { 17 | context.back(); 18 | }, 19 | icon: Icon(Icons.arrow_back_ios, color: context.primaryColor), 20 | ), 21 | centerTitle: true, 22 | title: TextUtils( 23 | text: title, 24 | fontSize: 20, 25 | fontWe: FontWe.medium, 26 | ), 27 | ); 28 | } 29 | 30 | @override 31 | Size get preferredSize => const Size.fromHeight(AppSizes.s55); 32 | } 33 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fashion_app", 3 | "short_name": "fashion_app", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/view/delivery/widgets/map/build_map.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 4 | 5 | import 'package:fashion_app/controllers/map/map_cubit.dart'; 6 | 7 | class BuildMap extends StatelessWidget { 8 | const BuildMap({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | MapCubit cubit = BlocProvider.of(context); 13 | return Stack( 14 | children: [ 15 | BlocBuilder( 16 | builder: (context, state) { 17 | return GoogleMap( 18 | myLocationEnabled: true, 19 | myLocationButtonEnabled: true, 20 | markers: cubit.markers, 21 | onTap: cubit.onMapTap, 22 | mapType: MapType.normal, 23 | initialCameraPosition: cubit.getInitalCameraPosition, 24 | onMapCreated: cubit.onMapCreated, 25 | ); 26 | }, 27 | ), 28 | ], 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/view/auth/widgets/or_divider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/core/utils/colors.dart'; 4 | import 'package:fashion_app/core/utils/strings.dart'; 5 | import 'package:fashion_app/view/widgets/common/text_utils.dart'; 6 | 7 | class OrDivider extends StatelessWidget { 8 | const OrDivider({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return const Padding( 13 | padding: EdgeInsets.symmetric(horizontal: 50), 14 | child: Row( 15 | children: [ 16 | Expanded( 17 | child: Divider( 18 | thickness: 2, 19 | color: AppColor.gray, 20 | ), 21 | ), 22 | Padding( 23 | padding: EdgeInsets.symmetric(horizontal: 5), 24 | child: TextUtils(text: AppStrings.or, fontSize: 12), 25 | ), 26 | Expanded( 27 | child: Divider( 28 | thickness: 2, 29 | color: AppColor.gray, 30 | )), 31 | ], 32 | ), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /lib/view/delivery/pages/delivery_address_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/controllers/address/address_cubit.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:fashion_app/view/delivery/widgets/delivery/custom_delivery_appbar.dart'; 5 | import 'package:fashion_app/view/delivery/widgets/delivery/delivery_body_section.dart'; 6 | 7 | class DeliveryAddress extends StatefulWidget { 8 | const DeliveryAddress({super.key}); 9 | 10 | @override 11 | State createState() => _DeliveryAddressState(); 12 | } 13 | 14 | class _DeliveryAddressState extends State { 15 | late final AddressCubit cubit; 16 | 17 | @override 18 | void initState() { 19 | super.initState(); 20 | cubit = AddressCubit.getCubit(context); 21 | } 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return const Scaffold( 26 | appBar: CustomDeliveryAppbar(), 27 | body: DeliveryBodySection(), 28 | ); 29 | } 30 | 31 | @override 32 | void dispose() { 33 | cubit.dispose(); 34 | super.dispose(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /assets/icons/email.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /lib/domain/usecases/payment/create_payment_intent_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/entities/payment/payment_entity.dart'; 4 | import 'package:fashion_app/domain/repository/repositories.dart'; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class CreatePaymentIntentUsecase 8 | extends BaseUsecase { 9 | final PaymentRepository _repository; 10 | CreatePaymentIntentUsecase(this._repository); 11 | @override 12 | Future> call(PaymentInputs parameters) async { 13 | return await _repository.createPaymentIntent( 14 | amount: parameters.amount, 15 | currency: parameters.currency, 16 | paymentMethod: parameters.paymentMethod, 17 | ); 18 | } 19 | } 20 | 21 | class PaymentInputs { 22 | final String amount; 23 | final String currency; 24 | final String paymentMethod; 25 | PaymentInputs({ 26 | required this.amount, 27 | required this.currency, 28 | required this.paymentMethod, 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-v31/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /lib/domain/entities/product/product_entity.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'package:equatable/equatable.dart'; 3 | 4 | class ProductEntity extends Equatable { 5 | final int id; 6 | final String name; 7 | final double price; 8 | final String currency; 9 | final String brandName; 10 | final String colour; 11 | final int productCode; 12 | final String url; 13 | final String imageUrl; 14 | final List additionalImageUrls; 15 | const ProductEntity({ 16 | required this.id, 17 | required this.name, 18 | required this.price, 19 | required this.currency, 20 | required this.brandName, 21 | required this.colour, 22 | required this.productCode, 23 | required this.url, 24 | required this.imageUrl, 25 | required this.additionalImageUrls, 26 | }); 27 | 28 | @override 29 | List get props { 30 | return [ 31 | id, 32 | name, 33 | price, 34 | currency, 35 | brandName, 36 | colour, 37 | productCode, 38 | url, 39 | imageUrl, 40 | additionalImageUrls, 41 | ]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night-v31/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /lib/domain/entities/account/orders.dart: -------------------------------------------------------------------------------- 1 | class Order { 2 | final int orderId; 3 | final int productId; 4 | final int productCode; 5 | final String image; 6 | final String name; 7 | final double price; 8 | final String date; 9 | 10 | Order({ 11 | required this.orderId, 12 | required this.productId, 13 | required this.productCode, 14 | required this.image, 15 | required this.name, 16 | required this.price, 17 | required this.date, 18 | }); 19 | 20 | Map toMap() { 21 | return { 22 | 'productId': productId, 23 | 'productCode': productCode, 24 | 'image': image, 25 | 'name': name, 26 | 'price': price, 27 | 'date': date, 28 | }; 29 | } 30 | 31 | factory Order.fromMap(Map map) { 32 | return Order( 33 | orderId: map['orderId'] as int, 34 | productId: map['productId'] as int, 35 | productCode: map['productCode'] as int, 36 | image: map['image'] as String, 37 | name: map['name'] as String, 38 | price: map['price'] as double, 39 | date: map['date'] as String, 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/data/data_source/payment_remote_data_source.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/data/remote/payment/payment_service.dart'; 2 | 3 | import '../models/payment/payment_response.dart'; 4 | 5 | abstract class PaymentRemoteDateSource { 6 | Future createPaymentIntent( 7 | {required String amount, 8 | required String currency, 9 | required String? paymentMethod}); 10 | 11 | Future retrievePaymentIntent(String id); 12 | } 13 | 14 | class PaymentRemoteDateSourceImpl implements PaymentRemoteDateSource { 15 | final PaymentService _service; 16 | PaymentRemoteDateSourceImpl(this._service); 17 | @override 18 | Future createPaymentIntent( 19 | {required String amount, 20 | required String currency, 21 | required String? paymentMethod}) async { 22 | return await _service.createPaymentIntent({ 23 | 'amount': amount, 24 | 'currency': currency, 25 | 'payment_method_types[]': 'card' 26 | }); 27 | } 28 | 29 | @override 30 | Future retrievePaymentIntent(String id) async { 31 | return await _service.retrievePaymentIntent(id); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/core/functions/state_renderer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_phoenix/flutter_phoenix.dart'; 3 | 4 | import 'package:fashion_app/core/utils/colors.dart'; 5 | import 'package:fashion_app/view/widgets/state_renderer/failure/full_screen_failure_state.dart'; 6 | import 'package:fashion_app/view/widgets/state_renderer/loading/full_screen_loading_state.dart'; 7 | 8 | _showStateRenderder(BuildContext context, Widget state) async { 9 | await showDialog( 10 | context: context, 11 | builder: (context) => state, 12 | ); 13 | } 14 | 15 | showFullScreenErrorState(BuildContext context, String errorMessage) { 16 | _showStateRenderder( 17 | context, 18 | FullScreenFailureState( 19 | message: errorMessage, 20 | press: () { 21 | Phoenix.rebirth(context); 22 | })); 23 | } 24 | 25 | Widget loadingCircularWidget() { 26 | return const Center( 27 | child: CircularProgressIndicator( 28 | color: AppColor.orange, 29 | ), 30 | ); 31 | } 32 | 33 | showFullScreenLoadingState(BuildContext context) { 34 | _showStateRenderder(context, const FullScreenLoadingState()); 35 | } 36 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:fashion_app/app.dart'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_test/flutter_test.dart'; 11 | 12 | void main() { 13 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 14 | // Build our app and trigger a frame. 15 | await tester.pumpWidget(const FashionApp()); 16 | 17 | // Verify that our counter starts at 0. 18 | expect(find.text('0'), findsOneWidget); 19 | expect(find.text('1'), findsNothing); 20 | 21 | // Tap the '+' icon and trigger a frame. 22 | await tester.tap(find.byIcon(Icons.add)); 23 | await tester.pump(); 24 | 25 | // Verify that our counter has incremented. 26 | expect(find.text('0'), findsNothing); 27 | expect(find.text('1'), findsOneWidget); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /lib/data/models/product/product_model.dart: -------------------------------------------------------------------------------- 1 | class ProductModel { 2 | final int? id; 3 | final String? name; 4 | final double? price; 5 | final String? currency; 6 | final String? brandName; 7 | final String? colour; 8 | final int? productCode; 9 | final String? url; 10 | final String? imageUrl; 11 | final List? additionalImageUrls; 12 | ProductModel({ 13 | this.id, 14 | this.name, 15 | this.price, 16 | this.currency, 17 | this.brandName, 18 | this.colour, 19 | this.productCode, 20 | this.url, 21 | this.imageUrl, 22 | this.additionalImageUrls, 23 | }); 24 | 25 | factory ProductModel.fromJson(Map json) { 26 | return ProductModel( 27 | id: json['id'], 28 | name: json['name'], 29 | price: json['price']['current']['value'], 30 | currency: json['currency'], 31 | brandName: json['brandName'], 32 | colour: json['colour'], 33 | productCode: json['productCode'], 34 | url: json['url'], 35 | imageUrl: json['imageUrl'], 36 | additionalImageUrls: (json['additionalImageUrls'] as List) 37 | .map((e) => e.toString()) 38 | .toList(), 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | void RegisterPlugins(flutter::PluginRegistry* registry) { 16 | FileSelectorWindowsRegisterWithRegistrar( 17 | registry->GetRegistrarForPlugin("FileSelectorWindows")); 18 | FirebaseCorePluginCApiRegisterWithRegistrar( 19 | registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); 20 | FlutterSecureStorageWindowsPluginRegisterWithRegistrar( 21 | registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); 22 | GeolocatorWindowsRegisterWithRegistrar( 23 | registry->GetRegistrarForPlugin("GeolocatorWindows")); 24 | PermissionHandlerWindowsPluginRegisterWithRegistrar( 25 | registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); 26 | } 27 | -------------------------------------------------------------------------------- /assets/icons/bag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/wallet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/mastercard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /lib/view/auth/widgets/google_and_facebook_login.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_svg/flutter_svg.dart'; 3 | 4 | import 'package:fashion_app/core/utils/assets.dart'; 5 | import 'package:fashion_app/core/utils/values.dart'; 6 | 7 | class GoogleAndFacebookLogin extends StatelessWidget { 8 | const GoogleAndFacebookLogin( 9 | {super.key, this.facebookLogin, this.googleLogin}); 10 | final Function()? facebookLogin; 11 | final Function()? googleLogin; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Row( 16 | mainAxisAlignment: MainAxisAlignment.center, 17 | children: [ 18 | InkWell( 19 | onTap: facebookLogin, 20 | child: Padding( 21 | padding: const EdgeInsets.all(AppPadding.p20), 22 | child: SvgPicture.asset(AssetsIconPath.facebook), 23 | ), 24 | ), 25 | const SizedBox(width: AppSizes.s15), 26 | InkWell( 27 | onTap: googleLogin, 28 | child: Padding( 29 | padding: const EdgeInsets.all(AppPadding.p20), 30 | child: SvgPicture.asset(AssetsIconPath.google), 31 | ), 32 | ), 33 | ], 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/view/widgets/state_renderer/loading/loading_indicator_listview.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/extensions/media_query_extension.dart'; 2 | import 'package:fashion_app/core/utils/values.dart'; 3 | import 'package:fashion_app/view/widgets/common/shimmer_effect.dart'; 4 | import 'package:fashion_app/view/widgets/state_renderer/skeleton_widgets.dart'; 5 | import 'package:flutter/material.dart'; 6 | 7 | class LoadingIndicatorListview extends StatelessWidget { 8 | const LoadingIndicatorListview({ 9 | super.key, 10 | }); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return ShimmerEffect( 15 | enabled: true, 16 | child: SizedBox( 17 | height: context.setHeight(0.40), 18 | child: ListView.separated( 19 | physics: const BouncingScrollPhysics(), 20 | padding: const EdgeInsets.only(left: AppPadding.p20), 21 | itemCount: 10, 22 | scrollDirection: Axis.horizontal, 23 | itemBuilder: (context, index) { 24 | return const CustomSkeletonWidget(); 25 | }, 26 | separatorBuilder: (context, index) => 27 | const SizedBox(width: AppSizes.s10), 28 | ), 29 | ), 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /assets/icons/notification.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/visa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/view/widgets/common/custom_elevated_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/utils/values.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:fashion_app/core/utils/colors.dart'; 5 | import 'package:fashion_app/view/widgets/common/text_utils.dart'; 6 | 7 | class CustomElevatedButton extends StatelessWidget { 8 | const CustomElevatedButton( 9 | {super.key, 10 | required this.label, 11 | required this.press, 12 | this.backgroundColor = AppColor.orange, 13 | this.textColor = AppColor.white}); 14 | 15 | final String label; 16 | final void Function() press; 17 | final Color backgroundColor; 18 | final Color textColor; 19 | @override 20 | Widget build(BuildContext context) { 21 | return ElevatedButton( 22 | style: ElevatedButton.styleFrom( 23 | backgroundColor: backgroundColor, 24 | padding: const EdgeInsets.symmetric( 25 | horizontal: 5, 26 | vertical: 5, 27 | ), 28 | minimumSize: const Size(double.infinity, AppSizes.s55), 29 | shape: 30 | RoundedRectangleBorder(borderRadius: BorderRadius.circular(50))), 31 | onPressed: press, 32 | child: TextUtils(text: label, color: textColor), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/domain/usecases/search/get_product_by_search_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | import 'package:fashion_app/core/errors/failure.dart'; 3 | import 'package:fashion_app/domain/entities/product/product_entity.dart'; 4 | import 'package:fashion_app/domain/repository/repositories.dart'; 5 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 6 | 7 | class GetProductsBySearchUsecase 8 | implements BaseUsecase, ProductsSearchInputs> { 9 | final SearchProductRepository _repository; 10 | GetProductsBySearchUsecase(this._repository); 11 | @override 12 | Future>> call( 13 | ProductsSearchInputs parameters) async { 14 | return _repository.getProdcutsBySearch( 15 | q: parameters.q, 16 | offset: parameters.offet, 17 | priceMax: parameters.priceMax, 18 | priceMin: parameters.priceMin, 19 | sort: parameters.sort, 20 | ); 21 | } 22 | } 23 | 24 | class ProductsSearchInputs { 25 | final String q; 26 | final int? offet; 27 | final String? sort; 28 | final int? priceMax; 29 | final int? priceMin; 30 | ProductsSearchInputs({ 31 | required this.q, 32 | this.offet, 33 | this.sort, 34 | this.priceMax, 35 | this.priceMin, 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /assets/icons/buy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lib/domain/usecases/category/get_products_by_filter_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:dartz/dartz.dart'; 2 | 3 | import 'package:fashion_app/core/errors/failure.dart'; 4 | import 'package:fashion_app/domain/entities/product/product_entity.dart'; 5 | import 'package:fashion_app/domain/repository/repositories.dart'; 6 | import 'package:fashion_app/domain/usecases/base_usecase.dart'; 7 | 8 | class GetProductsByFilterUsecase 9 | implements BaseUsecase, ProductsFilter> { 10 | final CategoryProductRepository _repository; 11 | GetProductsByFilterUsecase(this._repository); 12 | @override 13 | Future>> call( 14 | ProductsFilter parameters) async { 15 | return await _repository.getProdcutsByCategoryId( 16 | categoryId: parameters.categoryId, 17 | offset: parameters.offset, 18 | priceMax: parameters.priceMax, 19 | priceMin: parameters.priceMin, 20 | sort: parameters.sort, 21 | ); 22 | } 23 | } 24 | 25 | class ProductsFilter { 26 | int categoryId; 27 | int? offset; 28 | String? sort; 29 | int? priceMin; 30 | int? priceMax; 31 | 32 | ProductsFilter({ 33 | required this.categoryId, 34 | this.offset, 35 | this.sort, 36 | this.priceMin, 37 | this.priceMax, 38 | }); 39 | } 40 | -------------------------------------------------------------------------------- /lib/domain/entities/product/product_detail_entity.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class ProductDetailEntity extends Equatable { 4 | final int id; 5 | final String name; 6 | final String description; 7 | final String categoryName; 8 | final String gender; 9 | final String productCode; 10 | final String brand; 11 | final List images; 12 | final double currentPrice; 13 | final double previousPrice; 14 | final String currency; 15 | final String startDateTime; 16 | const ProductDetailEntity({ 17 | required this.id, 18 | required this.name, 19 | required this.description, 20 | required this.categoryName, 21 | required this.gender, 22 | required this.productCode, 23 | required this.brand, 24 | required this.images, 25 | required this.currentPrice, 26 | required this.previousPrice, 27 | required this.currency, 28 | required this.startDateTime, 29 | }); 30 | 31 | @override 32 | List get props { 33 | return [ 34 | id, 35 | name, 36 | description, 37 | categoryName, 38 | gender, 39 | productCode, 40 | brand, 41 | images, 42 | currentPrice, 43 | previousPrice, 44 | currency, 45 | startDateTime, 46 | ]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/view/delivery/pages/custom_google_map.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import 'package:fashion_app/controllers/map/map_cubit.dart'; 5 | import 'package:fashion_app/core/utils/colors.dart'; 6 | import 'package:fashion_app/view/delivery/widgets/map/build_map.dart'; 7 | 8 | import 'package:fashion_app/view/delivery/widgets/map/location_confirm_widget.dart'; 9 | 10 | class CustomGoogleMap extends StatefulWidget { 11 | const CustomGoogleMap({super.key}); 12 | 13 | @override 14 | State createState() => _CustomGoogleMapState(); 15 | } 16 | 17 | class _CustomGoogleMapState extends State { 18 | late final MapCubit cubit; 19 | @override 20 | void initState() { 21 | super.initState(); 22 | cubit = BlocProvider.of(context) 23 | ..checkPermission() 24 | ..getMyCurrnetLocation(); 25 | } 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return const Scaffold( 30 | backgroundColor: AppColor.white, 31 | body: SafeArea( 32 | child: Column( 33 | children: [ 34 | Expanded(child: BuildMap()), 35 | LocationConfirmWidget(), 36 | ], 37 | ), 38 | ), 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/view/search/widgets/search_products_girdview.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/functions/state_renderer.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | 5 | import 'package:fashion_app/controllers/search/search_cubit.dart'; 6 | import 'package:fashion_app/view/widgets/product/product_card_gridview.dart'; 7 | 8 | class SearchProductsGirdview extends StatelessWidget { 9 | const SearchProductsGirdview({ 10 | super.key, 11 | }); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return BlocConsumer( 16 | listener: (context, state) { 17 | if (state is Searchfailure) { 18 | showFullScreenErrorState(context, state.message); 19 | } 20 | }, 21 | builder: (context, state) { 22 | if (state is Searchloading) { 23 | return loadingCircularWidget(); 24 | } else if (state is Searchloaded) { 25 | return ProductCardGirdview( 26 | shrinkWrap: true, 27 | physics: const NeverScrollableScrollPhysics(), 28 | products: BlocProvider.of(context).searchProducts, 29 | ); 30 | } else { 31 | return Container(); 32 | } 33 | }, 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/controllers/filter/filter_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | part 'filter_state.dart'; 5 | 6 | const priceDesc = 'pricedesc'; 7 | const priceAsc = 'priceasc'; 8 | const freshness = 'freshness'; 9 | 10 | class FilterCubit extends Cubit { 11 | FilterCubit() : super(FilterInitial()); 12 | 13 | int currnetSortTab = 0; 14 | double priceStart = 5.0; 15 | double priceEnd = 360.0; 16 | 17 | List sorts = [freshness, priceDesc, priceAsc]; 18 | 19 | void onTap(int index) { 20 | currnetSortTab = index; 21 | emit(FilterChangeCategoryTab()); 22 | } 23 | 24 | onRangePriceChange(RangeValues rangeValue) { 25 | priceStart = rangeValue.start; 26 | priceEnd = rangeValue.end; 27 | emit(FilterPriceSilderChange()); 28 | } 29 | 30 | String getSort() { 31 | return sorts[currnetSortTab]; 32 | } 33 | 34 | clear() { 35 | currnetSortTab = 0; 36 | priceStart = 20.0; 37 | priceEnd = 100.0; 38 | 39 | emit(FilterClear()); 40 | } 41 | 42 | List get priceText { 43 | String start = '\$${priceStart.toInt()}'; 44 | String end = '\$${priceEnd.toInt()}'; 45 | 46 | return [start, end]; 47 | } 48 | 49 | void applyFiltter() { 50 | // Todo 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/view/on_boarding/widget/on_boarding_pageview.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/controllers/on_boarding/on_boarding_cubit.dart'; 4 | 5 | import 'package:fashion_app/core/extensions/media_query_extension.dart'; 6 | 7 | import 'package:fashion_app/view/on_boarding/widget/on_boarding_widget.dart'; 8 | 9 | class OnBoardingPageview extends StatelessWidget { 10 | const OnBoardingPageview( 11 | {super.key, required this.controller, required this.onChange}); 12 | final PageController controller; 13 | final Function(int) onChange; 14 | @override 15 | Widget build(BuildContext context) { 16 | final onBoardingList = OnBoardingCubit().onBoardingList; 17 | return SizedBox( 18 | height: context.setHeight(0.60), // 60 % device height 19 | child: PageView.builder( 20 | physics: const BouncingScrollPhysics(), 21 | onPageChanged: onChange, 22 | controller: controller, 23 | itemCount: onBoardingList.length, 24 | itemBuilder: (context, index) { 25 | return OnBoardingWidget( 26 | image: onBoardingList[index].image, 27 | title: onBoardingList[index].title, 28 | description: onBoardingList[index].description, 29 | ); 30 | }, 31 | ), 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/view/search/search_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/view/search/widgets/search_body_section.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | 5 | import 'package:fashion_app/controllers/search/search_cubit.dart'; 6 | import 'package:fashion_app/core/utils/utils.dart'; 7 | import 'package:fashion_app/view/widgets/common/custom_appbar.dart'; 8 | 9 | import '../widgets/common/back_to_top_button.dart'; 10 | 11 | class SearchPage extends StatefulWidget { 12 | const SearchPage({super.key}); 13 | 14 | @override 15 | State createState() => _SearchPageState(); 16 | } 17 | 18 | class _SearchPageState extends State { 19 | late SearchCubit searchCubit; 20 | @override 21 | void initState() { 22 | super.initState(); 23 | searchCubit = BlocProvider.of(context)..start(context); 24 | } 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return Scaffold( 29 | appBar: const CustomAppbar(title: AppStrings.search), 30 | body: const SearchBodySection(), 31 | floatingActionButton: 32 | BackToTopButton(scrollController: searchCubit.scrollController), 33 | ); 34 | } 35 | 36 | @override 37 | void dispose() { 38 | searchCubit.dispose(); 39 | super.dispose(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/core/utils/constants.dart: -------------------------------------------------------------------------------- 1 | abstract class AppConstants { 2 | static const fontFamilyEn = 'Montserrat'; 3 | static const fontFamilyAr = 'Cairo'; 4 | static const apiKey = 'API_KEY'; 5 | static const stripeKey = 'Stripe_Key'; 6 | static const stripePublishableKey = 'Stripe_Publishable_key'; 7 | static const apiHost = 'API_Host'; 8 | static const stripeBaseUrl = 'https://api.stripe.com/v1'; 9 | static const baseUrl = 'https://asos2.p.rapidapi.com'; 10 | static const productEndPoint = '/products/v2/list'; 11 | static const productDetailEndPoint = '/products/v3/detail'; 12 | static const addressCollection = 'address'; 13 | static const usersCollection = 'users'; 14 | static const favouritesCollection = 'favourites'; 15 | 16 | // home constants 17 | static const homeProductsLimit = 10; 18 | static const categoryProductsLimit = 20; 19 | static const profilePicturePlaceholder = 20 | "https://static.vecteezy.com/system/resources/previews/021/548/095/original/default-profile-picture-avatar-user-avatar-icon-person-icon-head-icon-profile-picture-icons-default-anonymous-user-male-and-female-businessman-photo-placeholder-social-network-avatar-portrait-free-vector.jpg"; 21 | 22 | static const splashTimerInSec = 3; 23 | static const splashAnimationInMilli = 500; 24 | static const pageTransitionInMilli = 450; 25 | } 26 | -------------------------------------------------------------------------------- /lib/view/home/widgets/profile/custom_drop_menu.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:fashion_app/config/routes/route_context.dart'; 5 | import 'package:fashion_app/config/routes/routes.dart'; 6 | import 'package:fashion_app/core/utils/strings.dart'; 7 | 8 | class CustomDropMenu extends StatelessWidget { 9 | const CustomDropMenu({ 10 | super.key, 11 | }); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return DropdownButton( 16 | underline: Container(), 17 | elevation: 8, 18 | padding: EdgeInsets.zero, 19 | icon: Icon( 20 | Icons.more_vert, 21 | color: Theme.of(context).primaryColor, 22 | ), 23 | items: [AppStrings.settings.tr(), AppStrings.accountSettings.tr()] 24 | .map((String value) { 25 | return DropdownMenuItem( 26 | value: value, 27 | child: Text(value), 28 | ); 29 | }).toList(), 30 | onChanged: (_) { 31 | if (_ == AppStrings.settings.tr()) { 32 | context.goToNamed(route: Routes.settings); 33 | } 34 | if (_ == AppStrings.accountSettings.tr()) { 35 | context.goToNamed(route: Routes.account); 36 | } 37 | }, 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 19 | 22 | 23 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 19 | 22 | 23 | -------------------------------------------------------------------------------- /ios/Runner/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CLIENT_ID 6 | 489509362219-9srincj2t49ds61ni1idoigasvqo6mlc.apps.googleusercontent.com 7 | REVERSED_CLIENT_ID 8 | com.googleusercontent.apps.489509362219-9srincj2t49ds61ni1idoigasvqo6mlc 9 | ANDROID_CLIENT_ID 10 | 489509362219-dueio1dbv2eldfl1dt2h7vghpr2rrf8r.apps.googleusercontent.com 11 | API_KEY 12 | AIzaSyCX-MQWr8QbXG3McP_-NFrqHdWm6VVD9Sk 13 | GCM_SENDER_ID 14 | 489509362219 15 | PLIST_VERSION 16 | 1 17 | BUNDLE_ID 18 | com.example.fashionApp 19 | PROJECT_ID 20 | chatme-f8dd8 21 | STORAGE_BUCKET 22 | chatme-f8dd8.appspot.com 23 | IS_ADS_ENABLED 24 | 25 | IS_ANALYTICS_ENABLED 26 | 27 | IS_APPINVITE_ENABLED 28 | 29 | IS_GCM_ENABLED 30 | 31 | IS_SIGNIN_ENABLED 32 | 33 | GOOGLE_APP_ID 34 | 1:489509362219:ios:e4c61a39b0123f0d04286e 35 | 36 | -------------------------------------------------------------------------------- /lib/view/widgets/state_renderer/loading/loading_product_category_girdview.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/core/utils/values.dart'; 2 | import 'package:fashion_app/view/widgets/common/shimmer_effect.dart'; 3 | import 'package:fashion_app/view/widgets/state_renderer/skeleton_widgets.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | class LoadingProductCategoryGirdview extends StatelessWidget { 7 | const LoadingProductCategoryGirdview({ 8 | super.key, 9 | this.shrinkWrap = false, 10 | }); 11 | final bool shrinkWrap; 12 | @override 13 | Widget build(BuildContext context) { 14 | return ShimmerEffect( 15 | enabled: true, 16 | child: GridView.builder( 17 | shrinkWrap: shrinkWrap, 18 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( 19 | crossAxisCount: 2, 20 | crossAxisSpacing: 10, 21 | mainAxisSpacing: 10, 22 | childAspectRatio: 0.6, 23 | ), 24 | physics: const BouncingScrollPhysics(), 25 | padding: const EdgeInsets.only( 26 | left: AppPadding.p20, 27 | right: AppPadding.p20, 28 | top: AppPadding.p20 - 10, 29 | ), 30 | scrollDirection: Axis.vertical, 31 | itemCount: 10, 32 | itemBuilder: (context, index) { 33 | return const CustomSkeletonWidget(); 34 | }, 35 | ), 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/view/widgets/product/product_card_listview.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/core/extensions/media_query_extension.dart'; 4 | 5 | import 'package:fashion_app/core/utils/values.dart'; 6 | 7 | import 'package:fashion_app/domain/entities/product/product_entity.dart'; 8 | 9 | import 'package:fashion_app/view/widgets/product/product_card.dart'; 10 | 11 | class ProductCardListview extends StatelessWidget { 12 | const ProductCardListview({ 13 | super.key, 14 | required this.products, 15 | }); 16 | final List products; 17 | @override 18 | Widget build(BuildContext context) { 19 | return SizedBox( 20 | height: context.setHeight(0.40), 21 | child: ListView.separated( 22 | physics: const BouncingScrollPhysics(), 23 | padding: const EdgeInsets.symmetric(horizontal: AppPadding.p20), 24 | itemCount: products.length, 25 | scrollDirection: Axis.horizontal, 26 | itemBuilder: (context, index) { 27 | return ProductCard( 28 | id: products[index].id, 29 | label: products[index].name, 30 | price: products[index].price, 31 | image: products[index].imageUrl, 32 | ); 33 | }, 34 | separatorBuilder: (context, index) => 35 | const SizedBox(width: AppSizes.s10), 36 | ), 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/view/home/widgets/catalog/catalog_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:fashion_app/core/utils/utils.dart'; 5 | import 'package:fashion_app/core/utils/values.dart'; 6 | import 'package:fashion_app/view/home/widgets/main/menu_widget.dart'; 7 | import 'package:fashion_app/view/widgets/common/text_utils.dart'; 8 | 9 | class CatalogAppbar extends StatelessWidget implements PreferredSizeWidget { 10 | const CatalogAppbar({super.key}); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return AppBar( 15 | title: const TextUtils(text: AppStrings.catalog), 16 | centerTitle: true, 17 | leading: const MenuIconWidget(), 18 | bottom: TabBar( 19 | dividerColor: AppColor.orange, 20 | indicatorColor: AppColor.orange, 21 | labelColor: AppColor.orange, 22 | unselectedLabelColor: AppColor.gray, 23 | indicatorPadding: 24 | const EdgeInsets.symmetric(horizontal: AppPadding.p20), 25 | indicatorWeight: 4.0, 26 | tabs: [ 27 | Tab( 28 | text: AppStrings.mens.tr(), 29 | ), 30 | Tab( 31 | text: AppStrings.womens.tr(), 32 | ), 33 | ], 34 | ), 35 | ); 36 | } 37 | 38 | @override 39 | Size get preferredSize => const Size.fromHeight(AppSizes.s100); 40 | } 41 | -------------------------------------------------------------------------------- /lib/view/auth/widgets/login_signup_logo_section.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:flutter_svg/flutter_svg.dart'; 4 | 5 | import 'package:fashion_app/controllers/auth/auth_cubit.dart'; 6 | import 'package:fashion_app/core/utils/utils.dart'; 7 | import 'package:fashion_app/core/utils/values.dart'; 8 | import 'package:fashion_app/view/widgets/common/text_utils.dart'; 9 | 10 | class LoginSignUpLogoSection extends StatelessWidget { 11 | const LoginSignUpLogoSection({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Column( 16 | crossAxisAlignment: CrossAxisAlignment.center, 17 | mainAxisSize: MainAxisSize.min, 18 | children: [ 19 | SizedBox( 20 | height: AppSizes.s50, 21 | width: AppSizes.s50, 22 | child: SvgPicture.asset(AssetsIconPath.appIcon), 23 | ), 24 | const SizedBox(height: AppSizes.s20), 25 | BlocBuilder( 26 | builder: (context, state) { 27 | return TextUtils( 28 | text: BlocProvider.of(context).isLogin 29 | ? AppStrings.login 30 | : AppStrings.signup, 31 | fontSize: 22, 32 | fontWe: FontWe.medium, 33 | ); 34 | }, 35 | ), 36 | ], 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/data/data_source/user_remote_data_source.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:fashion_app/data/remote/firebase_database/firebase_user_service.dart'; 3 | import 'package:fashion_app/domain/entities/account/user.dart'; 4 | 5 | abstract class UserRemoteDataSource { 6 | Future createUserProfile(UserModel user, String userUid); 7 | Future>> getUserProfileById( 8 | String userUid); 9 | Future updateUserProfile(UserModel user, String userUid); 10 | Future deleteUserProfile(String userUid); 11 | } 12 | 13 | class UserRemoteDataSourceImpl implements UserRemoteDataSource { 14 | final FirebaseUserService _service; 15 | UserRemoteDataSourceImpl(this._service); 16 | @override 17 | Future>> getUserProfileById( 18 | String userUid) async { 19 | return _service.getUserProfileById(userUid); 20 | } 21 | 22 | @override 23 | createUserProfile(UserModel accountModel, String userUid) async { 24 | await _service.createUserProfile(accountModel, userUid); 25 | } 26 | 27 | @override 28 | Future deleteUserProfile(String userUid) async { 29 | return await _service.deleteUserProfile(userUid); 30 | } 31 | 32 | @override 33 | Future updateUserProfile(UserModel user, String userUid) async { 34 | return await _service.updateUserProfile(user, userUid); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/view/favourite/widgets/favourite_body_section.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/view/favourite/widgets/favourites_products_girdview.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | 5 | import 'package:fashion_app/controllers/favourite/favourite_cubit.dart'; 6 | import 'package:fashion_app/core/functions/state_renderer.dart'; 7 | import 'package:fashion_app/core/utils/strings.dart'; 8 | import 'package:fashion_app/view/widgets/state_renderer/empty_state.dart'; 9 | 10 | class FavouriteBodySection extends StatelessWidget { 11 | const FavouriteBodySection({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return SafeArea( 16 | child: BlocBuilder( 17 | builder: (context, state) { 18 | if (state is FavouriteLoading) { 19 | return loadingCircularWidget(); 20 | } else if (BlocProvider.of(context) 21 | .favouriteProducts 22 | .isEmpty) { 23 | return const EmptyState( 24 | icon: Icons.favorite, message: AppStrings.favorite); 25 | } else { 26 | return FavouritesProductsGridview( 27 | favouriteProducts: 28 | BlocProvider.of(context).favouriteProducts, 29 | ); 30 | } 31 | }, 32 | ), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/config/services/permissions.dart: -------------------------------------------------------------------------------- 1 | import 'package:geolocator/geolocator.dart'; 2 | import 'package:permission_handler/permission_handler.dart'; 3 | 4 | import '../../core/functions/function.dart'; 5 | 6 | abstract class AppPermissions { 7 | Future checkLocationPermission(); 8 | Future openSettings(); 9 | Future requestPhotosPermission(); 10 | Future requestCameraPermission(); 11 | } 12 | 13 | class AppPermissionsImpl implements AppPermissions { 14 | @override 15 | Future checkLocationPermission() async { 16 | LocationPermission permission; 17 | permission = await Geolocator.checkPermission(); 18 | if (permission == LocationPermission.denied) { 19 | permission = await Geolocator.requestPermission(); 20 | if (permission == LocationPermission.denied) { 21 | showToastMessage('Location permissions are denied'); 22 | } 23 | } 24 | 25 | if (permission == LocationPermission.deniedForever) { 26 | showToastMessage('Permissions are denied forever'); 27 | } 28 | } 29 | 30 | @override 31 | Future openSettings() async { 32 | await openAppSettings(); 33 | } 34 | 35 | @override 36 | Future requestPhotosPermission() async { 37 | return await Permission.storage.request().isGranted; 38 | } 39 | 40 | @override 41 | Future requestCameraPermission() async { 42 | return await Permission.camera.request().isGranted; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.Create(L"fashion_app", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /lib/view/categories/widgets/category_body_section.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import 'package:fashion_app/controllers/category_product/category_product_cubit.dart'; 5 | import 'package:fashion_app/view/categories/widgets/categories_product_gridview.dart'; 6 | 7 | import '../../../core/functions/state_renderer.dart'; 8 | 9 | class CategoryBodySection extends StatelessWidget { 10 | const CategoryBodySection({ 11 | super.key, 12 | required this.categoryId, 13 | }); 14 | final int categoryId; 15 | @override 16 | Widget build(BuildContext context) { 17 | return CustomScrollView( 18 | physics: const BouncingScrollPhysics(), 19 | controller: 20 | BlocProvider.of(context).scrollController, 21 | slivers: [ 22 | const SliverToBoxAdapter(child: CategoriesProductGirdview()), 23 | SliverToBoxAdapter(child: _loadingMoreProducts()) 24 | ], 25 | ); 26 | } 27 | } 28 | 29 | _loadingMoreProducts() { 30 | return BlocBuilder( 31 | builder: (context, state) { 32 | if (BlocProvider.of(context).isLoadMore) { 33 | return Padding( 34 | padding: const EdgeInsets.symmetric(vertical: 20), 35 | child: loadingCircularWidget(), 36 | ); 37 | } 38 | return Container(); 39 | }, 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /lib/data/data_source/local_data_source.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/data/local/location/location_service.dart'; 2 | import 'package:geocoding/geocoding.dart'; 3 | import 'package:geolocator/geolocator.dart'; 4 | 5 | abstract class LocationLocalDataSource { 6 | Future getMyCurrnetLocation(); 7 | Future?> getLocationInfromation( 8 | double latitude, double longitude); 9 | Future openLocationPageSettings(); 10 | } 11 | 12 | class LocationLocalDataSourceImpl implements LocationLocalDataSource { 13 | final LocationService _locationService; 14 | LocationLocalDataSourceImpl(this._locationService); 15 | @override 16 | Future?> getLocationInfromation( 17 | double latitude, double longitude) async { 18 | try { 19 | return _locationService.getLocationInfromation(latitude, longitude); 20 | } catch (e) { 21 | await openLocationPageSettings(); 22 | } 23 | return null; 24 | } 25 | 26 | @override 27 | Future getMyCurrnetLocation() async { 28 | try { 29 | return _locationService.getMyCurrnetLocation(); 30 | } catch (e) { 31 | await openLocationPageSettings(); 32 | } 33 | return null; 34 | } 35 | 36 | @override 37 | Future openLocationPageSettings() { 38 | return _locationService.openLocationPageSettings(); 39 | } 40 | } 41 | 42 | openLocationPageSettings() async { 43 | await Geolocator.openLocationSettings(); 44 | } 45 | -------------------------------------------------------------------------------- /lib/view/home/widgets/main/custom_advanced_drawer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_advanced_drawer/flutter_advanced_drawer.dart'; 3 | 4 | import 'package:fashion_app/core/extensions/theme_extension.dart'; 5 | 6 | import 'package:fashion_app/core/utils/colors.dart'; 7 | 8 | class CustomAdvancedDrawer extends StatelessWidget { 9 | const CustomAdvancedDrawer( 10 | {super.key, 11 | required this.controller, 12 | required this.child, 13 | required this.drawer}); 14 | final AdvancedDrawerController controller; 15 | final Widget child; 16 | final Widget drawer; 17 | @override 18 | Widget build(BuildContext context) { 19 | return AdvancedDrawer( 20 | controller: controller, 21 | animationCurve: Curves.easeInOut, 22 | animationDuration: const Duration(milliseconds: 300), 23 | animateChildDecoration: true, 24 | rtlOpening: context.isRTL, 25 | disabledGestures: false, // disable swipe 26 | openScale: 0.8, 27 | backdrop: Container( 28 | width: double.infinity, 29 | height: double.infinity, 30 | decoration: BoxDecoration( 31 | color: context.isDark 32 | ? AppColor.blackBg.withOpacity(0.9) 33 | : AppColor.white2, 34 | ), 35 | ), 36 | childDecoration: BoxDecoration(borderRadius: BorderRadius.circular(20)), 37 | drawer: drawer, 38 | child: child, 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/data/data_source/favourites_remote_data_source.dart: -------------------------------------------------------------------------------- 1 | import 'package:fashion_app/data/remote/firebase_database/firebase_favourite_service.dart'; 2 | import 'package:fashion_app/domain/entities/account/favourites.dart'; 3 | 4 | abstract class FavouriteRemoteDataSource { 5 | Future> getFavourtiesProducts(String userUid); 6 | Future deleteFavouriteProduct(int productId, String userUid); 7 | Future clearFavouritesProducts(String userUid); 8 | Future addFavouriteProduct( 9 | ProductsFavourite productFav, String userUid); 10 | } 11 | 12 | class FavouriteRemoteDataSourceImpl implements FavouriteRemoteDataSource { 13 | final FirebaseFavouriteService _service; 14 | FavouriteRemoteDataSourceImpl(this._service); 15 | 16 | @override 17 | Future addFavouriteProduct( 18 | ProductsFavourite productFav, String userUid) async { 19 | return await _service.addFavouriteProduct(productFav, userUid); 20 | } 21 | 22 | @override 23 | Future clearFavouritesProducts(String userUid) async { 24 | return await _service.clearFavouritesProducts(userUid); 25 | } 26 | 27 | @override 28 | Future deleteFavouriteProduct(int productId, String userUid) async { 29 | return await _service.deleteFavouriteProduct(productId, userUid); 30 | } 31 | 32 | @override 33 | Future> getFavourtiesProducts(String userUid) async { 34 | return await _service.getFavourtiesProducts(userUid); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/view/favourite/widgets/favourites_products_girdview.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fashion_app/core/utils/values.dart'; 4 | import 'package:fashion_app/domain/entities/account/favourites.dart'; 5 | import 'package:fashion_app/view/widgets/product/product_card.dart'; 6 | 7 | class FavouritesProductsGridview extends StatelessWidget { 8 | const FavouritesProductsGridview( 9 | {super.key, required this.favouriteProducts}); 10 | final List favouriteProducts; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return GridView.builder( 15 | shrinkWrap: true, 16 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( 17 | crossAxisCount: 2, 18 | crossAxisSpacing: 10, 19 | mainAxisSpacing: 10, 20 | childAspectRatio: 0.60, 21 | ), 22 | physics: const BouncingScrollPhysics(), 23 | padding: const EdgeInsets.only( 24 | left: AppPadding.p20, 25 | right: AppPadding.p20, 26 | top: AppPadding.p20 - 10, 27 | ), 28 | scrollDirection: Axis.vertical, 29 | itemCount: favouriteProducts.length, 30 | itemBuilder: (context, index) { 31 | return ProductCard( 32 | id: favouriteProducts[index].productId, 33 | image: favouriteProducts[index].imageUrl, 34 | label: favouriteProducts[index].name, 35 | price: favouriteProducts[index].price, 36 | ); 37 | }, 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /assets/jsons/loading.json: -------------------------------------------------------------------------------- 1 | {"v":"5.5.8","fr":25,"ip":0,"op":50,"w":250,"h":250,"nm":"合成 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"形状图层 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":49,"s":[720]}],"ix":10},"p":{"a":0,"k":[123,124,0],"ix":2},"a":{"a":0,"k":[18,2,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[157.383,157.383],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.537254901961,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":26,"ix":5},"lc":2,"lj":2,"bm":0,"d":[{"n":"d","nm":"虚线","v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":49,"s":[0]}],"ix":1}},{"n":"g","nm":"间隙","v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[532]},{"t":49,"s":[62]}],"ix":2}},{"n":"o","nm":"偏移","v":{"a":0,"k":0,"ix":7}}],"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[17.691,-0.309],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":1,"s":[100]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":50,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /lib/data/models/product/product_detail_model.dart: -------------------------------------------------------------------------------- 1 | class ProductDetailModel { 2 | final int? id; 3 | final String? name; 4 | final String? description; 5 | final String? categoryName; 6 | final String? gender; 7 | final String? productCode; 8 | final String? brand; 9 | final List? images; 10 | final double? currentPrice; 11 | final double? previousPrice; 12 | final String? currency; 13 | final String? startDateTime; 14 | ProductDetailModel({ 15 | this.id, 16 | this.name, 17 | this.description, 18 | this.categoryName, 19 | this.gender, 20 | this.productCode, 21 | this.brand, 22 | this.images, 23 | this.currentPrice, 24 | this.previousPrice, 25 | this.currency, 26 | this.startDateTime, 27 | }); 28 | 29 | factory ProductDetailModel.fromJson(Map json) { 30 | return ProductDetailModel( 31 | id: json['id'], 32 | name: json['name'], 33 | description: json['description'], 34 | categoryName: json['productType']['name'], 35 | gender: json['gender'], 36 | productCode: json['productCode'], 37 | brand: json['brand']['name'], 38 | images: (json['media']['images'] as List) 39 | .map((e) => e['url'].toString()) 40 | .toList(), 41 | currentPrice: json['price']['current']['value'], 42 | previousPrice: json['price']['previous']['value'], 43 | currency: json['price']['currency'], 44 | startDateTime: json['startDateTime'], 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /android/app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "489509362219", 4 | "project_id": "chatme-f8dd8", 5 | "storage_bucket": "chatme-f8dd8.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:489509362219:android:b1f57cd6af90f13e04286e", 11 | "android_client_info": { 12 | "package_name": "com.example.fashion_app" 13 | } 14 | }, 15 | "oauth_client": [ 16 | { 17 | "client_id": "489509362219-i36ejo5saukbl3ok64k1pem1pc9pe8md.apps.googleusercontent.com", 18 | "client_type": 1, 19 | "android_info": { 20 | "package_name": "com.example.fashion_app", 21 | "certificate_hash": "a3fcb462f906db7f0b30a0d02b0ce14b73382f94" 22 | } 23 | }, 24 | { 25 | "client_id": "489509362219-ro1jioppdkfhfb55e0hbf2fc4ojcl3av.apps.googleusercontent.com", 26 | "client_type": 3 27 | } 28 | ], 29 | "api_key": [ 30 | { 31 | "current_key": "AIzaSyAo4NxFrg5xWCfBNzeLD0ZVUADKatE4iMA" 32 | } 33 | ], 34 | "services": { 35 | "appinvite_service": { 36 | "other_platform_oauth_client": [ 37 | { 38 | "client_id": "489509362219-eusj4gn6n648g99a55sqahfjvebjdc6d.apps.googleusercontent.com", 39 | "client_type": 3 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | ], 46 | "configuration_version": "1" 47 | } --------------------------------------------------------------------------------