├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── 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 │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme └── .gitignore ├── screens ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpeg └── 5.jpeg ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ └── favicon.ico ├── manifest.json └── index.html ├── assets ├── images │ ├── BB.jpg │ ├── Itau.jpg │ ├── Caixa.jpg │ ├── House.png │ ├── AboutUs.jpg │ ├── Bradesco.jpg │ ├── Santander.jpg │ ├── contact.jpg │ ├── Lage_Wpp_1.jpg │ ├── Lage_Wpp_2.jpg │ ├── Lage_Wpp_3.jpg │ ├── Lage_Wpp_4.jpg │ ├── Lage_Wpp_5.jpg │ ├── Lage_Wpp_6.jpg │ ├── Simulation.jpeg │ ├── properties.jpg │ ├── whatsapp-24.png │ └── whatsapp-48.png └── logo │ ├── Lage.png │ └── LageTransparente.png ├── android ├── gradle.properties ├── .gitignore ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ └── values │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── site_lage │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── build.gradle ├── lib ├── components │ ├── connection.dart │ ├── colors.dart │ └── handCursor.dart ├── util │ ├── foorter │ │ ├── footerLogo.dart │ │ ├── footerItem.dart │ │ ├── footerInfo.dart │ │ ├── footer_desktop.dart │ │ ├── footer_mobile.dart │ │ └── footer.dart │ ├── centeredView │ │ └── centeredView.dart │ └── navigationBar │ │ ├── navigationBar.dart │ │ ├── navigationBarLogo.dart │ │ ├── navigationBarItem.dart │ │ ├── navigationBar_desktop.dart │ │ └── navigationBar_mobile.dart ├── widgets │ ├── contactPage │ │ ├── mapWidget.dart │ │ ├── titleWidget.dart │ │ ├── getMap.dart │ │ ├── nameBar.dart │ │ ├── subjectBar.dart │ │ ├── textBar.dart │ │ ├── dataWidget.dart │ │ └── submitButton.dart │ ├── aboutusPage │ │ └── titleWidget.dart │ ├── simulations │ │ └── simulationTitle.dart │ ├── homePage │ │ ├── propertiesListLoading.dart │ │ ├── searchButton.dart │ │ ├── searchBar.dart │ │ ├── propertiesList.dart │ │ ├── propertyCard.dart │ │ ├── propertyCardMobile.dart │ │ ├── searchWidget.dart │ │ └── dropdownButtons.dart │ ├── propertyPage │ │ ├── propertyTitle.dart │ │ ├── propertyPhotos.dart │ │ ├── propertyDetails.dart │ │ └── propertyContact.dart │ └── propertiesPage │ │ ├── notFoundWidget.dart │ │ ├── propertyCardTile.dart │ │ └── propertiesTitleWidget.dart ├── pages │ ├── contactPage │ │ ├── contactPage_mobile.dart │ │ └── contactPage_desktop.dart │ ├── propertyPage │ │ ├── propertyPage_desktop.dart │ │ └── propertyPage_mobile.dart │ ├── aboutUsPage │ │ ├── aboutUsPage_desktop.dart │ │ └── aboutUsPage_mobile.dart │ ├── aboutUsPage.dart │ ├── contactPage.dart │ ├── simulationPage │ │ ├── simulationPage_desktop.dart │ │ └── simulationPage_mobile.dart │ ├── propertiesPage │ │ ├── propertiesPage_mobile.dart │ │ └── propertiesPage_desktop.dart │ ├── simulationPage.dart │ ├── homePage.dart │ ├── properiesPage.dart │ ├── propertyPage.dart │ └── homePage │ │ └── homePage_desktop.dart ├── main.dart ├── controllers │ ├── api_controller.dart │ ├── email_controller.dart │ ├── api_controller.g.dart │ ├── search_controller.dart │ ├── email_controller.g.dart │ └── search_controller.g.dart ├── models │ └── property.dart └── router │ └── config.dart ├── .metadata ├── README.md ├── .gitignore ├── test └── widget_test.dart └── pubspec.yaml /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /screens/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/screens/1.jpg -------------------------------------------------------------------------------- /screens/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/screens/2.jpg -------------------------------------------------------------------------------- /screens/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/screens/3.jpg -------------------------------------------------------------------------------- /screens/4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/screens/4.jpeg -------------------------------------------------------------------------------- /screens/5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/screens/5.jpeg -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/web/favicon.png -------------------------------------------------------------------------------- /assets/images/BB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/BB.jpg -------------------------------------------------------------------------------- /assets/images/Itau.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Itau.jpg -------------------------------------------------------------------------------- /assets/logo/Lage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/logo/Lage.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/web/icons/favicon.ico -------------------------------------------------------------------------------- /assets/images/Caixa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Caixa.jpg -------------------------------------------------------------------------------- /assets/images/House.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/House.png -------------------------------------------------------------------------------- /assets/images/AboutUs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/AboutUs.jpg -------------------------------------------------------------------------------- /assets/images/Bradesco.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Bradesco.jpg -------------------------------------------------------------------------------- /assets/images/Santander.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Santander.jpg -------------------------------------------------------------------------------- /assets/images/contact.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/contact.jpg -------------------------------------------------------------------------------- /assets/images/Lage_Wpp_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Lage_Wpp_1.jpg -------------------------------------------------------------------------------- /assets/images/Lage_Wpp_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Lage_Wpp_2.jpg -------------------------------------------------------------------------------- /assets/images/Lage_Wpp_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Lage_Wpp_3.jpg -------------------------------------------------------------------------------- /assets/images/Lage_Wpp_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Lage_Wpp_4.jpg -------------------------------------------------------------------------------- /assets/images/Lage_Wpp_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Lage_Wpp_5.jpg -------------------------------------------------------------------------------- /assets/images/Lage_Wpp_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Lage_Wpp_6.jpg -------------------------------------------------------------------------------- /assets/images/Simulation.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/Simulation.jpeg -------------------------------------------------------------------------------- /assets/images/properties.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/properties.jpg -------------------------------------------------------------------------------- /assets/images/whatsapp-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/whatsapp-24.png -------------------------------------------------------------------------------- /assets/images/whatsapp-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/images/whatsapp-48.png -------------------------------------------------------------------------------- /assets/logo/LageTransparente.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/assets/logo/LageTransparente.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saviollage/Site-Lage-Imoveis/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/Saviollage/Site-Lage-Imoveis/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/site_lage/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.site_lage 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/components/connection.dart: -------------------------------------------------------------------------------- 1 | class Constants { 2 | //static String url = "http://localhost:3000"; 3 | static String url = "https://lage-api.herokuapp.com/"; 4 | 5 | static Duration timeout = new Duration(seconds: 15); 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/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 | -------------------------------------------------------------------------------- /.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 and should not be manually edited. 5 | 6 | version: 7 | revision: 800e9511600c4a9c913cc29b21928d6a42d1e057 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /lib/util/foorter/footerLogo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FooterLogo extends StatelessWidget { 4 | 5 | final double size; 6 | 7 | const FooterLogo({Key key, this.size}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return SizedBox( 12 | height: size, 13 | child: Image.asset('assets/logo/LageTransparente.png'), 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/util/centeredView/centeredView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CenteredView extends StatelessWidget { 4 | final Widget child; 5 | 6 | const CenteredView({Key key, this.child}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | 12 | child: ConstrainedBox( 13 | constraints: BoxConstraints(maxWidth: 1920), 14 | child: child, 15 | ), 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/components/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class LageColors { 4 | // #403E3F 5 | static Color black = new Color(0xFF403F3F); 6 | // #BF9A2C 7 | static Color deepyellow = new Color(0xFFBF9A2C); 8 | // #F2AE2E 9 | static Color deepYellowAccent = new Color(0xFFF2AE2E); 10 | // #F2C12E 11 | static Color yellow = new Color(0xFFF2C12E); 12 | // #FECF27 13 | static Color yellowAccent = new Color(0xFFFECF27); 14 | 15 | // #F2B807 16 | static Color yellowLogo = new Color(0xFFFECF27); 17 | 18 | // #F8F8F8 19 | static Color whiteAccent = new Color(0xFFF8F8F8); 20 | } -------------------------------------------------------------------------------- /lib/components/handCursor.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/gestures.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:universal_html/prefer_sdk/html.dart' as html; 4 | 5 | class HandCursor extends MouseRegion { 6 | static final appContainer = html.window.document.getElementById('app-container'); 7 | HandCursor({Widget child}) 8 | : super( 9 | onHover: (PointerHoverEvent evt) { 10 | appContainer.style.cursor = 'pointer'; 11 | }, 12 | onExit: (PointerExitEvent evt) { 13 | appContainer.style.cursor = 'default'; 14 | }, 15 | child: child, 16 | ); 17 | } -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "site_lage", 3 | "short_name": "site_lage", 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 | } 24 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /lib/util/navigationBar/navigationBar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:responsive_builder/responsive_builder.dart'; 3 | import 'package:site_lage/util/navigationBar/navigationBar_desktop.dart'; 4 | 5 | import 'navigationBar_mobile.dart'; 6 | 7 | class NavigationBar extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | alignment: Alignment.topCenter, 12 | child: ScreenTypeLayout( 13 | 14 | desktop: NavigationBarDesktopAndTablet(), 15 | tablet: NavigationBarDesktopAndTablet(), 16 | mobile: NavigationBarMobile(), 17 | )); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | include ':app' 6 | 7 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 8 | def properties = new Properties() 9 | 10 | assert localPropertiesFile.exists() 11 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 12 | 13 | def flutterSdkPath = properties.getProperty("flutter.sdk") 14 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 15 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 16 | -------------------------------------------------------------------------------- /lib/util/navigationBar/navigationBarLogo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NavigationBarLogo extends StatelessWidget { 4 | final Function onPressed; 5 | 6 | const NavigationBarLogo({Key key, this.onPressed}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return SizedBox( 11 | height: 100, 12 | child: InkWell( 13 | onTap: onPressed, 14 | child: Image.asset('assets/logo/Lage.png'), 15 | focusColor: Colors.transparent, 16 | hoverColor: Colors.transparent, 17 | highlightColor: Colors.transparent, 18 | splashColor: Colors.transparent, 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/widgets/contactPage/mapWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/contactPage/getMap.dart'; 3 | 4 | class MapWidget extends StatelessWidget { 5 | final double size; 6 | 7 | const MapWidget({Key key, @required this.size}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | width: MediaQuery.of(context).size.width * size, 13 | decoration: BoxDecoration(boxShadow: [ 14 | BoxShadow(blurRadius: 10, offset: Offset(5, 5), color: Colors.grey) 15 | ], borderRadius: BorderRadius.circular(20), color: Colors.white), 16 | child: MapW(), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 💡 Site LAGE IMÓVEIS 2 | 3 | Site desenvolvido para a imobiliária Lage Imóveis. 4 | Disponível 5 | [neste link](https://lageimoveis.com.br) 6 | 7 | ## 📲 Tecnologias utilizadas 🖥 8 | 9 | ### Flutter Web 10 | - Arquitetura MVC 11 | - MOBX 12 | - Responsive Layout Builder 13 | 14 | ## 📸 Imagens do sistema 15 | 16 |

17 | 18 | 19 | 20 | 21 | 22 |

23 | 24 | 25 | ## 👩‍💻 Para executar 26 | 27 | ```bash 28 | flutter run -d chrome 29 | ``` 30 | 31 | ## Licença 32 | [MIT](https://choosealicense.com/licenses/mit/) -------------------------------------------------------------------------------- /lib/util/foorter/footerItem.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FooterItem extends StatelessWidget { 4 | final String title; 5 | final String subtitle; 6 | 7 | const FooterItem({Key key, this.title, this.subtitle}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Column( 12 | mainAxisSize: MainAxisSize.min, 13 | crossAxisAlignment: CrossAxisAlignment.start, 14 | children: [ 15 | Text( 16 | title, 17 | style: TextStyle(fontSize: 25, fontWeight: FontWeight.w800), 18 | ), 19 | Text( 20 | subtitle, 21 | style: TextStyle(fontSize: 15, fontWeight: FontWeight.w300), 22 | ) 23 | ], 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/util/foorter/footerInfo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FooterInfo extends StatelessWidget { 4 | final String title; 5 | final IconData icon; 6 | final double iconSize; 7 | final double textSize; 8 | 9 | const FooterInfo( 10 | {Key key, this.title, this.icon, this.iconSize, this.textSize}) 11 | : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Row( 16 | mainAxisSize: MainAxisSize.max, 17 | crossAxisAlignment: CrossAxisAlignment.center, 18 | children: [ 19 | Icon( 20 | icon, 21 | size: iconSize, 22 | ), 23 | SizedBox( 24 | width: 5, 25 | ), 26 | Flexible( 27 | child: Text( 28 | title, 29 | style: TextStyle(fontSize: textSize), 30 | )) 31 | ], 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/widgets/aboutusPage/titleWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AboutUsTitleWidget extends StatelessWidget { 4 | final double size; 5 | final double textSize; 6 | 7 | const AboutUsTitleWidget({Key key, this.size, this.textSize}) : super(key: key); 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | height: size, 12 | width: MediaQuery.of(context).size.width, 13 | decoration: BoxDecoration( 14 | image: DecorationImage( 15 | fit: BoxFit.cover, 16 | image: AssetImage("assets/images/AboutUs.jpg")), 17 | ), 18 | child: Container( 19 | color: Colors.black.withOpacity(0.8), 20 | child: Center( 21 | child: Text( 22 | "Sobre nós", 23 | style: TextStyle( 24 | fontSize: textSize, 25 | color: Colors.white, 26 | fontWeight: FontWeight.bold), 27 | ), 28 | ), 29 | )); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/widgets/contactPage/titleWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ContactTitleWidget extends StatelessWidget { 4 | 5 | final double size; 6 | final double textSize; 7 | 8 | const ContactTitleWidget({Key key, this.size, this.textSize}) : super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | height: size, 14 | width: MediaQuery.of(context).size.width, 15 | decoration: BoxDecoration( 16 | image: DecorationImage( 17 | fit: BoxFit.cover, 18 | image: AssetImage("assets/images/contact.jpg")), 19 | ), 20 | child: Container( 21 | color: Colors.black.withOpacity(0.8), 22 | child: Center( 23 | child: Text( 24 | "Contato", 25 | style: TextStyle( 26 | fontSize: textSize, 27 | color: Colors.white, 28 | fontWeight: FontWeight.bold), 29 | ), 30 | ), 31 | )); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/pages/contactPage/contactPage_mobile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/contactPage/dataWidget.dart'; 3 | import 'package:site_lage/widgets/contactPage/mapWidget.dart'; 4 | import 'package:site_lage/widgets/contactPage/titleWidget.dart'; 5 | 6 | class ContactPageMobile extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | return Container( 10 | width: MediaQuery.of(context).size.width, 11 | child: Column( 12 | mainAxisSize: MainAxisSize.max, 13 | children: [ 14 | ContactTitleWidget( 15 | size: 300, 16 | textSize: 35, 17 | ), 18 | DataWidget( 19 | percentSize: 0.9, 20 | fontSize: 30, 21 | ), 22 | SizedBox( 23 | height: 30, 24 | ), 25 | Container(height: 300, child: MapWidget(size: 0.9)), 26 | SizedBox( 27 | height: 50, 28 | ), 29 | ], 30 | )); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/widgets/contactPage/getMap.dart: -------------------------------------------------------------------------------- 1 | import 'dart:html'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:google_maps/google_maps.dart'; 4 | import 'dart:ui' as ui; 5 | 6 | class MapW extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | String htmlId = "7"; 10 | 11 | // ignore: undefined_prefixed_name 12 | ui.platformViewRegistry.registerViewFactory(htmlId, (int viewId) { 13 | final myLatlng = LatLng(-19.4754333, -42.5300626); 14 | 15 | final mapOptions = MapOptions() 16 | ..zoom = 18 17 | ..center = LatLng(-19.4754071, -42.5302311); 18 | 19 | final elem = DivElement() 20 | ..id = htmlId 21 | ..style.width = "100%" 22 | ..style.height = "100%" 23 | ..style.border = 'none'; 24 | 25 | final map = GMap(elem, mapOptions); 26 | 27 | Marker(MarkerOptions() 28 | ..position = myLatlng 29 | ..map = map 30 | ..title = 'Lage Imóveis'); 31 | 32 | return elem; 33 | }); 34 | 35 | return HtmlElementView(viewType: htmlId); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/util/navigationBar/navigationBarItem.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/components/colors.dart'; 3 | 4 | class NavigationBarItem extends StatelessWidget { 5 | final String title; 6 | final Function onPressed; 7 | final bool styled; 8 | 9 | const NavigationBarItem( 10 | {Key key, this.title, this.onPressed, this.styled = false}) 11 | : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return InkWell( 16 | child: Container( 17 | padding: EdgeInsets.all(10), 18 | decoration: BoxDecoration( 19 | color: styled ? LageColors.yellow : Colors.transparent, 20 | borderRadius: BorderRadius.circular(5)), 21 | child: Text( 22 | title, 23 | style: TextStyle(fontWeight: FontWeight.bold), 24 | ), 25 | ), 26 | onTap: onPressed, 27 | focusColor: Colors.transparent, 28 | hoverColor: Colors.transparent, 29 | highlightColor: Colors.transparent, 30 | splashColor: Colors.transparent, 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/widgets/simulations/simulationTitle.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SimulationTitleWidget extends StatelessWidget { 4 | final double size; 5 | final double fontSize; 6 | 7 | const SimulationTitleWidget( 8 | {Key key, @required this.size, @required this.fontSize}) 9 | : super(key: key); 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | height: size, 14 | width: MediaQuery.of(context).size.width, 15 | decoration: BoxDecoration( 16 | image: DecorationImage( 17 | fit: BoxFit.cover, 18 | image: AssetImage("assets/images/Simulation.jpeg")), 19 | ), 20 | child: Container( 21 | color: Colors.black.withOpacity(0.8), 22 | child: Center( 23 | child: Text( 24 | "SIMULADORES", 25 | style: TextStyle( 26 | fontSize: fontSize, 27 | color: Colors.white, 28 | fontWeight: FontWeight.bold), 29 | ), 30 | ), 31 | )); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/widgets/homePage/propertiesListLoading.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:skeleton_text/skeleton_text.dart'; 3 | 4 | class PropertiesListLoading extends StatelessWidget { 5 | final double size; 6 | 7 | const PropertiesListLoading({ 8 | Key key, 9 | @required this.size, 10 | }) : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return Container( 15 | height: size, 16 | child: ListView.builder( 17 | padding: EdgeInsets.only(left: 20, top: 10, bottom: 10), 18 | scrollDirection: Axis.horizontal, 19 | itemCount: 4, 20 | itemBuilder: (context, index) => SkeletonAnimation( 21 | child: Container( 22 | margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10), 23 | width: size == 300 ? 350 : 200, 24 | height: size, 25 | decoration: BoxDecoration( 26 | borderRadius: BorderRadius.circular(10.0), 27 | color: Colors.grey[300]), 28 | ), 29 | ))); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /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 that Flutter provides. 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:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:site_lage/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /lib/widgets/propertyPage/propertyTitle.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/components/colors.dart'; 3 | 4 | class PropertyTitle extends StatelessWidget { 5 | 6 | final String title; 7 | final String subtitle; 8 | final IconData icon; 9 | 10 | const PropertyTitle({Key key, this.title, this.subtitle, this.icon}) : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return Padding( 15 | padding: EdgeInsets.only(left: 20), 16 | child: ListTile( 17 | enabled: false, 18 | leading: Icon( 19 | icon, 20 | color: LageColors.yellow, 21 | ), 22 | title: Text( 23 | title, 24 | style: TextStyle(color: Colors.black), 25 | ), 26 | subtitle: Text( 27 | subtitle, 28 | style: TextStyle( 29 | color: LageColors.yellow, 30 | fontWeight: FontWeight.bold), 31 | ), 32 | ), 33 | ); 34 | } 35 | } -------------------------------------------------------------------------------- /lib/pages/contactPage/contactPage_desktop.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/contactPage/dataWidget.dart'; 3 | import 'package:site_lage/widgets/contactPage/mapWidget.dart'; 4 | import 'package:site_lage/widgets/contactPage/titleWidget.dart'; 5 | 6 | class ContactPageDesktop extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | return Column( 10 | mainAxisSize: MainAxisSize.max, 11 | children: [ 12 | ContactTitleWidget( 13 | size: 600, 14 | textSize: 70, 15 | ), 16 | Container( 17 | height: 600, 18 | width: MediaQuery.of(context).size.width, 19 | padding: EdgeInsets.symmetric(horizontal: 50, vertical: 50), 20 | child: Row( 21 | mainAxisSize: MainAxisSize.max, 22 | mainAxisAlignment: MainAxisAlignment.spaceAround, 23 | children: [ 24 | MapWidget( 25 | size: 0.35, 26 | ), 27 | Expanded( 28 | child: DataWidget( 29 | percentSize: 0.4, 30 | fontSize: 40, 31 | ), 32 | ), 33 | ], 34 | )) 35 | ], 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/widgets/homePage/searchButton.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get_it/get_it.dart'; 3 | import 'package:site_lage/components/colors.dart'; 4 | import 'package:site_lage/controllers/search_controller.dart'; 5 | import 'package:site_lage/pages/properiesPage.dart'; 6 | 7 | class SearchButton extends StatelessWidget { 8 | final searchController = GetIt.I.get(); 9 | 10 | final double size; 11 | final double percentSize; 12 | 13 | SearchButton({Key key, @required this.size, @required this.percentSize}) 14 | : super(key: key); 15 | @override 16 | Widget build(BuildContext context) { 17 | return InkWell( 18 | onTap: () => 19 | Navigator.of(context) 20 | .pushNamed(PropertiesPage.route), 21 | child: Container( 22 | height: size, 23 | width: MediaQuery.of(context).size.width * percentSize, 24 | padding: EdgeInsets.only(left: 10), 25 | decoration: BoxDecoration( 26 | color: LageColors.yellow, 27 | borderRadius: BorderRadius.circular(10)), 28 | child: Center( 29 | child: Text( 30 | 'BUSCAR', 31 | style: TextStyle(fontWeight: FontWeight.w800, fontSize: size*0.4), 32 | ), 33 | ), 34 | )); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/widgets/propertiesPage/notFoundWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/components/colors.dart'; 3 | 4 | class NotFoundWidget extends StatelessWidget { 5 | final double size; 6 | 7 | const NotFoundWidget({Key key, @required this.size}) : super(key: key); 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | margin: EdgeInsets.all(20), 12 | padding: EdgeInsets.all(20), 13 | child: Column( 14 | children: [ 15 | Container( 16 | height: size, 17 | decoration: BoxDecoration( 18 | image: DecorationImage(image: AssetImage("assets/images/House.png"))), 19 | ), 20 | ListTile( 21 | enabled: false, 22 | title: Text( 23 | "Desculpe :(", 24 | textAlign: TextAlign.center, 25 | style: TextStyle( 26 | color: Colors.black, 27 | fontWeight: FontWeight.bold, 28 | fontSize: 35), 29 | ), 30 | subtitle: Text( 31 | "Nenhuma propriedade encontrada", 32 | textAlign: TextAlign.center, 33 | style: TextStyle( 34 | color: LageColors.yellow, 35 | fontWeight: FontWeight.bold, 36 | fontSize: size == 300 ? 25 : 15), 37 | ), 38 | ), 39 | ], 40 | ), 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/widgets/contactPage/nameBar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:site_lage/components/colors.dart'; 5 | import 'package:site_lage/controllers/email_controller.dart'; 6 | 7 | class NameBar extends StatelessWidget { 8 | final emailController = GetIt.I.get(); 9 | 10 | final double percentSize; 11 | 12 | NameBar({Key key, @required this.percentSize}) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Container( 17 | height: 50, 18 | width: MediaQuery.of(context).size.width * percentSize, 19 | padding: EdgeInsets.only(left: 10), 20 | margin: EdgeInsets.symmetric(horizontal: 20), 21 | decoration: BoxDecoration( 22 | color: Colors.grey.withOpacity(0.2), 23 | borderRadius: BorderRadius.circular(10)), 24 | child: Observer( 25 | builder: (_) => TextFormField( 26 | cursorColor: LageColors.yellow, 27 | style: TextStyle(fontSize: 16), 28 | decoration: InputDecoration( 29 | border: InputBorder.none, 30 | hoverColor: LageColors.yellow, 31 | fillColor: LageColors.yellow, 32 | hintText: 'Digite seu email', 33 | hintStyle: TextStyle(fontSize: 16), 34 | errorText: emailController.error.name), 35 | onChanged: emailController.setName, 36 | ), 37 | ), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/widgets/contactPage/subjectBar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:site_lage/components/colors.dart'; 5 | import 'package:site_lage/controllers/email_controller.dart'; 6 | 7 | class SubjectBar extends StatelessWidget { 8 | final emailController = GetIt.I.get(); 9 | final double percentSize; 10 | 11 | SubjectBar({Key key, @required this.percentSize}) : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Container( 16 | height: 70, 17 | width: MediaQuery.of(context).size.width * percentSize, 18 | padding: EdgeInsets.only(left: 10), 19 | margin: EdgeInsets.symmetric(horizontal: 20), 20 | decoration: BoxDecoration( 21 | color: Colors.grey.withOpacity(0.2), 22 | borderRadius: BorderRadius.circular(10)), 23 | child: Observer( 24 | builder: (_) => TextFormField( 25 | cursorColor: LageColors.yellow, 26 | style: TextStyle(fontSize: 16), 27 | decoration: InputDecoration( 28 | border: InputBorder.none, 29 | hoverColor: LageColors.yellow, 30 | fillColor: LageColors.yellow, 31 | hintText: 'Assunto', 32 | hintStyle: TextStyle(fontSize: 16), 33 | errorText: emailController.error.subject), 34 | maxLines: 2, 35 | maxLength: 50, 36 | onChanged: emailController.setSubject, 37 | ), 38 | )); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_analytics/firebase_analytics.dart'; 2 | import 'package:firebase_analytics/observer.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | import 'package:google_fonts/google_fonts.dart'; 6 | import 'package:site_lage/components/colors.dart'; 7 | import 'package:site_lage/controllers/api_controller.dart'; 8 | import 'package:site_lage/controllers/email_controller.dart'; 9 | import 'package:site_lage/controllers/search_controller.dart'; 10 | import 'package:site_lage/pages/homePage.dart'; 11 | import 'package:site_lage/router/config.dart'; 12 | 13 | void main() { 14 | runApp(MyApp()); 15 | GetIt getIt = GetIt.I; 16 | getIt.registerSingleton(ApiController()); 17 | getIt.registerSingleton(SearchController()); 18 | getIt.registerSingleton(EmailController()); 19 | } 20 | 21 | class MyApp extends StatelessWidget { 22 | final FirebaseAnalytics analytics = FirebaseAnalytics(); 23 | @override 24 | Widget build(BuildContext context) { 25 | FirebaseAnalyticsObserver observer = 26 | FirebaseAnalyticsObserver(analytics: analytics); 27 | GetIt.I.registerSingleton(observer); 28 | return MaterialApp( 29 | title: 'Lage Imóveis', 30 | debugShowCheckedModeBanner: false, 31 | theme: ThemeData( 32 | textTheme: 33 | GoogleFonts.montserratTextTheme(Theme.of(context).textTheme), 34 | primaryColor: LageColors.yellow), 35 | initialRoute: HomePage.route, 36 | onGenerateRoute: RouteConfiguration.onGenerateRoute, 37 | navigatorObservers: [ 38 | observer, 39 | ], 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/widgets/homePage/searchBar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:site_lage/components/colors.dart'; 5 | import 'package:site_lage/controllers/search_controller.dart'; 6 | 7 | class SearchBar extends StatelessWidget { 8 | final searchController = GetIt.I.get(); 9 | final double size; 10 | final double percentSize; 11 | 12 | SearchBar({Key key, @required this.size, @required this.percentSize}) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Observer( 17 | builder: (_) => Container( 18 | height: size, 19 | width: MediaQuery.of(context).size.width * percentSize, 20 | padding: EdgeInsets.only(left: 10), 21 | decoration: BoxDecoration( 22 | color: Colors.white, borderRadius: BorderRadius.circular(10)), 23 | child: TextFormField( 24 | cursorColor: LageColors.yellow, 25 | style: TextStyle(fontSize: size*0.4), 26 | decoration: InputDecoration( 27 | border: InputBorder.none, 28 | hoverColor: LageColors.yellow, 29 | fillColor: LageColors.yellow, 30 | hintText: 'Pesquise por rua, bairro ou cidade', 31 | hintStyle: TextStyle(fontSize: size*0.4), 32 | ), 33 | initialValue: searchController.text, 34 | onChanged: searchController.setText, 35 | ), 36 | )); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | site_lage 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/widgets/homePage/propertiesList.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/homePage/propertyCard.dart'; 3 | import 'package:site_lage/widgets/homePage/propertyCardMobile.dart'; 4 | 5 | class PropertiesList extends StatelessWidget { 6 | final List properties; 7 | final String type; 8 | final double size; 9 | final int limit; 10 | 11 | const PropertiesList( 12 | {Key key, 13 | @required this.properties, 14 | this.type, 15 | @required this.size, 16 | this.limit}) 17 | : super(key: key); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | List filteredProperties = properties == null 22 | ? [] 23 | : type == null 24 | /* Retorna tudo */ 25 | ? properties 26 | : type.contains(",") 27 | ? properties 28 | .where((element) => type.split(",").contains(element.type)) 29 | .toList() 30 | : properties.where((element) => element.type == type).toList(); 31 | 32 | return Container( 33 | height: size, 34 | child: ListView.builder( 35 | padding: EdgeInsets.only(left: 20, top: 10, bottom: 10), 36 | scrollDirection: Axis.horizontal, 37 | itemCount: filteredProperties == null 38 | ? 0 39 | : limit == null ? filteredProperties.length : limit, 40 | itemBuilder: (context, index) => size == 300 41 | ? PropertyCard( 42 | property: filteredProperties[index], 43 | ) 44 | : PropertyCardMobile( 45 | property: filteredProperties[index], 46 | ), 47 | ), 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/widgets/contactPage/textBar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:site_lage/components/colors.dart'; 5 | import 'package:site_lage/controllers/email_controller.dart'; 6 | 7 | class TextBar extends StatelessWidget { 8 | final emailController = GetIt.I.get(); 9 | 10 | final double percentSize; 11 | final String initialText; 12 | 13 | TextBar({Key key, @required this.percentSize, this.initialText}) 14 | : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | if (initialText != null) emailController.setText(initialText); 19 | return Container( 20 | height: 140, 21 | width: MediaQuery.of(context).size.width * percentSize, 22 | padding: EdgeInsets.only(left: 10), 23 | margin: EdgeInsets.symmetric(horizontal: 20), 24 | decoration: BoxDecoration( 25 | color: Colors.grey.withOpacity(0.2), 26 | borderRadius: BorderRadius.circular(10)), 27 | child: Observer( 28 | builder: (_) => TextFormField( 29 | cursorColor: LageColors.yellow, 30 | style: TextStyle(fontSize: 16), 31 | initialValue: initialText, 32 | decoration: InputDecoration( 33 | border: InputBorder.none, 34 | hoverColor: LageColors.yellow, 35 | fillColor: LageColors.yellow, 36 | hintText: 'Texto', 37 | hintStyle: TextStyle(fontSize: 16), 38 | errorText: emailController.error.text), 39 | maxLines: 4, 40 | maxLengthEnforced: true, 41 | maxLength: 200, 42 | onChanged: emailController.setText, 43 | ), 44 | )); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/util/foorter/footer_desktop.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/util/foorter/footerInfo.dart'; 3 | import 'package:site_lage/util/foorter/footerLogo.dart'; 4 | 5 | class FooterDesktopAndTablet extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | height: 80, 10 | child: Row( 11 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 12 | children: [ 13 | // FooterItem( 14 | // title: "Lage Imóveis", 15 | // subtitle: "Filiada Rede Ipatinga Imóveis", 16 | // ), 17 | FooterLogo(), 18 | Row( 19 | mainAxisSize: MainAxisSize.min, 20 | children: [ 21 | Container( 22 | width: 2, 23 | color: Colors.black, 24 | margin: const EdgeInsets.only(right: 10), 25 | ), 26 | Column( 27 | mainAxisSize: MainAxisSize.max, 28 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 29 | crossAxisAlignment: CrossAxisAlignment.start, 30 | children: [ 31 | FooterInfo( 32 | icon: Icons.alternate_email, 33 | title: "contato@lageimoveis.com.br", 34 | ), 35 | FooterInfo( 36 | icon: Icons.phone, 37 | title: "(31) 3822-2535", 38 | ), 39 | FooterInfo( 40 | icon: Icons.business, 41 | title: 42 | "Rua Diamantina, 272 - Loja 02 Bairro Centro - Ipatinga/MG", 43 | ), 44 | ], 45 | ) 46 | ], 47 | ) 48 | ], 49 | ), 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/util/foorter/footer_mobile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/util/foorter/footerInfo.dart'; 3 | import 'package:site_lage/util/foorter/footerLogo.dart'; 4 | 5 | class FooterDesktopAndTablet extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | height: 80, 10 | child: Row( 11 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 12 | children: [ 13 | // FooterItem( 14 | // title: "Lage Imóveis", 15 | // subtitle: "Filiada Rede Ipatinga Imóveis", 16 | // ), 17 | FooterLogo(), 18 | Row( 19 | mainAxisSize: MainAxisSize.min, 20 | children: [ 21 | Container( 22 | width: 2, 23 | color: Colors.black, 24 | margin: const EdgeInsets.only(right: 10), 25 | ), 26 | Column( 27 | mainAxisSize: MainAxisSize.max, 28 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 29 | crossAxisAlignment: CrossAxisAlignment.start, 30 | children: [ 31 | FooterInfo( 32 | icon: Icons.alternate_email, 33 | title: "contato@lageimoveis.com.br", 34 | ), 35 | FooterInfo( 36 | icon: Icons.phone, 37 | title: "(31) 3822-2535", 38 | ), 39 | FooterInfo( 40 | icon: Icons.business, 41 | title: 42 | "Rua Diamantina, 272 - Loja 02 Bairro Centro - Ipatinga/MG", 43 | ), 44 | ], 45 | ) 46 | ], 47 | ) 48 | ], 49 | ), 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/pages/propertyPage/propertyPage_desktop.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/rendering.dart'; 3 | import 'package:site_lage/models/property.dart'; 4 | import 'package:site_lage/widgets/propertyPage/propertyContact.dart'; 5 | import 'package:site_lage/widgets/propertyPage/propertyDetails.dart'; 6 | import 'package:site_lage/widgets/propertyPage/propertyPhotos.dart'; 7 | 8 | class PropertyPageDesktop extends StatelessWidget { 9 | final Property property; 10 | 11 | const PropertyPageDesktop({Key key, this.property}) : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return ConstrainedBox( 16 | constraints: BoxConstraints( 17 | minHeight: MediaQuery.of(context).size.height * 0.85), 18 | child: Container( 19 | margin: EdgeInsets.symmetric(horizontal: 20), 20 | padding: EdgeInsets.symmetric(horizontal: 20), 21 | child: Row( 22 | crossAxisAlignment: CrossAxisAlignment.start, 23 | mainAxisSize: MainAxisSize.max, 24 | mainAxisAlignment: MainAxisAlignment.spaceAround, 25 | children: [ 26 | Column( 27 | mainAxisSize: MainAxisSize.min, 28 | children: [ 29 | PropertyDetails( 30 | property: property, 31 | percentSize: 0.4, 32 | ), 33 | PropertyContact( 34 | percentSize: 0.4, 35 | initText: "Olá, estou interessado(a) em " + 36 | property.title + 37 | " situado(a) no endereço " + 38 | property.address, 39 | ) 40 | ], 41 | ), 42 | PropertyPhotos( 43 | images: property.images, 44 | percentSize: 0.4, 45 | ), 46 | ], 47 | ), 48 | )); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.site_lage" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /lib/pages/aboutUsPage/aboutUsPage_desktop.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/aboutusPage/titleWidget.dart'; 3 | 4 | class AboutUsPageDesktop extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Container( 8 | child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ 9 | AboutUsTitleWidget( 10 | size: 600, 11 | textSize: 70, 12 | ), 13 | SizedBox(height: 50,), 14 | Padding( 15 | padding: EdgeInsets.symmetric(horizontal: 40, vertical: 10), 16 | child: Text( 17 | "LAGE IMÓVEIS entrou no ramo de imóveis há mais de 10 anos, com o intuito de apresentar ao mercado imobiliário um serviço diferenciado, visando atingir seus objetivos promovendo campanhas de marketing com um maior equilíbrio e sempre apresentando o seu maior diferencial, o atendimento.\nHoje dispomos de diversas soluções e serviços, sempre se preocupando em oferecer toda uma estrutura com atendimento de qualidade, além de conforto e segurança para que a transação com o cliente seja protegido com garantias de sucesso.", 18 | style: TextStyle(fontSize: 20), 19 | ), 20 | ), 21 | ListTile( 22 | enabled: false, 23 | contentPadding: EdgeInsets.symmetric(horizontal: 40), 24 | title: Text( 25 | "Nossa missão", 26 | style: TextStyle( 27 | fontSize: 30, fontWeight: FontWeight.bold, color: Colors.black), 28 | ), 29 | ), 30 | Padding( 31 | padding: EdgeInsets.symmetric(horizontal: 40, vertical: 20), 32 | child: Text( 33 | "Suprir as necessidades do segmento de imóveis, superando as expectativas de nossos clientes e empresas através de uma assessoria completa, com profissionais gabaritados, prestando serviços da mais alta qualidade, proporcionando soluções a preços justos e competitivos.", 34 | style: TextStyle(fontSize: 20), 35 | ), 36 | ), 37 | ]), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/pages/aboutUsPage/aboutUsPage_mobile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/aboutusPage/titleWidget.dart'; 3 | 4 | class AboutUsPageMobile extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Container( 8 | child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ 9 | AboutUsTitleWidget( 10 | size: 300, 11 | textSize: 35, 12 | ), 13 | SizedBox( 14 | height: 50, 15 | ), 16 | Padding( 17 | padding: EdgeInsets.symmetric(horizontal: 40, vertical: 10), 18 | child: Text( 19 | "LAGE IMÓVEIS entrou no ramo de imóveis há mais de 10 anos, com o intuito de apresentar ao mercado imobiliário um serviço diferenciado, visando atingir seus objetivos promovendo campanhas de marketing com um maior equilíbrio e sempre apresentando o seu maior diferencial, o atendimento.\nHoje dispomos de diversas soluções e serviços, sempre se preocupando em oferecer toda uma estrutura com atendimento de qualidade, além de conforto e segurança para que a transação com o cliente seja protegido com garantias de sucesso.", 20 | style: TextStyle(fontSize: 15), 21 | ), 22 | ), 23 | ListTile( 24 | enabled: false, 25 | contentPadding: EdgeInsets.symmetric(horizontal: 40), 26 | title: Text( 27 | "Nossa missão", 28 | style: TextStyle( 29 | fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black), 30 | ), 31 | ), 32 | Padding( 33 | padding: EdgeInsets.symmetric(horizontal: 40, vertical: 20), 34 | child: Text( 35 | "Suprir as necessidades do segmento de imóveis, superando as expectativas de nossos clientes e empresas através de uma assessoria completa, com profissionais gabaritados, prestando serviços da mais alta qualidade, proporcionando soluções a preços justos e competitivos.", 36 | style: TextStyle(fontSize: 15), 37 | ), 38 | ), 39 | ]), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/widgets/propertiesPage/propertyCardTile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/components/colors.dart'; 3 | import 'package:site_lage/models/property.dart'; 4 | import 'package:site_lage/pages/propertyPage.dart'; 5 | 6 | class PropertyCardTile extends StatelessWidget { 7 | final Property property; 8 | 9 | PropertyCardTile({Key key, @required this.property}) : super(key: key); 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | margin: EdgeInsets.symmetric(horizontal: 10, vertical: 5), 14 | padding: EdgeInsets.symmetric(vertical: 2), 15 | decoration: BoxDecoration(boxShadow: [ 16 | BoxShadow(blurRadius: 5, color: Colors.grey, offset: Offset(3, 3)) 17 | ], borderRadius: BorderRadius.circular(10), color: Colors.white), 18 | child: ListTile( 19 | leading: Container( 20 | height: 60, 21 | width: 60, 22 | decoration: BoxDecoration( 23 | borderRadius: BorderRadius.circular(5), 24 | image: DecorationImage( 25 | image: NetworkImage( 26 | property.images[0], 27 | ), 28 | fit: BoxFit.fill)), 29 | ), 30 | title: Text( 31 | property.title, 32 | style: TextStyle( 33 | color: Colors.black, 34 | fontSize: 15, 35 | fontWeight: FontWeight.bold), 36 | ), 37 | subtitle: Text( 38 | property.address, 39 | style: TextStyle(color: LageColors.yellow, fontSize: 10), 40 | ), 41 | trailing: Text( 42 | property.forSale ? "Venda" : "Aluguel", 43 | style: TextStyle( 44 | color: Colors.grey, 45 | fontSize: 10, 46 | fontStyle: FontStyle.italic), 47 | ), 48 | onTap: () => Navigator.of(context) 49 | .pushNamed(PropertyPage.route + '/' + property.sId))); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/controllers/api_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:mobx/mobx.dart'; 3 | import 'package:site_lage/components/connection.dart'; 4 | import 'package:site_lage/models/property.dart'; 5 | import 'package:http/http.dart' as http; 6 | part 'api_controller.g.dart'; 7 | 8 | class ApiController = _ApiControllerBase with _$ApiController; 9 | 10 | abstract class _ApiControllerBase with Store { 11 | @observable 12 | ObservableList properties; 13 | 14 | @observable 15 | bool loading = false; 16 | 17 | @observable 18 | Property property; 19 | 20 | @computed 21 | get propertiesList => properties.toList(); 22 | 23 | @action 24 | Future getAllproperties() async { 25 | if (properties != null) return properties; 26 | try { 27 | final response = await http 28 | .get(Constants.url + 'properties') 29 | .timeout(Constants.timeout, onTimeout: () => throw ("TimeoutError")); 30 | if (response.statusCode == 200) { 31 | var data = json.decode(utf8.decode(response.bodyBytes)); 32 | properties = new List.generate( 33 | data.length, (item) => Property.fromJson(data[item])) 34 | .asObservable(); 35 | return properties; 36 | } 37 | return null; 38 | } catch (error, stacktrace) { 39 | print("Erro ao carregar lista" + stacktrace.toString()); 40 | return null; 41 | } 42 | } 43 | 44 | @action 45 | Future getpropertyDetail(String id) async { 46 | try { 47 | loading = true; 48 | final response = await http 49 | .get(Constants.url + 'properties/' + id) 50 | .timeout(Constants.timeout, onTimeout: () => throw ("TimeoutError")); 51 | loading = false; 52 | if (response.statusCode == 200) { 53 | var data = json.decode(utf8.decode(response.bodyBytes)); 54 | 55 | property = Property.fromJson(data); 56 | return property; 57 | } 58 | return null; 59 | } catch (error, stacktrace) { 60 | loading = false; 61 | print("Erro ao carregar propriedade" + stacktrace.toString()); 62 | return null; 63 | } 64 | } 65 | 66 | @action 67 | void resetProperty() { 68 | loading = false; 69 | property = null; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/pages/aboutUsPage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:responsive_builder/responsive_builder.dart'; 3 | import 'package:site_lage/pages/aboutUsPage/aboutUsPage_desktop.dart'; 4 | import 'package:site_lage/pages/aboutUsPage/aboutUsPage_mobile.dart'; 5 | import 'package:site_lage/util/foorter/footer.dart'; 6 | import 'package:site_lage/util/navigationBar/navigationBar.dart'; 7 | import 'package:url_launcher/url_launcher.dart'; 8 | 9 | class AboutUsPage extends StatelessWidget { 10 | static const route = '/about'; 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold( 14 | body: Container( 15 | height: MediaQuery.of(context).size.height, 16 | child: NotificationListener( 17 | onNotification: (OverscrollIndicatorNotification overScroll) { 18 | overScroll.disallowGlow(); 19 | return false; 20 | }, 21 | child: SingleChildScrollView( 22 | physics: ClampingScrollPhysics(), 23 | child: Column( 24 | mainAxisSize: MainAxisSize.max, 25 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 26 | children: [ 27 | NavigationBar(), 28 | ConstrainedBox( 29 | constraints: BoxConstraints( 30 | minHeight: MediaQuery.of(context).size.height * 0.85), 31 | child: Container( 32 | alignment: Alignment.topCenter, 33 | child: ScreenTypeLayout( 34 | desktop: AboutUsPageDesktop(), 35 | tablet: AboutUsPageDesktop(), 36 | mobile: AboutUsPageMobile(), 37 | ), 38 | ), 39 | ), 40 | Footer() 41 | ], 42 | ), 43 | ), 44 | ), 45 | ), 46 | floatingActionButton: new FloatingActionButton( 47 | onPressed: () => 48 | launch("https://api.whatsapp.com/send?phone=553138222535"), 49 | child: Image.asset( 50 | "assets/images/whatsapp-24.png", 51 | fit: BoxFit.none, 52 | ), 53 | backgroundColor: const Color(0xff25D366), 54 | ), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/widgets/homePage/propertyCard.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/components/colors.dart'; 3 | import 'package:site_lage/models/property.dart'; 4 | import 'package:site_lage/pages/propertyPage.dart'; 5 | 6 | class PropertyCard extends StatelessWidget { 7 | final Property property; 8 | 9 | PropertyCard({Key key, this.property}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Container( 14 | margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10), 15 | width: 350, 16 | height: 300, 17 | decoration: BoxDecoration( 18 | color: Colors.white, 19 | borderRadius: BorderRadius.circular(10), 20 | image: DecorationImage( 21 | image: NetworkImage( 22 | property.images[0], 23 | ), 24 | fit: BoxFit.fill), 25 | boxShadow: [ 26 | BoxShadow(blurRadius: 10, offset: Offset(5, 5), color: Colors.grey) 27 | ]), 28 | child: Align( 29 | alignment: Alignment.bottomCenter, 30 | child: Container( 31 | height: 80, 32 | decoration: BoxDecoration( 33 | color: Colors.black.withOpacity(0.7), 34 | borderRadius: BorderRadius.only( 35 | bottomRight: Radius.circular(10), 36 | bottomLeft: Radius.circular(10)), 37 | ), 38 | child: ListTile( 39 | title: Text( 40 | property.title, 41 | style: TextStyle( 42 | color: Colors.white, 43 | fontSize: 22, 44 | fontWeight: FontWeight.bold), 45 | ), 46 | subtitle: Text( 47 | property.address, 48 | style: TextStyle(color: LageColors.yellow, fontSize: 12), 49 | ), 50 | trailing: Text( 51 | property.forSale ? "Venda" : "Aluguel", 52 | style: TextStyle( 53 | color: Colors.white, 54 | fontSize: 16, 55 | fontStyle: FontStyle.italic), 56 | ), 57 | onTap: () => Navigator.of(context) 58 | .pushNamed(PropertyPage.route + '/' + property.sId), 59 | ), 60 | ), 61 | ), 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/widgets/homePage/propertyCardMobile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/components/colors.dart'; 3 | import 'package:site_lage/models/property.dart'; 4 | import 'package:site_lage/pages/propertyPage.dart'; 5 | 6 | class PropertyCardMobile extends StatelessWidget { 7 | final Property property; 8 | 9 | PropertyCardMobile({Key key, this.property}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Container( 14 | margin: EdgeInsets.symmetric(horizontal: 5), 15 | width: 200, 16 | height: 200, 17 | decoration: BoxDecoration( 18 | color: Colors.white, 19 | borderRadius: BorderRadius.circular(10), 20 | image: DecorationImage( 21 | image: NetworkImage( 22 | property.images[0], 23 | ), 24 | fit: BoxFit.fill), 25 | boxShadow: [ 26 | BoxShadow(blurRadius: 10, offset: Offset(5, 5), color: Colors.grey) 27 | ]), 28 | child: Align( 29 | alignment: Alignment.bottomCenter, 30 | child: Container( 31 | height: 70, 32 | decoration: BoxDecoration( 33 | color: Colors.black.withOpacity(0.7), 34 | borderRadius: BorderRadius.only( 35 | bottomRight: Radius.circular(10), 36 | bottomLeft: Radius.circular(10)), 37 | ), 38 | child: ListTile( 39 | title: Text( 40 | property.title, 41 | style: TextStyle( 42 | color: Colors.white, 43 | fontSize: 15, 44 | fontWeight: FontWeight.bold), 45 | ), 46 | subtitle: Text( 47 | property.address, 48 | style: TextStyle(color: LageColors.yellow, fontSize: 8), 49 | ), 50 | trailing: Text( 51 | property.forSale ? "Venda" : "Aluguel", 52 | style: TextStyle( 53 | color: Colors.white, 54 | fontSize: 10, 55 | fontStyle: FontStyle.italic), 56 | ), 57 | onTap: () => Navigator.of(context) 58 | .pushNamed(PropertyPage.route + '/' + property.sId), 59 | ), 60 | ), 61 | ), 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/widgets/propertiesPage/propertiesTitleWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/homePage/dropdownButtons.dart'; 3 | import 'package:site_lage/widgets/homePage/searchBar.dart'; 4 | import 'package:site_lage/widgets/homePage/searchButton.dart'; 5 | 6 | class PropertiesTitleWidget extends StatelessWidget { 7 | final double size; 8 | final double textSize; 9 | final double percentSize; 10 | 11 | const PropertiesTitleWidget( 12 | {Key key, 13 | @required this.size, 14 | @required this.textSize, 15 | @required this.percentSize}) 16 | : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return Container( 21 | height: size, 22 | width: MediaQuery.of(context).size.width, 23 | decoration: BoxDecoration( 24 | image: DecorationImage( 25 | fit: BoxFit.cover, 26 | image: AssetImage("assets/images/properties.jpg")), 27 | ), 28 | child: Container( 29 | color: Colors.black.withOpacity(0.8), 30 | child: Column( 31 | mainAxisAlignment: MainAxisAlignment.spaceAround, 32 | children: [ 33 | Center( 34 | child: Text( 35 | "Todos os imóveis", 36 | style: TextStyle( 37 | fontSize: textSize, 38 | color: Colors.white, 39 | fontWeight: FontWeight.bold), 40 | ), 41 | ), 42 | Column( 43 | children: [ 44 | SearchBar( 45 | size: size * 0.1, 46 | percentSize: percentSize, 47 | ), 48 | SizedBox( 49 | height: 10, 50 | ), 51 | DropdownButtons( 52 | size: size * 0.1, 53 | percentSize: percentSize, 54 | ), 55 | SizedBox( 56 | height: 10, 57 | ), 58 | SearchButton( 59 | size: size * 0.1, 60 | percentSize: percentSize, 61 | ) 62 | ], 63 | ) 64 | ], 65 | ), 66 | )); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/widgets/homePage/searchWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/homePage/dropdownButtons.dart'; 3 | import 'package:site_lage/widgets/homePage/searchBar.dart'; 4 | import 'package:site_lage/widgets/homePage/searchButton.dart'; 5 | 6 | class SearchWidget extends StatelessWidget { 7 | final int number; 8 | final double size; 9 | final double textSize; 10 | final double percentSize; 11 | 12 | const SearchWidget( 13 | {Key key, 14 | this.number, 15 | @required this.size, 16 | @required this.textSize, 17 | @required this.percentSize}) 18 | : super(key: key); 19 | @override 20 | Widget build(BuildContext context) { 21 | return Container( 22 | height: size, 23 | width: MediaQuery.of(context).size.width, 24 | decoration: BoxDecoration( 25 | image: DecorationImage( 26 | fit: BoxFit.cover, 27 | image: AssetImage("assets/images/Lage_Wpp_" + number.toString() + ".jpg"), 28 | )), 29 | child: Container( 30 | padding: EdgeInsets.symmetric(vertical: 20), 31 | color: Colors.black.withOpacity(0.8), 32 | child: Column( 33 | mainAxisAlignment: MainAxisAlignment.spaceAround, 34 | children: [ 35 | Center( 36 | child: Text( 37 | "Faça sua busca online", 38 | textAlign: TextAlign.center, 39 | style: TextStyle( 40 | fontSize: textSize, 41 | color: Colors.white, 42 | fontWeight: FontWeight.bold), 43 | ), 44 | ), 45 | Column( 46 | children: [ 47 | SearchBar( 48 | size: size * 0.1, 49 | percentSize: percentSize, 50 | ), 51 | SizedBox( 52 | height: 10, 53 | ), 54 | DropdownButtons( 55 | size: size * 0.1, 56 | percentSize: percentSize, 57 | ), 58 | SizedBox( 59 | height: 10, 60 | ), 61 | SearchButton(size: size * 0.1, percentSize: percentSize) 62 | ], 63 | ) 64 | ], 65 | )), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/pages/contactPage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get_it/get_it.dart'; 3 | import 'package:responsive_builder/responsive_builder.dart'; 4 | import 'package:site_lage/controllers/email_controller.dart'; 5 | import 'package:site_lage/pages/contactPage/contactPage_desktop.dart'; 6 | import 'package:site_lage/pages/contactPage/contactPage_mobile.dart'; 7 | import 'package:site_lage/util/foorter/footer.dart'; 8 | import 'package:site_lage/util/navigationBar/navigationBar.dart'; 9 | import 'package:url_launcher/url_launcher.dart'; 10 | 11 | class ContactPage extends StatelessWidget { 12 | static const route = '/contact'; 13 | final emailController = GetIt.I.get(); 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | body: Container( 18 | height: MediaQuery.of(context).size.height, 19 | child: NotificationListener( 20 | onNotification: (OverscrollIndicatorNotification overScroll) { 21 | overScroll.disallowGlow(); 22 | return false; 23 | }, 24 | child: SingleChildScrollView( 25 | physics: ClampingScrollPhysics(), 26 | child: Column( 27 | mainAxisSize: MainAxisSize.max, 28 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 29 | children: [ 30 | NavigationBar(), 31 | ConstrainedBox( 32 | constraints: BoxConstraints( 33 | minHeight: MediaQuery.of(context).size.height * 0.85), 34 | child: Container( 35 | alignment: Alignment.topCenter, 36 | child: ScreenTypeLayout( 37 | desktop: ContactPageDesktop(), 38 | tablet: ContactPageDesktop(), 39 | mobile: ContactPageMobile(), 40 | )), 41 | ), 42 | Footer() 43 | ], 44 | ), 45 | ), 46 | ), 47 | ), 48 | floatingActionButton: new FloatingActionButton( 49 | onPressed: () => 50 | launch("https://api.whatsapp.com/send?phone=553138222535"), 51 | child: Image.asset( 52 | "assets/images/whatsapp-24.png", 53 | fit: BoxFit.none, 54 | ), 55 | backgroundColor: const Color(0xff25D366), 56 | ), 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/models/property.dart: -------------------------------------------------------------------------------- 1 | class Property { 2 | bool active; 3 | List images; 4 | String sId; 5 | String title; 6 | String description; 7 | int price; 8 | String type; 9 | bool forSale; 10 | bool forRent; 11 | String address; 12 | int qtdRooms; 13 | int qtdBathrooms; 14 | int qtdGarage; 15 | bool haveSuit; 16 | double frontDimensions; 17 | double sideDimensions; 18 | double totalArea; 19 | int iV; 20 | 21 | Property( 22 | {this.active, 23 | this.images, 24 | this.sId, 25 | this.title, 26 | this.description, 27 | this.price, 28 | this.type, 29 | this.forSale, 30 | this.forRent, 31 | this.address, 32 | this.qtdRooms, 33 | this.qtdBathrooms, 34 | this.qtdGarage, 35 | this.haveSuit, 36 | this.frontDimensions, 37 | this.sideDimensions, 38 | this.totalArea, 39 | this.iV}); 40 | 41 | Property.fromJson(Map json) { 42 | active = json['active']; 43 | images = json['images'].cast(); 44 | sId = json['_id']; 45 | title = json['title']; 46 | description = json['description']; 47 | price = json['price']; 48 | type = json['type']; 49 | forSale = json['forSale']; 50 | forRent = json['forRent']; 51 | address = json['address']; 52 | qtdRooms = json['qtdRooms']; 53 | qtdBathrooms = json['qtdBathrooms']; 54 | qtdGarage = json['qtdGarage']; 55 | haveSuit = json['haveSuit']; 56 | frontDimensions = json['frontDimensions']; 57 | sideDimensions = json['sideDimensions']; 58 | totalArea = json['totalArea']; 59 | iV = json['__v']; 60 | } 61 | 62 | Map toJson() { 63 | final Map data = new Map(); 64 | data['active'] = this.active; 65 | data['images'] = this.images; 66 | data['_id'] = this.sId; 67 | data['title'] = this.title; 68 | data['description'] = this.description; 69 | data['price'] = this.price; 70 | data['type'] = this.type; 71 | data['forSale'] = this.forSale; 72 | data['forRent'] = this.forRent; 73 | data['address'] = this.address; 74 | data['qtdRooms'] = this.qtdRooms; 75 | data['qtdBathrooms'] = this.qtdBathrooms; 76 | data['qtdGarage'] = this.qtdGarage; 77 | data['haveSuit'] = this.haveSuit; 78 | data['frontDimensions'] = this.frontDimensions; 79 | data['sideDimensions'] = this.sideDimensions; 80 | data['totalArea'] = this.totalArea; 81 | data['__v'] = this.iV; 82 | return data; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/pages/simulationPage/simulationPage_desktop.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/simulations/simulationTitle.dart'; 3 | import 'package:url_launcher/url_launcher.dart'; 4 | 5 | class SimulationPageDesktop extends StatelessWidget { 6 | final List options; 7 | final List links; 8 | 9 | const SimulationPageDesktop({Key key, this.options, this.links}) 10 | : super(key: key); 11 | @override 12 | Widget build(BuildContext context) { 13 | return Container( 14 | child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ 15 | SimulationTitleWidget( 16 | size: 600, 17 | fontSize: 70, 18 | ), 19 | SizedBox( 20 | height: 50, 21 | ), 22 | Padding( 23 | padding: EdgeInsets.symmetric(horizontal: 40, vertical: 10), 24 | child: Text( 25 | "Escolha um dos bancos abaixo para abrir seus simuladores de financiamento imobiliário.", 26 | style: TextStyle(fontSize: 20), 27 | ), 28 | ), 29 | Padding( 30 | padding: EdgeInsets.symmetric(horizontal: 30), 31 | child: GridView.builder( 32 | physics: NeverScrollableScrollPhysics(), 33 | shrinkWrap: true, 34 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 35 | crossAxisCount: MediaQuery.of(context).size.width ~/ 200, 36 | childAspectRatio: 400 / 280), 37 | itemCount: options.length, 38 | itemBuilder: (context, index) => InkWell( 39 | child: Container( 40 | margin: EdgeInsets.all(10), 41 | decoration: BoxDecoration( 42 | borderRadius: BorderRadius.circular(10), 43 | image: DecorationImage( 44 | image: AssetImage( 45 | "assets/images/" + options[index] + ".jpg"), 46 | fit: BoxFit.fill)), 47 | ), 48 | canRequestFocus: true, 49 | focusColor: Colors.transparent, 50 | hoverColor: Colors.transparent, 51 | highlightColor: Colors.transparent, 52 | splashColor: Colors.transparent, 53 | onTap: () => launch(links[index]), 54 | ))), 55 | SizedBox( 56 | height: 40, 57 | ) 58 | ]), 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/pages/simulationPage/simulationPage_mobile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/widgets/simulations/simulationTitle.dart'; 3 | import 'package:url_launcher/url_launcher.dart'; 4 | 5 | class SimulationPageMobile extends StatelessWidget { 6 | final List options; 7 | final List links; 8 | 9 | const SimulationPageMobile({Key key, this.options, this.links}) 10 | : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return Container( 15 | child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ 16 | SimulationTitleWidget( 17 | size: 300, 18 | fontSize: 35, 19 | ), 20 | SizedBox( 21 | height: 50, 22 | ), 23 | Padding( 24 | padding: EdgeInsets.symmetric(horizontal: 40, vertical: 10), 25 | child: Text( 26 | "Escolha um dos bancos abaixo para abrir seus simuladores de financiamento imobiliário.", 27 | style: TextStyle(fontSize: 15), 28 | ), 29 | ), 30 | Padding( 31 | padding: EdgeInsets.symmetric(horizontal: 30), 32 | child: GridView.builder( 33 | physics: NeverScrollableScrollPhysics(), 34 | shrinkWrap: true, 35 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 36 | crossAxisCount: MediaQuery.of(context).size.width ~/ 200, 37 | childAspectRatio: 400 / 280), 38 | itemCount: options.length, 39 | itemBuilder: (context, index) => InkWell( 40 | child: Container( 41 | margin: EdgeInsets.all(10), 42 | decoration: BoxDecoration( 43 | borderRadius: BorderRadius.circular(10), 44 | image: DecorationImage( 45 | image: AssetImage( 46 | "assets/images/" + options[index] + ".jpg"), 47 | fit: BoxFit.fill)), 48 | ), 49 | canRequestFocus: true, 50 | focusColor: Colors.transparent, 51 | hoverColor: Colors.transparent, 52 | highlightColor: Colors.transparent, 53 | splashColor: Colors.transparent, 54 | onTap: () => launch(links[index]), 55 | ))), 56 | SizedBox( 57 | height: 40, 58 | ) 59 | ]), 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/widgets/contactPage/dataWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get_it/get_it.dart'; 3 | import 'package:site_lage/components/colors.dart'; 4 | import 'package:site_lage/controllers/email_controller.dart'; 5 | import 'package:site_lage/widgets/contactPage/nameBar.dart'; 6 | import 'package:site_lage/widgets/contactPage/subjectBar.dart'; 7 | import 'package:site_lage/widgets/contactPage/submitButton.dart'; 8 | import 'package:site_lage/widgets/contactPage/textBar.dart'; 9 | 10 | class DataWidget extends StatelessWidget { 11 | final emailController = GetIt.I.get(); 12 | 13 | final double percentSize; 14 | final double fontSize; 15 | 16 | DataWidget({Key key, @required this.percentSize, @required this.fontSize}) 17 | : super(key: key); 18 | @override 19 | Widget build(BuildContext context) { 20 | return Container( 21 | child: Column( 22 | crossAxisAlignment: CrossAxisAlignment.start, 23 | children: [ 24 | ListTile( 25 | enabled: false, 26 | title: Text( 27 | "Lage Imóveis", 28 | style: TextStyle( 29 | color: Colors.black, 30 | fontWeight: FontWeight.bold, 31 | fontSize: fontSize), 32 | ), 33 | subtitle: Text( 34 | "CRECI MG 1915", 35 | style: TextStyle( 36 | color: LageColors.yellow, 37 | fontWeight: FontWeight.bold, 38 | fontSize: fontSize * 0.8), 39 | ), 40 | ), 41 | Container( 42 | height: 1, 43 | padding: EdgeInsets.symmetric(horizontal: 20), 44 | margin: EdgeInsets.symmetric(horizontal: 20), 45 | width: MediaQuery.of(context).size.width * percentSize, 46 | color: Colors.grey, 47 | ), 48 | ListTile( 49 | enabled: false, 50 | title: Text( 51 | "Alguma dúvida? Nos envie um email!", 52 | style: TextStyle(color: Colors.black, fontSize: fontSize*0.5), 53 | ), 54 | ), 55 | NameBar( 56 | percentSize: percentSize, 57 | ), 58 | SizedBox( 59 | height: 10, 60 | ), 61 | SubjectBar( 62 | percentSize: percentSize, 63 | ), 64 | SizedBox( 65 | height: 10, 66 | ), 67 | TextBar( 68 | percentSize: percentSize, 69 | ), 70 | SizedBox( 71 | height: 10, 72 | ), 73 | SubmitButton( 74 | percentSize: percentSize, 75 | ) 76 | ], 77 | )); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /lib/widgets/contactPage/submitButton.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get_it/get_it.dart'; 3 | import 'package:site_lage/components/colors.dart'; 4 | import 'package:site_lage/controllers/email_controller.dart'; 5 | 6 | class SubmitButton extends StatelessWidget { 7 | final emailController = GetIt.I.get(); 8 | 9 | final double percentSize; 10 | 11 | SubmitButton({Key key, @required this.percentSize}) : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return InkWell( 16 | child: Container( 17 | height: 50, 18 | width: MediaQuery.of(context).size.width * percentSize, 19 | padding: EdgeInsets.only(left: 10), 20 | margin: EdgeInsets.symmetric(horizontal: 20), 21 | decoration: BoxDecoration( 22 | color: LageColors.yellow, borderRadius: BorderRadius.circular(10)), 23 | child: Center( 24 | child: Text( 25 | "ENVIAR", 26 | style: TextStyle( 27 | color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20), 28 | ), 29 | ), 30 | ), 31 | onTap: () => emailController.validateAll().then((value) { 32 | if (value) { 33 | showDialog( 34 | barrierDismissible: false, 35 | context: context, 36 | builder: (_) => AlertDialog( 37 | content: ListTile( 38 | leading: CircularProgressIndicator( 39 | valueColor: AlwaysStoppedAnimation(LageColors.yellow), 40 | ), 41 | title: Text("Aguarde"), 42 | subtitle: Text('Enviando email'), 43 | ), 44 | ), 45 | ); 46 | emailController.submit().then((value) { 47 | Navigator.pop(context); 48 | showDialog( 49 | context: context, 50 | barrierDismissible: false, 51 | builder: (_) { 52 | Future.delayed(Duration(seconds: 3), () { 53 | Navigator.pop(context); 54 | }); 55 | 56 | return AlertDialog( 57 | content: ListTile( 58 | leading: Icon( 59 | value ? Icons.check_circle : Icons.cancel, 60 | color: LageColors.yellow, 61 | size: 40, 62 | ), 63 | title: value ? Text("Sucesso!") : Text("Ops!"), 64 | subtitle: value 65 | ? Text('Email enviado com sucesso!') 66 | : Text("ocorreu um erro, tente novamente")), 67 | ); 68 | }); 69 | }); 70 | } 71 | }), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/pages/propertiesPage/propertiesPage_mobile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:site_lage/controllers/search_controller.dart'; 5 | import 'package:site_lage/widgets/propertiesPage/notFoundWidget.dart'; 6 | import 'package:site_lage/widgets/propertiesPage/propertiesTitleWidget.dart'; 7 | import 'package:site_lage/widgets/propertiesPage/propertyCardTile.dart'; 8 | import 'package:skeleton_text/skeleton_text.dart'; 9 | 10 | class PropertiesPageMobile extends StatelessWidget { 11 | final searchController = GetIt.I.get(); 12 | final AsyncSnapshot snapshot; 13 | 14 | PropertiesPageMobile({Key key, @required this.snapshot}) : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Column( 19 | mainAxisSize: MainAxisSize.max, 20 | children: [ 21 | PropertiesTitleWidget( 22 | percentSize: 0.8, 23 | size: 300, 24 | textSize: 35, 25 | ), 26 | snapshot.connectionState == ConnectionState.waiting 27 | ? ListView.builder( 28 | physics: NeverScrollableScrollPhysics(), 29 | shrinkWrap: true, 30 | scrollDirection: Axis.vertical, 31 | itemCount: searchController.filteredList.length, 32 | itemBuilder: (context, index) => SkeletonAnimation( 33 | child: Container( 34 | margin: 35 | EdgeInsets.symmetric(horizontal: 10, vertical: 5), 36 | padding: EdgeInsets.symmetric(vertical: 2), 37 | decoration: BoxDecoration( 38 | borderRadius: BorderRadius.circular(10), 39 | color: Colors.grey), 40 | ), 41 | )) 42 | : Observer( 43 | builder: (context) => searchController.filteredList.length > 0 44 | ? ConstrainedBox( 45 | constraints: BoxConstraints(minHeight: 500), 46 | child: ListView.builder( 47 | physics: NeverScrollableScrollPhysics(), 48 | shrinkWrap: true, 49 | scrollDirection: Axis.vertical, 50 | itemCount: searchController.filteredList.length, 51 | itemBuilder: (context, index) => PropertyCardTile( 52 | property: 53 | searchController.filteredList.elementAt(index), 54 | ), 55 | ), 56 | ) 57 | : Container( 58 | margin: EdgeInsets.symmetric(horizontal: 20), 59 | child: NotFoundWidget( 60 | size: 150, 61 | ), 62 | ), 63 | ), 64 | ], 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/controllers/email_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:mobx/mobx.dart'; 4 | import 'package:http/http.dart' as http; 5 | import 'package:site_lage/components/connection.dart'; 6 | part 'email_controller.g.dart'; 7 | 8 | class EmailController = _EmailControllerBase with _$EmailController; 9 | 10 | abstract class _EmailControllerBase with Store { 11 | @observable 12 | String name = ""; 13 | 14 | @observable 15 | String subject = ""; 16 | 17 | @observable 18 | String text = ""; 19 | 20 | @action 21 | void setName(String val) { 22 | name = val; 23 | } 24 | 25 | @action 26 | void setSubject(String val) { 27 | subject = val; 28 | } 29 | 30 | @action 31 | void setText(String val) { 32 | text = val; 33 | } 34 | 35 | @action 36 | Future submit() async { 37 | var response = await http 38 | .post(Constants.url + "email/sendEmail", 39 | headers: { 40 | "Content-Type": "application/json", 41 | }, 42 | body: json.encode( 43 | {"userMail": name, "subject": subject, "text": text}, 44 | )) 45 | .timeout((Constants.timeout), 46 | onTimeout: () => http.Response( 47 | json.encode({'error': "Servidor demorou para responder"}), 48 | 400)); 49 | if (response.statusCode == 200) 50 | return true; 51 | else 52 | return false; 53 | } 54 | 55 | List _disposers; 56 | 57 | void setupValidations() { 58 | _disposers = [ 59 | reaction((_) => name, validateName), 60 | reaction((_) => subject, validateSubject), 61 | reaction((_) => text, validateText) 62 | ]; 63 | } 64 | 65 | /* AÇÕES DE VALIDAÇÃO */ 66 | 67 | final FormErrorState error = FormErrorState(); 68 | 69 | @action 70 | void validateName(String value) { 71 | error.name = value == null || value.isEmpty 72 | ? "Digite seu email" 73 | : !value.contains("@") && !value.contains(".com") 74 | ? "Digite um email válido" 75 | : null; 76 | } 77 | 78 | @action 79 | void validateSubject(String value) { 80 | error.subject = value == null || value.isEmpty ? "Digite um assunto" : null; 81 | } 82 | 83 | @action 84 | void validateText(String value) { 85 | error.text = value == null || value.isEmpty ? "Digite um texto" : null; 86 | } 87 | 88 | /* Verifica a ausencia de erros */ 89 | @computed 90 | bool get canContinue => !error.hasErrors; 91 | 92 | void dispose() { 93 | for (final d in _disposers) d(); 94 | } 95 | 96 | Future validateAll() async { 97 | validateName(name); 98 | validateSubject(subject); 99 | validateText(text); 100 | 101 | return canContinue; 102 | } 103 | } 104 | 105 | class FormErrorState = _FormErrorStateBase with _$FormErrorState; 106 | 107 | abstract class _FormErrorStateBase with Store { 108 | @observable 109 | String name; 110 | 111 | @observable 112 | String subject; 113 | 114 | @observable 115 | String text; 116 | 117 | @computed 118 | bool get hasErrors => name != null || subject != null || text != null; 119 | } 120 | -------------------------------------------------------------------------------- /lib/controllers/api_controller.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'api_controller.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic 10 | 11 | mixin _$ApiController on _ApiControllerBase, Store { 12 | Computed _$propertiesListComputed; 13 | 14 | @override 15 | dynamic get propertiesList => (_$propertiesListComputed ??= 16 | Computed(() => super.propertiesList)) 17 | .value; 18 | 19 | final _$propertiesAtom = Atom(name: '_ApiControllerBase.properties'); 20 | 21 | @override 22 | ObservableList get properties { 23 | _$propertiesAtom.context.enforceReadPolicy(_$propertiesAtom); 24 | _$propertiesAtom.reportObserved(); 25 | return super.properties; 26 | } 27 | 28 | @override 29 | set properties(ObservableList value) { 30 | _$propertiesAtom.context.conditionallyRunInAction(() { 31 | super.properties = value; 32 | _$propertiesAtom.reportChanged(); 33 | }, _$propertiesAtom, name: '${_$propertiesAtom.name}_set'); 34 | } 35 | 36 | final _$loadingAtom = Atom(name: '_ApiControllerBase.loading'); 37 | 38 | @override 39 | bool get loading { 40 | _$loadingAtom.context.enforceReadPolicy(_$loadingAtom); 41 | _$loadingAtom.reportObserved(); 42 | return super.loading; 43 | } 44 | 45 | @override 46 | set loading(bool value) { 47 | _$loadingAtom.context.conditionallyRunInAction(() { 48 | super.loading = value; 49 | _$loadingAtom.reportChanged(); 50 | }, _$loadingAtom, name: '${_$loadingAtom.name}_set'); 51 | } 52 | 53 | final _$propertyAtom = Atom(name: '_ApiControllerBase.property'); 54 | 55 | @override 56 | Property get property { 57 | _$propertyAtom.context.enforceReadPolicy(_$propertyAtom); 58 | _$propertyAtom.reportObserved(); 59 | return super.property; 60 | } 61 | 62 | @override 63 | set property(Property value) { 64 | _$propertyAtom.context.conditionallyRunInAction(() { 65 | super.property = value; 66 | _$propertyAtom.reportChanged(); 67 | }, _$propertyAtom, name: '${_$propertyAtom.name}_set'); 68 | } 69 | 70 | final _$getAllpropertiesAsyncAction = AsyncAction('getAllproperties'); 71 | 72 | @override 73 | Future getAllproperties() { 74 | return _$getAllpropertiesAsyncAction.run(() => super.getAllproperties()); 75 | } 76 | 77 | final _$getpropertyDetailAsyncAction = AsyncAction('getpropertyDetail'); 78 | 79 | @override 80 | Future getpropertyDetail(String id) { 81 | return _$getpropertyDetailAsyncAction 82 | .run(() => super.getpropertyDetail(id)); 83 | } 84 | 85 | final _$_ApiControllerBaseActionController = 86 | ActionController(name: '_ApiControllerBase'); 87 | 88 | @override 89 | void resetProperty() { 90 | final _$actionInfo = _$_ApiControllerBaseActionController.startAction(); 91 | try { 92 | return super.resetProperty(); 93 | } finally { 94 | _$_ApiControllerBaseActionController.endAction(_$actionInfo); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /lib/pages/simulationPage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:responsive_builder/responsive_builder.dart'; 3 | import 'package:site_lage/pages/simulationPage/simulationPage_desktop.dart'; 4 | import 'package:site_lage/pages/simulationPage/simulationPage_mobile.dart'; 5 | import 'package:site_lage/util/foorter/footer.dart'; 6 | import 'package:site_lage/util/navigationBar/navigationBar.dart'; 7 | import 'package:url_launcher/url_launcher.dart'; 8 | 9 | class SimulationPage extends StatelessWidget { 10 | static const route = '/simulation'; 11 | final List options = ["BB", "Caixa", "Santander", "Bradesco", "Itau"]; 12 | final List links = [ 13 | "https://www42.bb.com.br/portalbb/imobiliario/creditoimobiliario/simular,802,2250,2250.bbx", 14 | "http://www8.caixa.gov.br/siopiinternet-web/simulaOperacaoInternet.do?method=inicializarCasoUso", 15 | "https://www.santander.com.br/portal/wps/script/templates/GCMRequest.do?page=5516", 16 | "https://banco.bradesco/html/classic/produtos-servicos/emprestimo-e-financiamento/encontre-seu-credito/simuladores-imoveis.shtm#box1-comprar", 17 | "https://www.itau.com.br/creditos-financiamentos/imoveis/simulador/" 18 | ]; 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return Scaffold( 23 | body: Container( 24 | height: MediaQuery.of(context).size.height, 25 | child: NotificationListener( 26 | onNotification: (OverscrollIndicatorNotification overScroll) { 27 | overScroll.disallowGlow(); 28 | return false; 29 | }, 30 | child: SingleChildScrollView( 31 | physics: ClampingScrollPhysics(), 32 | child: Column( 33 | mainAxisSize: MainAxisSize.max, 34 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 35 | children: [ 36 | NavigationBar(), 37 | ConstrainedBox( 38 | constraints: BoxConstraints( 39 | minHeight: MediaQuery.of(context).size.height * 0.85), 40 | child: Container( 41 | alignment: Alignment.topCenter, 42 | child: ScreenTypeLayout( 43 | desktop: SimulationPageDesktop( 44 | links: links, 45 | options: options, 46 | ), 47 | tablet: SimulationPageDesktop( 48 | links: links, 49 | options: options, 50 | ), 51 | mobile: SimulationPageMobile( 52 | links: links, 53 | options: options, 54 | ), 55 | ), 56 | ), 57 | ), 58 | Footer() 59 | ], 60 | ), 61 | ), 62 | ), 63 | ), 64 | floatingActionButton: new FloatingActionButton( 65 | onPressed: () => 66 | launch("https://api.whatsapp.com/send?phone=553138222535"), 67 | child: Image.asset( 68 | "assets/images/whatsapp-24.png", 69 | fit: BoxFit.none, 70 | ), 71 | backgroundColor: const Color(0xff25D366), 72 | ), 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/pages/propertiesPage/propertiesPage_desktop.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:site_lage/controllers/search_controller.dart'; 5 | import 'package:site_lage/widgets/homePage/propertyCard.dart'; 6 | import 'package:site_lage/widgets/propertiesPage/notFoundWidget.dart'; 7 | import 'package:site_lage/widgets/propertiesPage/propertiesTitleWidget.dart'; 8 | import 'package:skeleton_text/skeleton_text.dart'; 9 | 10 | class PropertiesPageDesktop extends StatelessWidget { 11 | final searchController = GetIt.I.get(); 12 | final AsyncSnapshot snapshot; 13 | 14 | PropertiesPageDesktop({Key key, @required this.snapshot}) : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Column( 19 | mainAxisSize: MainAxisSize.max, 20 | children: [ 21 | PropertiesTitleWidget( 22 | size: 600, 23 | textSize: 70, 24 | percentSize: 0.6, 25 | ), 26 | Container( 27 | margin: EdgeInsets.symmetric(horizontal: 20), 28 | child: snapshot.connectionState == ConnectionState.waiting 29 | ? GridView.builder( 30 | shrinkWrap: true, 31 | physics: NeverScrollableScrollPhysics(), 32 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 33 | crossAxisCount: MediaQuery.of(context).size.width ~/ 400, 34 | childAspectRatio: 400 / 300), 35 | itemCount: 10, 36 | itemBuilder: (context, index) => SkeletonAnimation( 37 | child: Container( 38 | margin: EdgeInsets.symmetric( 39 | horizontal: 10, vertical: 10), 40 | width: 350, 41 | height: 300, 42 | decoration: BoxDecoration( 43 | borderRadius: BorderRadius.circular(10.0), 44 | color: Colors.grey[300]), 45 | ), 46 | )) 47 | : Observer( 48 | builder: (context) => searchController.filteredList.length > 0 49 | ? GridView.builder( 50 | shrinkWrap: true, 51 | physics: NeverScrollableScrollPhysics(), 52 | gridDelegate: 53 | SliverGridDelegateWithFixedCrossAxisCount( 54 | crossAxisCount: 55 | MediaQuery.of(context).size.width ~/ 400, 56 | childAspectRatio: 400 / 300), 57 | itemCount: searchController.filteredList.length, 58 | itemBuilder: (context, index) => PropertyCard( 59 | property: 60 | searchController.filteredList.elementAt(index), 61 | ), 62 | ) 63 | : NotFoundWidget( 64 | size: 300, 65 | ), 66 | ), 67 | ) 68 | ], 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: site_lage 2 | description: Lage Imóveis - CRECI MG 1915 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | google_fonts: 27 | mobx: 28 | flutter_mobx: 29 | get_it: 30 | universal_html: 31 | http: 32 | responsive_builder: 33 | cached_network_image: 34 | google_maps: 35 | url_launcher: 36 | skeleton_text: 37 | photo_view: 38 | flutter_swiper: 39 | firebase_analytics: 40 | 41 | dev_dependencies: 42 | flutter_test: 43 | sdk: flutter 44 | mobx_codegen: 45 | build_runner: 46 | 47 | # For information on the generic Dart part of this file, see the 48 | # following page: https://dart.dev/tools/pub/pubspec 49 | 50 | # The following section is specific to Flutter. 51 | flutter: 52 | # The following line ensures that the Material Icons font is 53 | # included with your application, so that you can use the icons in 54 | # the material Icons class. 55 | uses-material-design: true 56 | 57 | # To add assets to your application, add an assets section, like this: 58 | assets: 59 | - assets/logo/ 60 | - assets/images/ 61 | # - images/a_dot_ham.jpeg 62 | # An image asset can refer to one or more resolution-specific "variants", see 63 | # https://flutter.dev/assets-and-images/#resolution-aware. 64 | # For details regarding adding assets from package dependencies, see 65 | # https://flutter.dev/assets-and-images/#from-packages 66 | # To add custom fonts to your application, add a fonts section here, 67 | # in this "flutter" section. Each entry in this list should have a 68 | # "family" key with the font family name, and a "fonts" key with a 69 | # list giving the asset and other descriptors for the font. For 70 | # example: 71 | # fonts: 72 | # - family: Schyler 73 | # fonts: 74 | # - asset: fonts/Schyler-Regular.ttf 75 | # - asset: fonts/Schyler-Italic.ttf 76 | # style: italic 77 | # - family: Trajan Pro 78 | # fonts: 79 | # - asset: fonts/TrajanPro.ttf 80 | # - asset: fonts/TrajanPro_Bold.ttf 81 | # weight: 700 82 | # 83 | # For details regarding fonts from package dependencies, 84 | # see https://flutter.dev/custom-fonts/#from-packages 85 | -------------------------------------------------------------------------------- /lib/router/config.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/pages/aboutUsPage.dart'; 3 | import 'package:site_lage/pages/contactPage.dart'; 4 | import 'package:site_lage/pages/homePage.dart'; 5 | import 'package:site_lage/pages/properiesPage.dart'; 6 | import 'package:site_lage/pages/propertyPage.dart'; 7 | import 'package:site_lage/pages/simulationPage.dart'; 8 | 9 | class Path { 10 | const Path(this.pattern, this.builder); 11 | 12 | /// A RegEx string for route matching. 13 | final String pattern; 14 | 15 | /// The builder for the associated pattern route. The first argument is the 16 | /// [BuildContext] and the second argument is a RegEx match if it is 17 | /// included inside of the pattern. 18 | final Widget Function(BuildContext, String) builder; 19 | } 20 | 21 | class RouteConfiguration { 22 | /// List of [Path] to for route matching. When a named route is pushed with 23 | /// [Navigator.pushNamed], the route name is matched with the [Path.pattern] 24 | /// in the list below. As soon as there is a match, the associated builder 25 | /// will be returned. This means that the paths higher up in the list will 26 | /// take priority. 27 | static List paths = [ 28 | Path( 29 | r'^' + HomePage.route, 30 | (context, match) => HomePage(), 31 | ), 32 | Path( 33 | r'^' + ContactPage.route, 34 | (context, match) => ContactPage(), 35 | ), 36 | Path( 37 | r'^' + AboutUsPage.route, 38 | (context, match) => AboutUsPage(), 39 | ), 40 | Path( 41 | r'^' + SimulationPage.route, 42 | (context, match) => SimulationPage(), 43 | ), 44 | Path( 45 | r'^' + PropertiesPage.route, 46 | (context, match) => PropertiesPage(), 47 | ), 48 | Path( 49 | r'^/property/([\w-]+)$', 50 | (context, match) => PropertyPage( 51 | id: match, 52 | ), 53 | ) 54 | ]; 55 | 56 | /// The route generator callback used when the app is navigated to a named 57 | /// route. Set it on the [MaterialApp.onGenerateRoute] or 58 | /// [WidgetsApp.onGenerateRoute] to make use of the [paths] for route 59 | /// matching. 60 | static Route onGenerateRoute(RouteSettings settings) { 61 | for (Path path in paths) { 62 | final regExpPattern = RegExp(path.pattern); 63 | if (regExpPattern.hasMatch(settings.name)) { 64 | final firstMatch = regExpPattern.firstMatch(settings.name); 65 | final match = (firstMatch.groupCount == 1) ? firstMatch.group(1) : null; 66 | // return MaterialPageRoute( 67 | // builder: (context) => path.builder(context, match), 68 | // settings: settings, 69 | // ); 70 | return PageRouteBuilder( 71 | settings: settings, 72 | pageBuilder: (context, animation, secondaryAnimation) => 73 | path.builder(context, match), 74 | transitionsBuilder: ( 75 | BuildContext context, 76 | Animation animation, 77 | Animation secondaryAnimation, 78 | Widget child, 79 | ) => 80 | FadeTransition( 81 | opacity: animation, 82 | child: child, 83 | ), 84 | ); 85 | } 86 | } 87 | 88 | // If no match was found, we let [WidgetsApp.onUnknownRoute] handle it. 89 | return null; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/widgets/homePage/dropdownButtons.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:site_lage/components/colors.dart'; 5 | import 'package:site_lage/controllers/search_controller.dart'; 6 | 7 | class DropdownButtons extends StatelessWidget { 8 | final searchController = GetIt.I.get(); 9 | 10 | final double percentSize; 11 | 12 | final double size; 13 | 14 | DropdownButtons({Key key, @required this.size, @required this.percentSize}) 15 | : super(key: key); 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | height: size, 20 | width: MediaQuery.of(context).size.width * percentSize, 21 | decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)), 22 | child: Row( 23 | mainAxisSize: MainAxisSize.max, 24 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 25 | children: [ 26 | Container( 27 | width: MediaQuery.of(context).size.width * (percentSize / 2.1), 28 | padding: EdgeInsets.symmetric(horizontal: 10), 29 | decoration: BoxDecoration( 30 | color: Colors.white, borderRadius: BorderRadius.circular(10)), 31 | child: Observer( 32 | builder: (context) => DropdownButton( 33 | isExpanded: true, 34 | underline: Container(), 35 | value: searchController.propertyType, 36 | style: 37 | TextStyle(fontSize: size * 0.4, color: LageColors.black), 38 | items: List.from( 39 | searchController.propertyTypes.toList().map( 40 | (e) => DropdownMenuItem( 41 | value: e.toString(), 42 | child: Text( 43 | e.toString(), 44 | ), 45 | ), 46 | ), 47 | ), 48 | onChanged: (content) => 49 | searchController.setpropertyType(content), 50 | ), 51 | ), 52 | ), 53 | Container( 54 | width: MediaQuery.of(context).size.width * (percentSize / 2), 55 | padding: EdgeInsets.symmetric(horizontal: 10), 56 | decoration: BoxDecoration( 57 | color: Colors.white, borderRadius: BorderRadius.circular(10)), 58 | child: Observer( 59 | builder: (context) => DropdownButton( 60 | isExpanded: true, 61 | underline: Container(), 62 | value: searchController.method, 63 | style: 64 | TextStyle(fontSize: size * 0.4, color: LageColors.black), 65 | items: List.from( 66 | searchController.methodTypes.toList().map( 67 | (e) => DropdownMenuItem( 68 | value: e.toString(), 69 | child: Text( 70 | e.toString(), 71 | ), 72 | ), 73 | ), 74 | ), 75 | onChanged: (content) => searchController.setMethod(content), 76 | ), 77 | ), 78 | ) 79 | ], 80 | )); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/pages/homePage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get_it/get_it.dart'; 3 | import 'package:responsive_builder/responsive_builder.dart'; 4 | import 'package:site_lage/controllers/api_controller.dart'; 5 | import 'package:site_lage/controllers/search_controller.dart'; 6 | import 'package:site_lage/pages/homePage/homePage_desktop.dart'; 7 | import 'package:site_lage/pages/homePage/homePage_mobile.dart'; 8 | import 'package:site_lage/util/foorter/footer.dart'; 9 | import 'package:site_lage/util/navigationBar/navigationBar.dart'; 10 | import 'package:url_launcher/url_launcher.dart'; 11 | 12 | class HomePage extends StatefulWidget { 13 | static const route = '/home'; 14 | @override 15 | HomePageState createState() => new HomePageState(); 16 | } 17 | 18 | class HomePageState extends State { 19 | final apiController = GetIt.I.get(); 20 | final searchController = GetIt.I.get(); 21 | 22 | @override 23 | void initState() { 24 | if (apiController.properties == null || 25 | apiController.properties.length == 0) 26 | apiController.getAllproperties().whenComplete( 27 | () => searchController.getProperties(apiController.propertiesList)); 28 | super.initState(); 29 | } 30 | 31 | @override 32 | void dispose() { 33 | 34 | super.dispose(); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Scaffold( 40 | body: Container( 41 | height: MediaQuery.of(context).size.height, 42 | child: NotificationListener( 43 | onNotification: (OverscrollIndicatorNotification overScroll) { 44 | overScroll.disallowGlow(); 45 | return false; 46 | }, 47 | child: SingleChildScrollView( 48 | physics: ClampingScrollPhysics(), 49 | child: Column( 50 | mainAxisSize: MainAxisSize.max, 51 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 52 | children: [ 53 | NavigationBar(), 54 | ConstrainedBox( 55 | constraints: BoxConstraints( 56 | minHeight: MediaQuery.of(context).size.height * 0.85), 57 | child: FutureBuilder( 58 | future: apiController.getAllproperties(), 59 | builder: (context, snapshot) => Container( 60 | alignment: Alignment.topCenter, 61 | child: ScreenTypeLayout( 62 | desktop: HomePageDesktop( 63 | snapshot: snapshot, 64 | ), 65 | tablet: HomePageDesktop( 66 | snapshot: snapshot, 67 | ), 68 | mobile: HomePageMobile( 69 | snapshot: snapshot, 70 | ), 71 | )), 72 | )), 73 | Footer() 74 | ], 75 | ), 76 | ), 77 | ), 78 | ), 79 | floatingActionButton: new FloatingActionButton( 80 | onPressed: () => 81 | launch("https://api.whatsapp.com/send?phone=553138222535"), 82 | child: Image.asset( 83 | "assets/images/whatsapp-24.png", 84 | fit: BoxFit.none, 85 | ), 86 | backgroundColor: const Color(0xff25D366), 87 | ), 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/util/navigationBar/navigationBar_desktop.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_analytics/observer.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:site_lage/controllers/email_controller.dart'; 5 | import 'package:site_lage/controllers/search_controller.dart'; 6 | import 'package:site_lage/pages/aboutUsPage.dart'; 7 | import 'package:site_lage/pages/contactPage.dart'; 8 | import 'package:site_lage/pages/homePage.dart'; 9 | import 'package:site_lage/pages/properiesPage.dart'; 10 | import 'package:site_lage/pages/simulationPage.dart'; 11 | import 'package:site_lage/util/navigationBar/navigationBarItem.dart'; 12 | import 'package:site_lage/util/navigationBar/navigationBarLogo.dart'; 13 | 14 | class NavigationBarDesktopAndTablet extends StatelessWidget { 15 | final searchController = GetIt.I.get(); 16 | final emailController = GetIt.I.get(); 17 | final observer = GetIt.I.get(); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return Container( 22 | padding: const EdgeInsets.symmetric(horizontal: 70), 23 | height: 100, 24 | child: Row( 25 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 26 | children: [ 27 | NavigationBarLogo(onPressed: () { 28 | observer.analytics.setCurrentScreen( 29 | screenName: HomePage.route, 30 | ); 31 | searchController.reset(); 32 | Navigator.of(context).pushNamed(HomePage.route); 33 | }), 34 | Row( 35 | mainAxisSize: MainAxisSize.max, 36 | children: [ 37 | NavigationBarItem( 38 | title: "Sobre nós", 39 | onPressed: () { 40 | observer.analytics.setCurrentScreen( 41 | screenName: AboutUsPage.route, 42 | ); 43 | Navigator.of(context).pushNamed(AboutUsPage.route); 44 | }), 45 | SizedBox( 46 | width: 30, 47 | ), 48 | NavigationBarItem( 49 | title: "Contato", 50 | onPressed: () { 51 | observer.analytics.setCurrentScreen( 52 | screenName: ContactPage.route, 53 | ); 54 | Navigator.of(context).pushNamed(ContactPage.route); 55 | }, 56 | ), 57 | SizedBox( 58 | width: 30, 59 | ), 60 | NavigationBarItem( 61 | styled: false, 62 | title: "Simuladores", 63 | onPressed: () { 64 | observer.analytics.setCurrentScreen( 65 | screenName: SimulationPage.route, 66 | ); 67 | Navigator.of(context).pushNamed(SimulationPage.route); 68 | }, 69 | ), 70 | SizedBox( 71 | width: 30, 72 | ), 73 | NavigationBarItem( 74 | title: "Todos os Imóveis", 75 | onPressed: () { 76 | observer.analytics.setCurrentScreen( 77 | screenName: PropertiesPage.route, 78 | ); 79 | searchController.reset(); 80 | Navigator.of(context).pushNamed(PropertiesPage.route); 81 | }, 82 | ), 83 | ], 84 | ) 85 | ], 86 | ), 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lib/pages/properiesPage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get_it/get_it.dart'; 3 | import 'package:responsive_builder/responsive_builder.dart'; 4 | import 'package:site_lage/controllers/api_controller.dart'; 5 | import 'package:site_lage/controllers/search_controller.dart'; 6 | import 'package:site_lage/pages/propertiesPage/propertiesPage_desktop.dart'; 7 | import 'package:site_lage/pages/propertiesPage/propertiesPage_mobile.dart'; 8 | import 'package:site_lage/util/foorter/footer.dart'; 9 | import 'package:site_lage/util/navigationBar/navigationBar.dart'; 10 | import 'package:url_launcher/url_launcher.dart'; 11 | 12 | class PropertiesPage extends StatefulWidget { 13 | static const route = '/properties'; 14 | 15 | @override 16 | PropertiesPageState createState() => PropertiesPageState(); 17 | } 18 | 19 | class PropertiesPageState extends State { 20 | final apiController = GetIt.I.get(); 21 | final searchController = GetIt.I.get(); 22 | 23 | @override 24 | void initState() { 25 | if (apiController.properties == null || 26 | apiController.properties.length == 0) 27 | apiController.getAllproperties().whenComplete( 28 | () => searchController.getProperties(apiController.propertiesList)); 29 | super.initState(); 30 | } 31 | 32 | @override 33 | void dispose() { 34 | super.dispose(); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Scaffold( 40 | body: Container( 41 | height: MediaQuery.of(context).size.height, 42 | child: NotificationListener( 43 | onNotification: (OverscrollIndicatorNotification overScroll) { 44 | overScroll.disallowGlow(); 45 | return false; 46 | }, 47 | child: SingleChildScrollView( 48 | physics: ClampingScrollPhysics(), 49 | child: Column( 50 | mainAxisSize: MainAxisSize.max, 51 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 52 | children: [ 53 | NavigationBar(), 54 | ConstrainedBox( 55 | constraints: BoxConstraints( 56 | minHeight: MediaQuery.of(context).size.height * 0.85), 57 | child: FutureBuilder( 58 | future: apiController.getAllproperties(), 59 | builder: (context, snapshot) => Container( 60 | alignment: Alignment.topCenter, 61 | child: ScreenTypeLayout( 62 | desktop: PropertiesPageDesktop( 63 | snapshot: snapshot, 64 | ), 65 | tablet: PropertiesPageDesktop( 66 | snapshot: snapshot, 67 | ), 68 | mobile: PropertiesPageMobile( 69 | snapshot: snapshot, 70 | ), 71 | ), 72 | ), 73 | ), 74 | ), 75 | Footer() 76 | ], 77 | ), 78 | ), 79 | ), 80 | ), 81 | floatingActionButton: new FloatingActionButton( 82 | onPressed: () => 83 | launch("https://api.whatsapp.com/send?phone=553138222535"), 84 | child: Image.asset( 85 | "assets/images/whatsapp-24.png", 86 | fit: BoxFit.none, 87 | ), 88 | backgroundColor: const Color(0xff25D366), 89 | ), 90 | ); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /lib/widgets/propertyPage/propertyPhotos.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_swiper/flutter_swiper.dart'; 3 | import 'package:photo_view/photo_view.dart'; 4 | import 'package:site_lage/components/colors.dart'; 5 | 6 | class PropertyPhotos extends StatelessWidget { 7 | final controller = SwiperController(); 8 | final List images; 9 | final double percentSize; 10 | 11 | PropertyPhotos({Key key, @required this.images, @required this.percentSize}) 12 | : super(key: key); 13 | @override 14 | Widget build(BuildContext context) { 15 | return Container( 16 | width: MediaQuery.of(context).size.width * percentSize, 17 | child: Column( 18 | mainAxisSize: MainAxisSize.max, 19 | children: [ 20 | Container( 21 | height: 400, 22 | decoration: BoxDecoration( 23 | borderRadius: BorderRadius.circular(10), 24 | // image: DecorationImage( 25 | // fit: BoxFit.fitHeight, 26 | // image: NetworkImage( 27 | // images.elementAt(propertyController.currentIndex), 28 | // ), 29 | // ), 30 | ), 31 | child: Swiper( 32 | pagination: SwiperPagination( 33 | builder: DotSwiperPaginationBuilder( 34 | size: 5, 35 | activeColor: LageColors.yellow, 36 | color: Colors.grey.withOpacity(0.3))), 37 | control: SwiperControl( 38 | color: LageColors.yellow, 39 | ), 40 | controller: controller, 41 | itemCount: images.length, 42 | itemBuilder: (context, index) => PhotoView( 43 | backgroundDecoration: 44 | BoxDecoration(color: Colors.transparent), 45 | minScale: 0.6, 46 | imageProvider: NetworkImage( 47 | images.elementAt(index), 48 | ), 49 | ), 50 | )), 51 | SizedBox( 52 | height: 40, 53 | ), 54 | ListTile( 55 | enabled: false, 56 | subtitle: Text( 57 | "Fotos", 58 | style: TextStyle( 59 | color: LageColors.yellow, 60 | fontWeight: FontWeight.bold, 61 | fontSize: 35), 62 | ), 63 | ), 64 | GridView.builder( 65 | physics: NeverScrollableScrollPhysics(), 66 | shrinkWrap: true, 67 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 68 | crossAxisCount: 3, childAspectRatio: 400 / 300), 69 | itemCount: images.length, 70 | itemBuilder: (context, index) => InkWell( 71 | child: Container( 72 | padding: EdgeInsets.all(10), 73 | margin: EdgeInsets.all(10), 74 | decoration: BoxDecoration( 75 | borderRadius: BorderRadius.circular(10), 76 | image: DecorationImage( 77 | fit: BoxFit.fill, 78 | image: NetworkImage(images.elementAt(index)))), 79 | ), 80 | onTap: () => controller.move(index, animation: true), 81 | focusColor: Colors.transparent, 82 | hoverColor: Colors.transparent, 83 | highlightColor: Colors.transparent, 84 | splashColor: Colors.transparent, 85 | )) 86 | ], 87 | ), 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/util/foorter/footer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:responsive_builder/responsive_builder.dart'; 3 | import 'package:site_lage/components/colors.dart'; 4 | import 'footerInfo.dart'; 5 | import 'footerLogo.dart'; 6 | 7 | // class Footer extends StatelessWidget { 8 | // @override 9 | // Widget build(BuildContext context) { 10 | // return Container( 11 | // padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20), 12 | // alignment: Alignment.topCenter, 13 | // color: LageColors.yellow, 14 | // child: ScreenTypeLayout( 15 | // desktop: FooterDesktopAndTablet(), 16 | // mobile: FooterDesktopAndTablet(), 17 | // ), 18 | // ); 19 | // } 20 | // } 21 | 22 | class Footer extends StatelessWidget { 23 | @override 24 | Widget build(BuildContext context) { 25 | return ResponsiveBuilder(builder: (context, sizingInfo) { 26 | double textSize = 27 | sizingInfo.deviceScreenType == DeviceScreenType.mobile ? 8 : 10; 28 | double iconSize = 29 | sizingInfo.deviceScreenType == DeviceScreenType.mobile ? 16 : 20; 30 | double imageSize = 31 | sizingInfo.deviceScreenType == DeviceScreenType.mobile ? 60 : 120; 32 | double spacerSize = 33 | sizingInfo.deviceScreenType == DeviceScreenType.mobile ? 25 : 50; 34 | double infoSize = 35 | sizingInfo.deviceScreenType == DeviceScreenType.mobile ? 140 : 200; 36 | return Container( 37 | padding: EdgeInsets.symmetric(horizontal: spacerSize, vertical: 20), 38 | alignment: Alignment.topCenter, 39 | color: LageColors.yellow, 40 | child: Container( 41 | height: 80, 42 | child: Row( 43 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 44 | children: [ 45 | // FooterItem( 46 | // title: "Lage Imóveis", 47 | // subtitle: "Filiada Rede Ipatinga Imóveis", 48 | // ), 49 | FooterLogo( 50 | size: imageSize, 51 | ), 52 | Row( 53 | mainAxisSize: MainAxisSize.min, 54 | children: [ 55 | Container( 56 | width: 2, 57 | color: Colors.black, 58 | margin: const EdgeInsets.only(right: 5), 59 | ), 60 | Container( 61 | width: infoSize, 62 | child: Column( 63 | mainAxisSize: MainAxisSize.max, 64 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 65 | crossAxisAlignment: CrossAxisAlignment.start, 66 | children: [ 67 | FooterInfo( 68 | icon: Icons.alternate_email, 69 | title: "contato@lageimoveis.com.br", 70 | textSize: textSize, 71 | iconSize: iconSize, 72 | ), 73 | FooterInfo( 74 | icon: Icons.phone, 75 | title: "(31) 3822-2535", 76 | textSize: textSize, 77 | iconSize: iconSize, 78 | ), 79 | FooterInfo( 80 | icon: Icons.business, 81 | title: 82 | "Rua Diamantina, 272 - Loja 02 Bairro Centro - Ipatinga/MG", 83 | textSize: textSize, 84 | iconSize: iconSize, 85 | ), 86 | ], 87 | )) 88 | ], 89 | ) 90 | ], 91 | ), 92 | )); 93 | }); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /lib/pages/propertyPage/propertyPage_mobile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:site_lage/components/colors.dart'; 4 | import 'package:site_lage/controllers/email_controller.dart'; 5 | import 'package:site_lage/models/property.dart'; 6 | import 'package:site_lage/widgets/propertyPage/propertyDetails.dart'; 7 | import 'package:site_lage/widgets/propertyPage/propertyPhotos.dart'; 8 | import 'package:url_launcher/url_launcher.dart'; 9 | 10 | class PropertyPageMobile extends StatelessWidget { 11 | final Property property; 12 | 13 | PropertyPageMobile({Key key, this.property}) : super(key: key); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | String filtered = "Olá, estou interessado(a) em " + 18 | property.title + 19 | " situado(a) no endereço " + 20 | property.address; 21 | return ConstrainedBox( 22 | constraints: BoxConstraints( 23 | minHeight: MediaQuery.of(context).size.height * 0.85), 24 | child: Container( 25 | margin: EdgeInsets.symmetric(horizontal: 20), 26 | padding: EdgeInsets.symmetric(horizontal: 20), 27 | child: Column( 28 | mainAxisSize: MainAxisSize.max, 29 | children: [ 30 | PropertyDetails( 31 | property: property, 32 | percentSize: 1, 33 | ), 34 | SizedBox( 35 | height: 30, 36 | ), 37 | PropertyPhotos( 38 | images: property.images, 39 | percentSize: 1, 40 | ), 41 | Container( 42 | width: MediaQuery.of(context).size.width, 43 | height: 1, 44 | color: Colors.grey, 45 | margin: EdgeInsets.symmetric(vertical: 15), 46 | ), 47 | InkWell( 48 | child: Container( 49 | height: 50, 50 | width: MediaQuery.of(context).size.width, 51 | padding: EdgeInsets.only(left: 10), 52 | margin: EdgeInsets.symmetric(horizontal: 20), 53 | decoration: BoxDecoration( 54 | color: LageColors.yellow, 55 | borderRadius: BorderRadius.circular(10)), 56 | child: Center( 57 | child: Text( 58 | "EMAIL", 59 | style: TextStyle( 60 | color: Colors.black, 61 | fontWeight: FontWeight.bold, 62 | fontSize: 20), 63 | ), 64 | ), 65 | ), 66 | onTap: () => launch( 67 | "mailto:lageimoveis@uol.com.br?cc=eustaquio.lage@uol.com.br&subject=INTERESSE%20POR%20IM%C3%93VEL&body=" + 68 | filtered.replaceAll(" ", "%20")), 69 | ), 70 | SizedBox( 71 | height: 10, 72 | ), 73 | InkWell( 74 | child: Container( 75 | height: 50, 76 | width: MediaQuery.of(context).size.width, 77 | padding: EdgeInsets.only(left: 10), 78 | margin: EdgeInsets.symmetric(horizontal: 20), 79 | decoration: BoxDecoration( 80 | color: const Color(0xff25D366), 81 | borderRadius: BorderRadius.circular(10)), 82 | child: Center( 83 | child: Text( 84 | "WHATSAPP", 85 | style: TextStyle( 86 | color: Colors.white, 87 | fontWeight: FontWeight.bold, 88 | fontSize: 20), 89 | ), 90 | ), 91 | ), 92 | onTap: () => launch( 93 | "https://api.whatsapp.com/send?phone=553138222535&text=" + 94 | filtered.replaceAll(" ", "%20")), 95 | ), 96 | SizedBox( 97 | height: 50, 98 | ) 99 | ], 100 | ), 101 | )); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 18 | 19 | 20 | 21 | 25 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Lage Imóveis 40 | 41 | 42 | 76 | 77 | 78 | 79 | 80 | 81 | 83 | 84 | 85 | 101 | 102 |
103 | 104 |
105 | 106 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /lib/util/navigationBar/navigationBar_mobile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/components/colors.dart'; 3 | import 'package:site_lage/pages/aboutUsPage.dart'; 4 | import 'package:site_lage/pages/contactPage.dart'; 5 | import 'package:site_lage/pages/homePage.dart'; 6 | import 'package:site_lage/pages/properiesPage.dart'; 7 | import 'package:site_lage/pages/simulationPage.dart'; 8 | import 'package:site_lage/util/navigationBar/navigationBarLogo.dart'; 9 | 10 | class NavigationBarMobile extends StatelessWidget { 11 | final pages = [ 12 | HomePage.route, 13 | AboutUsPage.route, 14 | ContactPage.route, 15 | SimulationPage.route, 16 | PropertiesPage.route 17 | ]; 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return Container( 22 | padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 10), 23 | height: 100, 24 | child: Row( 25 | mainAxisSize: MainAxisSize.max, 26 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 27 | children: [ 28 | NavigationBarLogo( 29 | onPressed: () => Navigator.of(context).pushNamed(HomePage.route)), 30 | DropdownButton( 31 | icon: Icon(Icons.menu), 32 | underline: SizedBox(), 33 | items: [ 34 | new DropdownMenuItem( 35 | value: 0, 36 | child: Row( 37 | mainAxisSize: MainAxisSize.min, 38 | children: [ 39 | Icon( 40 | Icons.home, 41 | color: LageColors.yellow, 42 | ), 43 | SizedBox( 44 | width: 10, 45 | ), 46 | Text('Home') 47 | ], 48 | ), 49 | ), 50 | new DropdownMenuItem( 51 | value: 1, 52 | child: Row( 53 | mainAxisSize: MainAxisSize.min, 54 | children: [ 55 | Icon( 56 | Icons.info, 57 | color: LageColors.yellow, 58 | ), 59 | SizedBox( 60 | width: 10, 61 | ), 62 | Text('Sobre nós') 63 | ], 64 | ), 65 | ), 66 | new DropdownMenuItem( 67 | value: 2, 68 | child: Row( 69 | mainAxisSize: MainAxisSize.min, 70 | children: [ 71 | Icon( 72 | Icons.alternate_email, 73 | color: LageColors.yellow, 74 | ), 75 | SizedBox( 76 | width: 10, 77 | ), 78 | Text('Contato') 79 | ], 80 | ), 81 | ), 82 | new DropdownMenuItem( 83 | value: 3, 84 | child: Row( 85 | mainAxisSize: MainAxisSize.min, 86 | children: [ 87 | Icon( 88 | Icons.insert_chart, 89 | color: LageColors.yellow, 90 | ), 91 | SizedBox( 92 | width: 10, 93 | ), 94 | Text('Simuladores') 95 | ], 96 | ), 97 | ), 98 | new DropdownMenuItem( 99 | value: 4, 100 | child: Row( 101 | mainAxisSize: MainAxisSize.min, 102 | children: [ 103 | Icon( 104 | Icons.location_city, 105 | color: LageColors.yellow, 106 | ), 107 | SizedBox( 108 | width: 10, 109 | ), 110 | Text('Todos imóveis') 111 | ], 112 | ), 113 | ) 114 | ], 115 | onChanged: (index) => 116 | Navigator.of(context).pushNamed(pages[index])) 117 | //IconButton(icon: Icon(Icons.menu), onPressed: null) 118 | ], 119 | ), 120 | ); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/pages/propertyPage.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_analytics/observer.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get_it/get_it.dart'; 4 | import 'package:responsive_builder/responsive_builder.dart'; 5 | import 'package:site_lage/components/colors.dart'; 6 | import 'package:site_lage/pages/propertyPage/propertyPage_desktop.dart'; 7 | import 'package:site_lage/pages/propertyPage/propertyPage_mobile.dart'; 8 | import 'package:site_lage/util/foorter/footer.dart'; 9 | import 'package:site_lage/util/navigationBar/navigationBar.dart'; 10 | import 'package:site_lage/controllers/api_controller.dart'; 11 | import 'package:site_lage/widgets/propertiesPage/notFoundWidget.dart'; 12 | 13 | class PropertyPage extends StatefulWidget { 14 | static const route = '/property'; 15 | final String id; 16 | PropertyPage({Key key, this.id}) : super(key: key); 17 | 18 | @override 19 | PropertyPageState createState() => PropertyPageState(id); 20 | } 21 | 22 | class PropertyPageState extends State { 23 | final apiController = GetIt.I.get(); 24 | final observer = GetIt.I.get(); 25 | final String id; 26 | 27 | PropertyPageState(this.id); 28 | 29 | @override 30 | void initState() { 31 | observer.analytics.setCurrentScreen( 32 | screenName: '/property/' + id, 33 | ); 34 | 35 | apiController.getpropertyDetail(id); 36 | super.initState(); 37 | } 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | return Scaffold( 42 | body: Container( 43 | height: MediaQuery.of(context).size.height, 44 | child: NotificationListener( 45 | onNotification: (OverscrollIndicatorNotification overScroll) { 46 | overScroll.disallowGlow(); 47 | return false; 48 | }, 49 | child: SingleChildScrollView( 50 | physics: ClampingScrollPhysics(), 51 | child: Column( 52 | mainAxisSize: MainAxisSize.max, 53 | children: [ 54 | NavigationBar(), 55 | ConstrainedBox( 56 | constraints: BoxConstraints( 57 | minHeight: MediaQuery.of(context).size.height * 0.85), 58 | child: FutureBuilder( 59 | future: apiController.getpropertyDetail(widget.id), 60 | builder: (context, snapshot) => snapshot.connectionState == 61 | ConnectionState.waiting 62 | ? Container( 63 | color: Colors.transparent, 64 | child: Column( 65 | mainAxisAlignment: MainAxisAlignment.center, 66 | children: [ 67 | CircularProgressIndicator( 68 | valueColor: 69 | AlwaysStoppedAnimation(LageColors.yellow), 70 | ), 71 | SizedBox( 72 | height: 20, 73 | ), 74 | Text('Aguarde, por favor') 75 | ], 76 | )) 77 | : !snapshot.hasData 78 | ? Container( 79 | color: Colors.transparent, 80 | child: NotFoundWidget( 81 | size: MediaQuery.of(context).size.width * 82 | 0.4)) 83 | : Container( 84 | alignment: Alignment.topCenter, 85 | child: ScreenTypeLayout( 86 | desktop: PropertyPageDesktop( 87 | property: snapshot.data, 88 | ), 89 | tablet: PropertyPageDesktop( 90 | property: snapshot.data, 91 | ), 92 | mobile: PropertyPageMobile( 93 | property: snapshot.data, 94 | ), 95 | ), 96 | ), 97 | ), 98 | ), 99 | Footer() 100 | ], 101 | ), 102 | ), 103 | ), 104 | ), 105 | ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /lib/widgets/propertyPage/propertyDetails.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:site_lage/components/colors.dart'; 3 | import 'package:site_lage/models/property.dart'; 4 | import 'package:site_lage/widgets/propertyPage/propertyTitle.dart'; 5 | 6 | class PropertyDetails extends StatelessWidget { 7 | final Property property; 8 | final double percentSize; 9 | 10 | PropertyDetails( 11 | {Key key, @required this.property, @required this.percentSize}) 12 | : super(key: key); 13 | 14 | String getPrice() { 15 | String price = property.price.toString(); 16 | String aux = ""; 17 | 18 | for (int i = 0; i < price.length; i++) { 19 | aux = price[price.length - i - 1] + aux; 20 | if ((i + 1) % 3 == 0 && (i + 1) < price.length) aux = "." + aux; 21 | } 22 | price = aux; 23 | price += ",00"; 24 | return price; 25 | } 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return Container( 30 | width: MediaQuery.of(context).size.width * percentSize, 31 | child: Column( 32 | mainAxisSize: MainAxisSize.max, 33 | children: [ 34 | ListTile( 35 | enabled: false, 36 | title: Text( 37 | property.title, 38 | style: TextStyle( 39 | color: LageColors.black, 40 | fontWeight: FontWeight.bold, 41 | fontSize: 35), 42 | ), 43 | subtitle: Text( 44 | property.description, 45 | style: TextStyle( 46 | color: LageColors.yellow, 47 | fontWeight: FontWeight.bold, 48 | fontSize: 15), 49 | ), 50 | ), 51 | Container( 52 | margin: EdgeInsets.symmetric(vertical: 10), 53 | height: 1, 54 | color: Colors.grey, 55 | ), 56 | PropertyTitle( 57 | icon: Icons.pin_drop, 58 | title: property.address, 59 | subtitle: "Endereço", 60 | ), 61 | property.qtdRooms == null 62 | ? Container() 63 | : PropertyTitle( 64 | icon: Icons.hotel, 65 | title: property.qtdRooms.toString(), 66 | subtitle: "Quartos", 67 | ), 68 | property.qtdBathrooms == null 69 | ? Container() 70 | : PropertyTitle( 71 | icon: Icons.hot_tub, 72 | title: property.qtdBathrooms.toString(), 73 | subtitle: "Banheiros", 74 | ), 75 | property.qtdGarage == null 76 | ? Container() 77 | : PropertyTitle( 78 | icon: Icons.directions_car, 79 | title: property.qtdGarage.toString(), 80 | subtitle: "Vagas de garagem", 81 | ), 82 | property.haveSuit == null 83 | ? Container() 84 | : PropertyTitle( 85 | icon: property.haveSuit ? Icons.check_circle : Icons.cancel, 86 | title: 87 | property.haveSuit ? "Possui Suíte" : "Não Possui Suíte", 88 | subtitle: "", 89 | ), 90 | property.frontDimensions == null 91 | ? Container() 92 | : PropertyTitle( 93 | icon: Icons.photo_size_select_small, 94 | title: property.frontDimensions.toString() + "m", 95 | subtitle: "Metros de frente", 96 | ), 97 | property.sideDimensions == null 98 | ? Container() 99 | : PropertyTitle( 100 | icon: Icons.photo_size_select_small, 101 | title: property.sideDimensions.toString() + "m", 102 | subtitle: "Metros de lado", 103 | ), 104 | property.totalArea == null 105 | ? Container() 106 | : PropertyTitle( 107 | icon: Icons.border_outer, 108 | title: property.totalArea.toString() + "m²", 109 | subtitle: "Área Total", 110 | ), 111 | PropertyTitle( 112 | icon: Icons.swap_horiz, 113 | title: property.forSale ? "Venda" : "Locação", 114 | subtitle: "Transação", 115 | ), 116 | property.price != null && property.price != 0 117 | ? PropertyTitle( 118 | icon: Icons.monetization_on, 119 | title: "R\$" + getPrice(), 120 | subtitle: "Preço", 121 | ) 122 | : Container(), 123 | Container( 124 | height: 1, 125 | color: Colors.grey, 126 | ), 127 | ], 128 | ), 129 | ); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /lib/controllers/search_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:mobx/mobx.dart'; 2 | import 'package:site_lage/models/property.dart'; 3 | part 'search_controller.g.dart'; 4 | 5 | class SearchController = _SearchControllerBase with _$SearchController; 6 | 7 | abstract class _SearchControllerBase with Store { 8 | @observable 9 | String text = ""; 10 | 11 | @observable 12 | String propertyType = "Todos"; 13 | 14 | @observable 15 | ObservableList propertyTypes = [ 16 | "Todos", 17 | "Área", 18 | "Apartamento", 19 | "Casa", 20 | "Casa Geminada", 21 | "Chácara", 22 | "Cobertura", 23 | "Fazenda", 24 | "Galpão", 25 | "Loja", 26 | "Lote", 27 | "Prédio", 28 | "Quitinete", 29 | "Sala", 30 | "Sítio", 31 | "Terreno" 32 | ].asObservable(); 33 | 34 | @computed 35 | get getPropertyTypes => propertyTypes.toList(); 36 | 37 | @observable 38 | String method = "Aluguel e Venda"; 39 | 40 | @observable 41 | ObservableList methodTypes = 42 | ["Aluguel e Venda", "Aluguel", "Venda"].asObservable(); 43 | 44 | @observable 45 | ObservableList properties; 46 | 47 | @action 48 | void getProperties(List l) { 49 | properties = new List.from(l).asObservable(); 50 | } 51 | 52 | @action 53 | void setText(String newText) { 54 | text = newText; 55 | } 56 | 57 | @action 58 | void setpropertyType(String newPropertyType) { 59 | propertyType = newPropertyType; 60 | } 61 | 62 | @action 63 | void setMethod(String newMethod) { 64 | method = newMethod; 65 | } 66 | 67 | @action 68 | void showData() { 69 | print(text + "\t" + propertyType + "\t" + method); 70 | } 71 | 72 | @action 73 | void reset() { 74 | text = ""; 75 | propertyType = "Todos"; 76 | method = "Aluguel e Venda"; 77 | } 78 | 79 | String normalize(String currentString) { 80 | String possible = "áàãâéêíóôõúüñçÁÀÃÂÉÊÍÓÔÕÚÜÑÇ"; 81 | String result = "aaaaeeiooouuncAAAAEEIOOOUUNC"; 82 | 83 | String newValue = ""; 84 | for (int i = 0; i < currentString.length; i++) { 85 | if (possible.contains(currentString[i])) { 86 | newValue += result[possible.indexOf(currentString[i])]; 87 | } else { 88 | newValue += currentString[i]; 89 | } 90 | } 91 | return newValue; 92 | } 93 | 94 | @computed 95 | get filteredList { 96 | if (text.isEmpty) { 97 | if (propertyType == "Todos") { 98 | if (method == "Aluguel e Venda") 99 | return properties; 100 | else if (method == "Aluguel") 101 | return properties.where((element) => element.forRent); 102 | else 103 | return properties.where((element) => element.forSale); 104 | } else { 105 | if (method == "Aluguel e Venda") 106 | return properties.where((element) => element.type == propertyType); 107 | else if (method == "Aluguel") 108 | return properties.where( 109 | (element) => element.type == propertyType && element.forRent); 110 | else 111 | return properties.where( 112 | (element) => element.type == propertyType && element.forSale); 113 | } 114 | } else { 115 | if (propertyType == "Todos") { 116 | if (method == "Aluguel e Venda") 117 | return properties.where((element) => normalize(element.address) 118 | .toLowerCase() 119 | .contains(text.toLowerCase())); 120 | else if (method == "Aluguel") 121 | return properties.where((element) => 122 | normalize(element.address) 123 | .toLowerCase() 124 | .contains(text.toLowerCase()) && 125 | element.forRent); 126 | else 127 | return properties.where((element) => 128 | normalize(element.address) 129 | .toLowerCase() 130 | .contains(text.toLowerCase()) && 131 | element.forSale); 132 | } else { 133 | if (method == "Aluguel e Venda") 134 | return properties.where((element) => 135 | normalize(element.address) 136 | .toLowerCase() 137 | .contains(text.toLowerCase()) && 138 | element.type == propertyType); 139 | else if (method == "Aluguel") 140 | return properties.where((element) => 141 | normalize(element.address) 142 | .toLowerCase() 143 | .contains(text.toLowerCase()) && 144 | element.type == propertyType && 145 | element.forRent); 146 | else 147 | return properties.where((element) => 148 | normalize(element.address) 149 | .toLowerCase() 150 | .contains(text.toLowerCase()) && 151 | element.type == propertyType && 152 | element.forSale); 153 | } 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /lib/controllers/email_controller.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'email_controller.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic 10 | 11 | mixin _$EmailController on _EmailControllerBase, Store { 12 | Computed _$canContinueComputed; 13 | 14 | @override 15 | bool get canContinue => 16 | (_$canContinueComputed ??= Computed(() => super.canContinue)).value; 17 | 18 | final _$nameAtom = Atom(name: '_EmailControllerBase.name'); 19 | 20 | @override 21 | String get name { 22 | _$nameAtom.context.enforceReadPolicy(_$nameAtom); 23 | _$nameAtom.reportObserved(); 24 | return super.name; 25 | } 26 | 27 | @override 28 | set name(String value) { 29 | _$nameAtom.context.conditionallyRunInAction(() { 30 | super.name = value; 31 | _$nameAtom.reportChanged(); 32 | }, _$nameAtom, name: '${_$nameAtom.name}_set'); 33 | } 34 | 35 | final _$subjectAtom = Atom(name: '_EmailControllerBase.subject'); 36 | 37 | @override 38 | String get subject { 39 | _$subjectAtom.context.enforceReadPolicy(_$subjectAtom); 40 | _$subjectAtom.reportObserved(); 41 | return super.subject; 42 | } 43 | 44 | @override 45 | set subject(String value) { 46 | _$subjectAtom.context.conditionallyRunInAction(() { 47 | super.subject = value; 48 | _$subjectAtom.reportChanged(); 49 | }, _$subjectAtom, name: '${_$subjectAtom.name}_set'); 50 | } 51 | 52 | final _$textAtom = Atom(name: '_EmailControllerBase.text'); 53 | 54 | @override 55 | String get text { 56 | _$textAtom.context.enforceReadPolicy(_$textAtom); 57 | _$textAtom.reportObserved(); 58 | return super.text; 59 | } 60 | 61 | @override 62 | set text(String value) { 63 | _$textAtom.context.conditionallyRunInAction(() { 64 | super.text = value; 65 | _$textAtom.reportChanged(); 66 | }, _$textAtom, name: '${_$textAtom.name}_set'); 67 | } 68 | 69 | final _$submitAsyncAction = AsyncAction('submit'); 70 | 71 | @override 72 | Future submit() { 73 | return _$submitAsyncAction.run(() => super.submit()); 74 | } 75 | 76 | final _$_EmailControllerBaseActionController = 77 | ActionController(name: '_EmailControllerBase'); 78 | 79 | @override 80 | void setName(String val) { 81 | final _$actionInfo = _$_EmailControllerBaseActionController.startAction(); 82 | try { 83 | return super.setName(val); 84 | } finally { 85 | _$_EmailControllerBaseActionController.endAction(_$actionInfo); 86 | } 87 | } 88 | 89 | @override 90 | void setSubject(String val) { 91 | final _$actionInfo = _$_EmailControllerBaseActionController.startAction(); 92 | try { 93 | return super.setSubject(val); 94 | } finally { 95 | _$_EmailControllerBaseActionController.endAction(_$actionInfo); 96 | } 97 | } 98 | 99 | @override 100 | void setText(String val) { 101 | final _$actionInfo = _$_EmailControllerBaseActionController.startAction(); 102 | try { 103 | return super.setText(val); 104 | } finally { 105 | _$_EmailControllerBaseActionController.endAction(_$actionInfo); 106 | } 107 | } 108 | 109 | @override 110 | void validateName(String value) { 111 | final _$actionInfo = _$_EmailControllerBaseActionController.startAction(); 112 | try { 113 | return super.validateName(value); 114 | } finally { 115 | _$_EmailControllerBaseActionController.endAction(_$actionInfo); 116 | } 117 | } 118 | 119 | @override 120 | void validateSubject(String value) { 121 | final _$actionInfo = _$_EmailControllerBaseActionController.startAction(); 122 | try { 123 | return super.validateSubject(value); 124 | } finally { 125 | _$_EmailControllerBaseActionController.endAction(_$actionInfo); 126 | } 127 | } 128 | 129 | @override 130 | void validateText(String value) { 131 | final _$actionInfo = _$_EmailControllerBaseActionController.startAction(); 132 | try { 133 | return super.validateText(value); 134 | } finally { 135 | _$_EmailControllerBaseActionController.endAction(_$actionInfo); 136 | } 137 | } 138 | } 139 | 140 | mixin _$FormErrorState on _FormErrorStateBase, Store { 141 | Computed _$hasErrorsComputed; 142 | 143 | @override 144 | bool get hasErrors => 145 | (_$hasErrorsComputed ??= Computed(() => super.hasErrors)).value; 146 | 147 | final _$nameAtom = Atom(name: '_FormErrorStateBase.name'); 148 | 149 | @override 150 | String get name { 151 | _$nameAtom.context.enforceReadPolicy(_$nameAtom); 152 | _$nameAtom.reportObserved(); 153 | return super.name; 154 | } 155 | 156 | @override 157 | set name(String value) { 158 | _$nameAtom.context.conditionallyRunInAction(() { 159 | super.name = value; 160 | _$nameAtom.reportChanged(); 161 | }, _$nameAtom, name: '${_$nameAtom.name}_set'); 162 | } 163 | 164 | final _$subjectAtom = Atom(name: '_FormErrorStateBase.subject'); 165 | 166 | @override 167 | String get subject { 168 | _$subjectAtom.context.enforceReadPolicy(_$subjectAtom); 169 | _$subjectAtom.reportObserved(); 170 | return super.subject; 171 | } 172 | 173 | @override 174 | set subject(String value) { 175 | _$subjectAtom.context.conditionallyRunInAction(() { 176 | super.subject = value; 177 | _$subjectAtom.reportChanged(); 178 | }, _$subjectAtom, name: '${_$subjectAtom.name}_set'); 179 | } 180 | 181 | final _$textAtom = Atom(name: '_FormErrorStateBase.text'); 182 | 183 | @override 184 | String get text { 185 | _$textAtom.context.enforceReadPolicy(_$textAtom); 186 | _$textAtom.reportObserved(); 187 | return super.text; 188 | } 189 | 190 | @override 191 | set text(String value) { 192 | _$textAtom.context.conditionallyRunInAction(() { 193 | super.text = value; 194 | _$textAtom.reportChanged(); 195 | }, _$textAtom, name: '${_$textAtom.name}_set'); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /lib/controllers/search_controller.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'search_controller.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic 10 | 11 | mixin _$SearchController on _SearchControllerBase, Store { 12 | Computed _$getPropertyTypesComputed; 13 | 14 | @override 15 | dynamic get getPropertyTypes => (_$getPropertyTypesComputed ??= 16 | Computed(() => super.getPropertyTypes)) 17 | .value; 18 | Computed _$filteredListComputed; 19 | 20 | @override 21 | dynamic get filteredList => 22 | (_$filteredListComputed ??= Computed(() => super.filteredList)) 23 | .value; 24 | 25 | final _$textAtom = Atom(name: '_SearchControllerBase.text'); 26 | 27 | @override 28 | String get text { 29 | _$textAtom.context.enforceReadPolicy(_$textAtom); 30 | _$textAtom.reportObserved(); 31 | return super.text; 32 | } 33 | 34 | @override 35 | set text(String value) { 36 | _$textAtom.context.conditionallyRunInAction(() { 37 | super.text = value; 38 | _$textAtom.reportChanged(); 39 | }, _$textAtom, name: '${_$textAtom.name}_set'); 40 | } 41 | 42 | final _$propertyTypeAtom = Atom(name: '_SearchControllerBase.propertyType'); 43 | 44 | @override 45 | String get propertyType { 46 | _$propertyTypeAtom.context.enforceReadPolicy(_$propertyTypeAtom); 47 | _$propertyTypeAtom.reportObserved(); 48 | return super.propertyType; 49 | } 50 | 51 | @override 52 | set propertyType(String value) { 53 | _$propertyTypeAtom.context.conditionallyRunInAction(() { 54 | super.propertyType = value; 55 | _$propertyTypeAtom.reportChanged(); 56 | }, _$propertyTypeAtom, name: '${_$propertyTypeAtom.name}_set'); 57 | } 58 | 59 | final _$propertyTypesAtom = Atom(name: '_SearchControllerBase.propertyTypes'); 60 | 61 | @override 62 | ObservableList get propertyTypes { 63 | _$propertyTypesAtom.context.enforceReadPolicy(_$propertyTypesAtom); 64 | _$propertyTypesAtom.reportObserved(); 65 | return super.propertyTypes; 66 | } 67 | 68 | @override 69 | set propertyTypes(ObservableList value) { 70 | _$propertyTypesAtom.context.conditionallyRunInAction(() { 71 | super.propertyTypes = value; 72 | _$propertyTypesAtom.reportChanged(); 73 | }, _$propertyTypesAtom, name: '${_$propertyTypesAtom.name}_set'); 74 | } 75 | 76 | final _$methodAtom = Atom(name: '_SearchControllerBase.method'); 77 | 78 | @override 79 | String get method { 80 | _$methodAtom.context.enforceReadPolicy(_$methodAtom); 81 | _$methodAtom.reportObserved(); 82 | return super.method; 83 | } 84 | 85 | @override 86 | set method(String value) { 87 | _$methodAtom.context.conditionallyRunInAction(() { 88 | super.method = value; 89 | _$methodAtom.reportChanged(); 90 | }, _$methodAtom, name: '${_$methodAtom.name}_set'); 91 | } 92 | 93 | final _$methodTypesAtom = Atom(name: '_SearchControllerBase.methodTypes'); 94 | 95 | @override 96 | ObservableList get methodTypes { 97 | _$methodTypesAtom.context.enforceReadPolicy(_$methodTypesAtom); 98 | _$methodTypesAtom.reportObserved(); 99 | return super.methodTypes; 100 | } 101 | 102 | @override 103 | set methodTypes(ObservableList value) { 104 | _$methodTypesAtom.context.conditionallyRunInAction(() { 105 | super.methodTypes = value; 106 | _$methodTypesAtom.reportChanged(); 107 | }, _$methodTypesAtom, name: '${_$methodTypesAtom.name}_set'); 108 | } 109 | 110 | final _$propertiesAtom = Atom(name: '_SearchControllerBase.properties'); 111 | 112 | @override 113 | ObservableList get properties { 114 | _$propertiesAtom.context.enforceReadPolicy(_$propertiesAtom); 115 | _$propertiesAtom.reportObserved(); 116 | return super.properties; 117 | } 118 | 119 | @override 120 | set properties(ObservableList value) { 121 | _$propertiesAtom.context.conditionallyRunInAction(() { 122 | super.properties = value; 123 | _$propertiesAtom.reportChanged(); 124 | }, _$propertiesAtom, name: '${_$propertiesAtom.name}_set'); 125 | } 126 | 127 | final _$_SearchControllerBaseActionController = 128 | ActionController(name: '_SearchControllerBase'); 129 | 130 | @override 131 | void getProperties(dynamic l) { 132 | final _$actionInfo = _$_SearchControllerBaseActionController.startAction(); 133 | try { 134 | return super.getProperties(l); 135 | } finally { 136 | _$_SearchControllerBaseActionController.endAction(_$actionInfo); 137 | } 138 | } 139 | 140 | @override 141 | void setText(String newText) { 142 | final _$actionInfo = _$_SearchControllerBaseActionController.startAction(); 143 | try { 144 | return super.setText(newText); 145 | } finally { 146 | _$_SearchControllerBaseActionController.endAction(_$actionInfo); 147 | } 148 | } 149 | 150 | @override 151 | void setpropertyType(String newPropertyType) { 152 | final _$actionInfo = _$_SearchControllerBaseActionController.startAction(); 153 | try { 154 | return super.setpropertyType(newPropertyType); 155 | } finally { 156 | _$_SearchControllerBaseActionController.endAction(_$actionInfo); 157 | } 158 | } 159 | 160 | @override 161 | void setMethod(String newMethod) { 162 | final _$actionInfo = _$_SearchControllerBaseActionController.startAction(); 163 | try { 164 | return super.setMethod(newMethod); 165 | } finally { 166 | _$_SearchControllerBaseActionController.endAction(_$actionInfo); 167 | } 168 | } 169 | 170 | @override 171 | void showData() { 172 | final _$actionInfo = _$_SearchControllerBaseActionController.startAction(); 173 | try { 174 | return super.showData(); 175 | } finally { 176 | _$_SearchControllerBaseActionController.endAction(_$actionInfo); 177 | } 178 | } 179 | 180 | @override 181 | void reset() { 182 | final _$actionInfo = _$_SearchControllerBaseActionController.startAction(); 183 | try { 184 | return super.reset(); 185 | } finally { 186 | _$_SearchControllerBaseActionController.endAction(_$actionInfo); 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /lib/widgets/propertyPage/propertyContact.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mobx/flutter_mobx.dart'; 3 | import 'package:site_lage/components/colors.dart'; 4 | import 'package:site_lage/controllers/email_controller.dart'; 5 | import 'package:url_launcher/url_launcher.dart'; 6 | 7 | class PropertyContact extends StatelessWidget { 8 | final double percentSize; 9 | final String initText; 10 | final emailController = EmailController(); 11 | 12 | PropertyContact({Key key, @required this.percentSize, this.initText}) 13 | : super(key: key); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | emailController.setText(initText); 18 | return Container( 19 | width: MediaQuery.of(context).size.width * percentSize, 20 | child: Column( 21 | children: [ 22 | ListTile( 23 | enabled: false, 24 | subtitle: Text( 25 | "Contato", 26 | style: TextStyle( 27 | color: LageColors.yellow, 28 | fontWeight: FontWeight.bold, 29 | fontSize: 20), 30 | ), 31 | ), 32 | Container( 33 | height: 50, 34 | width: MediaQuery.of(context).size.width * percentSize, 35 | padding: EdgeInsets.only(left: 10), 36 | margin: EdgeInsets.symmetric(horizontal: 20), 37 | decoration: BoxDecoration( 38 | color: Colors.grey.withOpacity(0.2), 39 | borderRadius: BorderRadius.circular(10)), 40 | child: Observer( 41 | builder: (_) => TextFormField( 42 | cursorColor: LageColors.yellow, 43 | style: TextStyle(fontSize: 16), 44 | decoration: InputDecoration( 45 | border: InputBorder.none, 46 | hoverColor: LageColors.yellow, 47 | fillColor: LageColors.yellow, 48 | hintText: 'Digite seu email', 49 | hintStyle: TextStyle(fontSize: 16), 50 | errorText: emailController.error.name), 51 | onChanged: emailController.setName, 52 | ), 53 | ), 54 | ), 55 | SizedBox( 56 | height: 10, 57 | ), 58 | Container( 59 | height: 70, 60 | width: MediaQuery.of(context).size.width * percentSize, 61 | padding: EdgeInsets.only(left: 10), 62 | margin: EdgeInsets.symmetric(horizontal: 20), 63 | decoration: BoxDecoration( 64 | color: Colors.grey.withOpacity(0.2), 65 | borderRadius: BorderRadius.circular(10)), 66 | child: Observer( 67 | builder: (_) => TextFormField( 68 | cursorColor: LageColors.yellow, 69 | style: TextStyle(fontSize: 16), 70 | decoration: InputDecoration( 71 | border: InputBorder.none, 72 | hoverColor: LageColors.yellow, 73 | fillColor: LageColors.yellow, 74 | hintText: 'Assunto', 75 | hintStyle: TextStyle(fontSize: 16), 76 | errorText: emailController.error.subject), 77 | maxLines: 2, 78 | maxLength: 50, 79 | onChanged: emailController.setSubject, 80 | ), 81 | )), 82 | SizedBox( 83 | height: 10, 84 | ), 85 | Container( 86 | height: 140, 87 | width: MediaQuery.of(context).size.width * percentSize, 88 | padding: EdgeInsets.only(left: 10), 89 | margin: EdgeInsets.symmetric(horizontal: 20), 90 | decoration: BoxDecoration( 91 | color: Colors.grey.withOpacity(0.2), 92 | borderRadius: BorderRadius.circular(10)), 93 | child: Observer( 94 | builder: (_) => TextFormField( 95 | cursorColor: LageColors.yellow, 96 | style: TextStyle(fontSize: 16), 97 | initialValue: initText, 98 | decoration: InputDecoration( 99 | border: InputBorder.none, 100 | hoverColor: LageColors.yellow, 101 | fillColor: LageColors.yellow, 102 | hintText: 'Texto', 103 | hintStyle: TextStyle(fontSize: 16), 104 | errorText: emailController.error.text), 105 | maxLines: 4, 106 | maxLengthEnforced: true, 107 | maxLength: 200, 108 | onChanged: emailController.setText, 109 | ), 110 | )), 111 | SizedBox( 112 | height: 10, 113 | ), 114 | InkWell( 115 | child: Container( 116 | height: 50, 117 | width: MediaQuery.of(context).size.width * percentSize, 118 | padding: EdgeInsets.only(left: 10), 119 | margin: EdgeInsets.symmetric(horizontal: 20), 120 | decoration: BoxDecoration( 121 | color: LageColors.yellow, 122 | borderRadius: BorderRadius.circular(10)), 123 | child: Center( 124 | child: Text( 125 | "ENVIAR", 126 | style: TextStyle( 127 | color: Colors.black, 128 | fontWeight: FontWeight.bold, 129 | fontSize: 20), 130 | ), 131 | ), 132 | ), 133 | onTap: () => emailController.validateAll().then((value) { 134 | if (value) { 135 | showDialog( 136 | barrierDismissible: false, 137 | context: context, 138 | builder: (_) => AlertDialog( 139 | content: ListTile( 140 | leading: CircularProgressIndicator( 141 | valueColor: AlwaysStoppedAnimation(LageColors.yellow), 142 | ), 143 | title: Text("Aguarde"), 144 | subtitle: Text('Enviando email'), 145 | ), 146 | ), 147 | ); 148 | emailController.submit().then((value) { 149 | Navigator.pop(context); 150 | showDialog( 151 | context: context, 152 | barrierDismissible: false, 153 | builder: (_) { 154 | Future.delayed(Duration(seconds: 3), () { 155 | Navigator.pop(context); 156 | }); 157 | 158 | return AlertDialog( 159 | content: ListTile( 160 | leading: Icon( 161 | value ? Icons.check_circle : Icons.cancel, 162 | color: LageColors.yellow, 163 | size: 40, 164 | ), 165 | title: value ? Text("Sucesso!") : Text("Ops!"), 166 | subtitle: value 167 | ? Text('Email enviado com sucesso!') 168 | : Text("ocorreu um erro, tente novamente")), 169 | ); 170 | }); 171 | }); 172 | } 173 | }), 174 | ), 175 | SizedBox( 176 | height: 10, 177 | ), 178 | InkWell( 179 | child: Container( 180 | height: 50, 181 | width: MediaQuery.of(context).size.width * percentSize, 182 | padding: EdgeInsets.only(left: 10), 183 | margin: EdgeInsets.symmetric(horizontal: 20), 184 | decoration: BoxDecoration( 185 | color: const Color(0xff25D366), 186 | borderRadius: BorderRadius.circular(10)), 187 | child: Center( 188 | child: Text( 189 | "WHATSAPP", 190 | style: TextStyle( 191 | color: Colors.white, 192 | fontWeight: FontWeight.bold, 193 | fontSize: 20), 194 | ), 195 | ), 196 | ), 197 | onTap: () => launch( 198 | "https://api.whatsapp.com/send?phone=553138222535&text=" + 199 | initText), 200 | ), 201 | SizedBox( 202 | height: 30, 203 | ) 204 | ], 205 | )); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /lib/pages/homePage/homePage_desktop.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | import 'package:site_lage/components/colors.dart'; 6 | import 'package:site_lage/controllers/search_controller.dart'; 7 | import 'package:site_lage/pages/properiesPage.dart'; 8 | import 'package:site_lage/widgets/homePage/propertiesList.dart'; 9 | import 'package:site_lage/widgets/homePage/propertiesListLoading.dart'; 10 | import 'package:site_lage/widgets/homePage/searchWidget.dart'; 11 | 12 | class HomePageDesktop extends StatelessWidget { 13 | final searchController = GetIt.I.get(); 14 | 15 | final AsyncSnapshot snapshot; 16 | 17 | HomePageDesktop({Key key, @required this.snapshot}) : super(key: key); 18 | @override 19 | Widget build(BuildContext context) { 20 | return Container( 21 | child: Column( 22 | crossAxisAlignment: CrossAxisAlignment.start, 23 | children: [ 24 | SearchWidget( 25 | size: 600, 26 | textSize: 70, 27 | percentSize: 0.6, 28 | number: Random().nextInt(5) + 1, 29 | ), 30 | SizedBox( 31 | height: 50, 32 | ), 33 | ListTile( 34 | enabled: false, 35 | contentPadding: EdgeInsets.symmetric(horizontal: 20), 36 | title: Text( 37 | "Destaques", 38 | style: TextStyle( 39 | fontSize: 30, 40 | fontWeight: FontWeight.bold, 41 | color: Colors.black), 42 | ), 43 | ), 44 | (snapshot.connectionState == ConnectionState.waiting 45 | ? PropertiesListLoading(size: 300) 46 | : PropertiesList( 47 | limit: 5, 48 | size: 300, 49 | properties: snapshot.data, 50 | )), 51 | Container( 52 | margin: EdgeInsets.symmetric(vertical: 25), 53 | width: MediaQuery.of(context).size.width, 54 | child: Image.network( 55 | "https://lageimoveis.s3.amazonaws.com/Lage_01.jpg", 56 | fit: BoxFit.fitWidth, 57 | ), 58 | ), 59 | 60 | snapshot.hasData && List.from(snapshot.data) 61 | .where((element) => element.type == "Casa") 62 | .length == 63 | 0 64 | ? Container() 65 | : ListTile( 66 | enabled: false, 67 | contentPadding: EdgeInsets.symmetric(horizontal: 20), 68 | title: Text( 69 | "Casas", 70 | style: TextStyle( 71 | fontSize: 30, 72 | fontWeight: FontWeight.bold, 73 | color: Colors.black), 74 | ), 75 | trailing: FlatButton( 76 | focusColor: Colors.transparent, 77 | hoverColor: Colors.transparent, 78 | highlightColor: Colors.transparent, 79 | splashColor: Colors.transparent, 80 | onPressed: () { 81 | searchController.setpropertyType("Casa"); 82 | Navigator.of(context).pushNamed(PropertiesPage.route); 83 | }, 84 | child: Text( 85 | "Ver mais", 86 | style: TextStyle(color: LageColors.yellow), 87 | )), 88 | ), 89 | snapshot.hasData && List.from(snapshot.data) 90 | .where((element) => element.type == "Casa") 91 | .length == 92 | 0 93 | ? Container() 94 | : (snapshot.connectionState == ConnectionState.waiting 95 | ? PropertiesListLoading(size: 300) 96 | : PropertiesList( 97 | size: 300, 98 | properties: snapshot.data.toList(), 99 | type: "Casa", 100 | )), 101 | snapshot.hasData && List.from(snapshot.data) 102 | .where((element) => element.type == "Apartamento") 103 | .length == 104 | 0 105 | ? Container() 106 | : ListTile( 107 | enabled: false, 108 | contentPadding: EdgeInsets.symmetric(horizontal: 20), 109 | title: Text( 110 | "Apartamentos", 111 | style: TextStyle( 112 | fontSize: 30, 113 | fontWeight: FontWeight.bold, 114 | color: Colors.black), 115 | ), 116 | trailing: FlatButton( 117 | focusColor: Colors.transparent, 118 | hoverColor: Colors.transparent, 119 | highlightColor: Colors.transparent, 120 | splashColor: Colors.transparent, 121 | onPressed: () { 122 | searchController.setpropertyType("Apartamento"); 123 | Navigator.of(context).pushNamed(PropertiesPage.route); 124 | }, 125 | child: Text( 126 | "Ver mais", 127 | style: TextStyle(color: LageColors.yellow), 128 | )), 129 | ), 130 | snapshot.hasData && List.from(snapshot.data) 131 | .where((element) => element.type == "Apartamento") 132 | .length == 133 | 0 134 | ? Container() 135 | : (snapshot.connectionState == ConnectionState.waiting 136 | ? PropertiesListLoading(size: 300) 137 | : PropertiesList( 138 | size: 300, 139 | properties: snapshot.data.toList(), 140 | type: "Apartamento", 141 | )), 142 | snapshot.hasData && List.from(snapshot.data) 143 | .where((element) => element.type == "Sítio") 144 | .length == 145 | 0 146 | ? Container() 147 | : ListTile( 148 | enabled: false, 149 | contentPadding: EdgeInsets.symmetric(horizontal: 20), 150 | title: Text( 151 | "Sítios", 152 | style: TextStyle( 153 | fontSize: 30, 154 | fontWeight: FontWeight.bold, 155 | color: Colors.black), 156 | ), 157 | trailing: FlatButton( 158 | focusColor: Colors.transparent, 159 | hoverColor: Colors.transparent, 160 | highlightColor: Colors.transparent, 161 | splashColor: Colors.transparent, 162 | onPressed: () { 163 | searchController.setpropertyType("Sítio"); 164 | Navigator.of(context).pushNamed(PropertiesPage.route); 165 | }, 166 | child: Text( 167 | "Ver mais", 168 | style: TextStyle(color: LageColors.yellow), 169 | )), 170 | ), 171 | snapshot.hasData && List.from(snapshot.data) 172 | .where((element) => element.type == "Sítio") 173 | .length == 174 | 0 175 | ? Container() 176 | : (snapshot.connectionState == ConnectionState.waiting 177 | ? PropertiesListLoading(size: 300) 178 | : PropertiesList( 179 | size: 300, 180 | properties: snapshot.data.toList(), 181 | type: "Sítio", 182 | )), 183 | snapshot.hasData && List.from(snapshot.data) 184 | .where((element) => element.type == "Lote") 185 | .length == 186 | 0 187 | ? Container() 188 | : ListTile( 189 | enabled: false, 190 | contentPadding: EdgeInsets.symmetric(horizontal: 20), 191 | title: Text( 192 | "Lotes", 193 | style: TextStyle( 194 | fontSize: 30, 195 | fontWeight: FontWeight.bold, 196 | color: Colors.black), 197 | ), 198 | trailing: FlatButton( 199 | focusColor: Colors.transparent, 200 | hoverColor: Colors.transparent, 201 | highlightColor: Colors.transparent, 202 | splashColor: Colors.transparent, 203 | onPressed: () { 204 | searchController.setpropertyType("Lote"); 205 | Navigator.of(context).pushNamed(PropertiesPage.route); 206 | }, 207 | child: Text( 208 | "Ver mais", 209 | style: TextStyle(color: LageColors.yellow), 210 | )), 211 | ), 212 | snapshot.hasData && List.from(snapshot.data) 213 | .where((element) => element.type == "Lote") 214 | .length == 215 | 0 216 | ? Container() 217 | : (snapshot.connectionState == ConnectionState.waiting 218 | ? PropertiesListLoading(size: 300) 219 | : PropertiesList( 220 | size: 300, 221 | properties: snapshot.data.toList(), 222 | type: "Lote", 223 | )), 224 | SizedBox(height: 30) 225 | ], 226 | ), 227 | ); 228 | } 229 | } 230 | --------------------------------------------------------------------------------