commit 8eda6bb8ed6d981331c26400a4d824cb6613f2bd Author: rasz Date: Thu Sep 2 08:35:25 2021 -0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0fa6b67 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..9db89cf --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 7f1d1414cc5f0b0317272ced49a9c0b44e5c3af8 + channel: master + +project_type: app diff --git a/README.md b/README.md new file mode 100644 index 0000000..9321ff4 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# ESMS +## Sistema de Gerenciamento para Técnicos em Eletrônica ou Informática +### Desenvolvido por: F. Raszeja, 2021 + +![Logo ESMS](android/app/src/main/ic_launcher-playstore.png) + +O sistema inclui: +1. Cadastro de Clientes +2. Registro de Aparelhos +3. Registro de Consertos Realizados + +Desenvolvido utilizando Flutter 2.7, com objetivo Apk funcional para Android + +---------------------------------------------------------------------------- +# EN-US +# ESMS +# Electronics Service Management System +### Author: F. Raszeja, 2021 + +![ESMS Logo](android/app/src/main/ic_launcher-playstore.png) + +Features: +1. View, Edit and Create Clients +2. View, Edit and Add stuff to repair +3. Once you're done, you can optionally register how the repair was made. + +This was made using Flutter 2.7, with the idea of having a working Apk file at the end. +It's all in Portuguese, currently. \ No newline at end of file diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..ba59e68 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,68 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 30 + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.esms.android" + minSdkVersion 21 + targetSdkVersion 30 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..ea84811 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..14293d9 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/ic_launcher-playstore.png b/android/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..990882b Binary files /dev/null and b/android/app/src/main/ic_launcher-playstore.png differ diff --git a/android/app/src/main/kotlin/com/esms/android/MainActivity.kt b/android/app/src/main/kotlin/com/esms/android/MainActivity.kt new file mode 100644 index 0000000..9d5b35c --- /dev/null +++ b/android/app/src/main/kotlin/com/esms/android/MainActivity.kt @@ -0,0 +1,6 @@ +package com.esms.android + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/drawable/ic_launcher_foreground.xml b/android/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..879f603 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..4b3201d Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..6e1ffe5 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..1217dbc Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..2b2ed08 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..94a37fd Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..b43a912 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..9a14aca Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..ba53706 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..f7a3839 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..ab76ace Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..a31a7e5 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..e12e535 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..168f53c Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..2096fc0 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..e39db77 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..449a9f9 --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..627fe62 --- /dev/null +++ b/android/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FF5252 + \ No newline at end of file diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..d74aa35 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..c61326e --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..ed45c65 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.1.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..94adc3a --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..bc6a58a --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..44e62bc --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..151026b --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,33 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..9367d48 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..51195e2 --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,472 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.esms.android; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.esms.android; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.esms.android; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..a28140c --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.h b/ios/Runner/AppDelegate.h new file mode 100644 index 0000000..36e21bb --- /dev/null +++ b/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/ios/Runner/AppDelegate.m b/ios/Runner/AppDelegate.m new file mode 100644 index 0000000..70e8393 --- /dev/null +++ b/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#import "AppDelegate.h" +#import "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +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. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..d034759 --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + esms_project + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/ios/Runner/main.m b/ios/Runner/main.m new file mode 100644 index 0000000..dff6597 --- /dev/null +++ b/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/lib/client.dart b/lib/client.dart new file mode 100644 index 0000000..9318d26 --- /dev/null +++ b/lib/client.dart @@ -0,0 +1,53 @@ +import 'dbhandler.dart'; + +class Client{ + final String name, + telephone, + cellular, + observations; + int id, status, enabled; + Client(this.name, this.telephone, this.cellular, this.observations); + + final dbHandler dbh = dbHandler.instance; + + Client.fromJson(Map jsona) + :id= int.tryParse(jsona['id'].toString()), + name = jsona['name'], + cellular = jsona['cellular'], + telephone = jsona['telephone'], + observations = jsona['observations']; + + Map toJson() => + { + 'name':name, + 'cellular':cellular, + 'telephone':telephone, + 'observations':observations + }; + + void SaveToDB() async + { + Future t = dbh.insert(this.toJson(),"client"); + t.then((int value){ + this.id = value; + return value; + }); + } + + Future LoadFromDB(int num) async{ + List> eq = await dbh.queryByID("client", num); + return Client.fromJson(eq[0]); + } + UpdateDB(int num) + { + dbh.update(this.toJson(), num, "client").then((value){ + status = 1; + },onError: (object){ + status = 0; + }); + } + Future RemoveDB(int num) async + { + return await dbh.delete(num, "client"); + } +} \ No newline at end of file diff --git a/lib/dbhandler.dart b/lib/dbhandler.dart new file mode 100644 index 0000000..2c392ba --- /dev/null +++ b/lib/dbhandler.dart @@ -0,0 +1,147 @@ +import 'dart:io'; +import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:sqflite/sqflite.dart'; + +class dbHandler{ + static final _dbname = "elec.db"; + static final _dbver = 1; + + dbHandler._privateConstructor(); + static final dbHandler instance = dbHandler._privateConstructor(); + + static Database _db; + + Future get database async{ + if(_db != null) return _db; + _db = await _initDB(); + return _db; + } + + _initDB() async{ + Directory docsDirectory = await getApplicationDocumentsDirectory(); + String path = join(docsDirectory.path,_dbname); + return await openDatabase(path, + version: _dbver, + onCreate: _onCreate + ); + } + + Future _onCreate(Database db, int version) async{ + Batch batch = db.batch(); + batch.execute( + "CREATE TABLE IF NOT EXISTS client ( " + "id INTEGER PRIMARY KEY, " + "name TEXT NOT NULL, " + "cellular TEXT, " + "telephone TEXT, " + "observations TEXT);" + ); + batch.execute( + "CREATE TABLE IF NOT EXISTS equipment (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "client_id INTEGER NOT NULL," + "name TEXT NOT NULL," + "problem TEXT NOT NULL," + "observation TEXT NOT NULL," + "images TEXT," + "dateInput TEXT NOT NULL," + "dateExit TEXT," + "isDelivered BOOLEAN NOT NULL); " + ); + batch.execute("CREATE TABLE IF NOT EXISTS repair(" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "eq_id INTEGER NOT NULL," + "repair TEXT NOT NULL);" + ); + batch.execute( + "CREATE VIEW v_repair " + "AS SELECT r.id as repair_id, " + "eq.id as id, " + "eq.name as name," + "r.repair as repair " + "FROM repair r INNER JOIN equipment eq " + "WHERE eq.id = r.eq_id" + ); + batch.execute("CREATE VIEW v_equipment " + "AS SELECT cli.id as client_id, " + "cli.name as name, " + "eq.id as id, " + "eq.name as equipment, " + "eq.problem as problem, " + "eq.observation as observation, " + "eq.images as images, " + "eq.dateInput as dateInput, " + "eq.dateExit as dateExit, " + "eq.isDelivered as isDelivered " + "FROM client cli INNER JOIN equipment eq " + "WHERE cli.id = eq.client_id"); + List res = await batch.commit(); + } + + Future insert(Map row, String table) async + { + Database db = await instance.database; + return await db.insert(table, row); + } + + Future>> queryAllRows(String table) async{ + Database db = await instance.database; + return await db.query(table); + } + + Future>> queryOrdered(String table, String order, String val) async{ + Database db = await instance.database; + return await db.query(table, orderBy: val+' '+order); + } + + Future>> queryAllEquipment() async{ + Database db = await instance.database; + return await db.query("v_equipment", orderBy: 'equipment ASC', where: 'isDelivered = 0'); + } + + Future>> queryAllEquipmentDelivered() async{ + Database db = await instance.database; + return await db.query("v_equipment", orderBy: 'equipment ASC', where: 'isDelivered = 1'); + } + + Future>> queryRepair(String name) async{ + Database db = await instance.database; + return await db.query("v_repair", where: 'name LIKE ?', whereArgs: ['%$name%'], orderBy: 'name ASC'); + } + + Future>> queryEquipment(String equipment) async{ + Database db = await instance.database; + return await db.query("v_equipment", where: 'equipment LIKE ?', whereArgs: ['%$equipment%'], orderBy: 'equipment ASC'); + } + + Future>> queryClient(String name) async{ + Database db = await instance.database; + return await db.query("client", where: 'name LIKE ?', whereArgs: ['%$name%'], orderBy: 'name ASC'); + } + + Future>> queryEquipmentClient(int client_id) async{ + Database db = await instance.database; + return await db.query("v_equipment", where: 'client_id = ?', whereArgs: [client_id]); + } + + Future>> queryByID(String table, int id) async { + Database db = await instance.database; + return await db.query(table, where: 'id = ?', whereArgs: [id]); + } + + Future>> queryByName(String table, String name) async { + Database db = await instance.database; + return await db.query(table, where: 'name LIKE ?', whereArgs: ['%$name%']); + } + + Future update(Map row, int id, String table) async{ + Database db = await instance.database; + return await db.update(table,row, where: 'id = ?', whereArgs: [id]); + } + + Future delete(int id, String table) async{ + Database db = await instance.database; + return await db.delete(table, where: 'id = ?', whereArgs: [id]); + } +} \ No newline at end of file diff --git a/lib/electronic.dart b/lib/electronic.dart new file mode 100644 index 0000000..186305d --- /dev/null +++ b/lib/electronic.dart @@ -0,0 +1,148 @@ +// Objetivo: Classe p/ guardar eletrônicos +// Nome +// Cliente (outra classe) +// Descrição do problema +// Observações +// Data da Entrada +// Data da Saída +// Foto(s) do aparelho +import 'dbhandler.dart'; + +class Repair{ + int id, status; + final int eq_id; + final repair; + Repair(this.eq_id,this.repair); + + final dbHandler dbh = dbHandler.instance; + + Map toJson() =>{ + 'eq_id': eq_id, + 'repair': repair + }; + Repair.fromView(Map jsona) + : + id = jsona['repair_id'], + eq_id = jsona['id'], + repair = jsona['repair']; + + Repair.fromJson(Map jsona) + : + eq_id = jsona['eq_id'], + repair = jsona['repair']; + + int SaveToDB() { + Future t = dbh.insert(this.toJson(), "repair"); + t.then((int value) { + this.id = value; + status = 1; + },onError: (object){ + status = 0; + }); + } + + Future LoadFromDB(int num) async { + dbh.queryByID("repair", num).then((List> value){ + return Repair.fromJson(value[0]); + } + ); + } + + UpdateDB(int num) { + dbh.update(this.toJson(), num, "repair").then((value){ + status = 1; + },onError: (object){ + status = 0; + }); + } + + RemoveDB(int num) { + dbh.delete(num, "repair").then((value){ + status = 1; + }, onError: (object){ + status = 0; + }); + } +} + +class Equipment { + int id, status; + final int client_id; + final String name, problem, observation; + final DateTime dateInput; + DateTime dateExit; + List images = []; + int isDelivered = 0; + Equipment(this.client_id, this.name, this.problem, this.observation, + this.dateInput); + + final dbHandler dbh = dbHandler.instance; + + Map toJson() => { + 'client_id': client_id, + 'name': name, + 'problem': problem, + 'observation': observation, + 'dateInput': dateInput.toString(), + 'dateExit': dateExit.toString(), + 'images': images.toString(), + 'isDelivered': isDelivered + }; + + Equipment.fromJson(Map jsona) + : id = jsona['id'], + client_id = jsona['client_id'], + name = jsona['name'], + problem = jsona['problem'], + observation = jsona['observation'], + dateInput = DateTime.tryParse(jsona['dateInput']), + dateExit = DateTime.tryParse(jsona['dateExit']), + images = jsona['images'].toString().substring(1,jsona['images'].length-1).split(',').toList(), + isDelivered = int.tryParse(jsona['isDelivered'].toString()); + + void AddImage(String image) { + images.add(image); + } + + void AddImageAsRange(List imageL) { + images.addAll(imageL); + } + + void EquipmentLeave(DateTime time) { + dateExit = time; + isDelivered = 1; + } + + int SaveToDB() { + Future t = dbh.insert(this.toJson(), "equipment"); + t.then((int value) { + this.id = value; + status = 1; + }, onError: (value) { + status = 0; + }); + } + + Future LoadFromDB(int num) async { + dbh.queryByID("equipment", num).then((List> value){ + return Equipment.fromJson(value[0]); + } + ); + } + + UpdateDB(int num) { + dbh.update(this.toJson(), num, "equipment").then((value){ + status = 1; + },onError: (object){ + status = 0; + }); + } + + RemoveDB(int num) { + dbh.delete(num, "equipment").then((value){ + status = 1; + }, onError: (object){ + status = 0; + }); + } +} diff --git a/lib/listEquipmentMain.dart b/lib/listEquipmentMain.dart new file mode 100644 index 0000000..6f18e11 --- /dev/null +++ b/lib/listEquipmentMain.dart @@ -0,0 +1,181 @@ +import 'package:esms_project/screens/listEquipment.dart'; +import 'package:esms_project/screens/listEquipmentByClient.dart'; +import 'package:esms_project/screens/listEquipmentByID.dart'; +import 'package:esms_project/screens/listEquipmentDelivered.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:esms_project/widgets/widget_input.dart'; +import 'package:flutter/material.dart'; + +class listEquipmentMain extends StatefulWidget { + @override + _listEquipmentMainState createState() => _listEquipmentMainState(); +} +// TODO: Tela pesquisar via cliente +// Polir +class _listEquipmentMainState extends State { + final _formCli = GlobalKey(); + final _formCli2 = GlobalKey(); + TextEditingController input = TextEditingController(); + TextEditingController input2 = TextEditingController(); + @override + Widget build(BuildContext context) { + return Scaffold(body: _layout()); + } + + _layout() { + return Container( + padding: EdgeInsets.all(20), + child: Center( + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + fontWeight: FontWeight.w400, + color: Colors.black, + fontSize: 30), + text: "Listagem de Aparelhos")), + RichText( + text: TextSpan( + style: TextStyle( + fontWeight: FontWeight.w300, + color: Colors.black, + fontSize: 20), + text: "Selecione uma das opções abaixo.")), + Divider(color: Colors.black38,), + FractionallySizedBox( + widthFactor: 0.7, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + BotaoCustom( + "Por Cliente", + onPressed: () => _modalInput("Digite um nome.", + "Ex. José da Silva"), + ), + BotaoCustom( + "Por Número", + onPressed: () => _modalInputID("Digite um número.", + "Ex. 1123"), + ), + BotaoCustom( + "Aparelhos Entregues", + onPressed: () => _goto(context, listEquipmentDelivered()), + ), + BotaoCustom("Aparelhos em Aberto", + onPressed: () => _goto(context, listEquipment())) + ], + ), + ) + ], + ), + ) + )); + } + + _goto(context, page) { + setState(() { + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) => page)); + }); + } + + _modalInputID(String label, String hint) { + input.clear(); + return showDialog( + context: context, + builder: (_) => SimpleDialog( + contentPadding: EdgeInsets.all(20), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(Icons.search), + Text("Filtro de Pesquisa"), + ], + ), + Divider(color: Colors.black38), + Form(key: _formCli, child: InputNumber(label, hint, controller: input)), + Botoes( + "Pesquisar", + onPressed: () => _validateSearchID(), + ), + Botoes( + "Fechar", + onPressed: () { + Navigator.of(context, rootNavigator: true).pop('dialog'); + }, + ) + ], + )); + } + + _modalInput(String label, String hint) { + input2.clear(); + return showDialog( + context: context, + builder: (_) => SimpleDialog( + contentPadding: EdgeInsets.all(20), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(Icons.search), + Text("Filtro de Pesquisa"), + ], + ), + Divider(color: Colors.black38), + Form(key: _formCli2, child: InputValidado(label, hint, controller: input2)), + Botoes( + "Pesquisar", + onPressed: () => _validateSearchClient(), + ), + Botoes( + "Fechar", + onPressed: () { + Navigator.of(context, rootNavigator: true).pop('dialog'); + }, + ) + ], + )); + } + _validateSearchClient() { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.unfocus(); + } + setState(() { + if (_formCli2.currentState.validate()) { + if (input2 != null) { + String name = input2.text; + Navigator.of(context, rootNavigator: true).pop('dialog'); + Navigator.of(context).push(new MaterialPageRoute( + builder: (context) => listEquipmentClient( + clientName: name, + ))); + } + } + }); + } + + _validateSearchID() { + FocusScopeNode currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus) { + currentFocus.unfocus(); + } + setState(() { + if (_formCli.currentState.validate()) { + if (input != null) { + int goto = int.tryParse(input.text); + input.clear(); + Navigator.of(context, rootNavigator: true).pop('dialog'); + Navigator.of(context).push(new MaterialPageRoute( + builder: (context) => listEquipmentID(goto))); + } + } + }); + } +} diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..9df32ba --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,25 @@ +import 'package:esms_project/mainScreen.dart'; +import 'package:flutter/material.dart'; + +void main() { + runApp(ESMSApp()); +} + +class ESMSApp extends StatelessWidget { + /* TODO: Consertos realizados em outros aparelhos parecidos? -- 01/06/2021, adicionado tabela + TODO: Fazer telas relacionadas a tabela + Vai pegar o nome do aparelho quando colocar data de entrega se o usuário quiser + Pode deletar ou alterar informações de reparo*/ + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'ESMS - Sistema para Técnicos em Eletrônica', + debugShowCheckedModeBanner: false, + theme: ThemeData( + primarySwatch: Colors.red, + ), + home: mainScreen(), + ); + } +} + diff --git a/lib/mainScreen.dart b/lib/mainScreen.dart new file mode 100644 index 0000000..5dd9392 --- /dev/null +++ b/lib/mainScreen.dart @@ -0,0 +1,123 @@ +import 'dart:io'; + +import 'package:esms_project/listEquipmentMain.dart'; +import 'package:esms_project/screens/aboutESMS.dart'; +import 'package:esms_project/screens/createClient.dart'; +import 'package:esms_project/screens/createEquipment.dart'; +import 'package:esms_project/screens/listClients.dart'; +import 'package:esms_project/screens/listRepairs.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:path_provider/path_provider.dart'; + +class mainScreen extends StatefulWidget { + @override + _mainScreenState createState() => _mainScreenState(); +} + +class _mainScreenState extends State { + String verNumber; + int superCoolSecret = 0; + @override + void initState() { + super.initState(); + makeFolders(); + } + + @override + Widget build(BuildContext context) { + return Scaffold(body: _layout()); + } + + makeFolders() async { + final _self = await getApplicationDocumentsDirectory(); + final _selfPictures = Directory('${_self.path}/Pictures'); + if (!await _selfPictures.exists()) { + final _newFolder = await _selfPictures.create(recursive: true); + } + PackageInfo.fromPlatform().then((PackageInfo p) { + verNumber = p.version; + }); + } + + _layout() { + return Container( + padding: EdgeInsets.all(20), + child: Center( + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + child: SizedBox( + child: Column( + children: [ + RichText( + text: TextSpan( + style: TextStyle( + fontWeight: FontWeight.w100, + color: Colors.black, + fontSize: 100), + text: "ESMS")), + RichText( + text: TextSpan( + style: TextStyle( + fontWeight: FontWeight.w400, + color: Colors.black, + fontSize: 12), + text: "Eletronics Servicing Management System"), + ) + ], + )), + onTap: () { + setState(() { + if (superCoolSecret < 4) superCoolSecret++; + }); + }, + highlightColor: Colors.transparent, + splashColor: Colors.transparent, + onLongPress: () { + setState(() { + if (superCoolSecret >= 4) _goto(context, AboutScr()); + }); + }, + ), + Divider( + color: Colors.black38, + ), + FractionallySizedBox( + widthFactor: 0.7, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + BotaoCustom( + "Cadastrar Cliente", + onPressed: () => _goto(context, CreateClient()), + ), + BotaoCustom("Cadastrar Aparelho", + onPressed: () => _goto(context, CreateEquipment())), + BotaoCustom("Ver Aparelhos", + onPressed: () => _goto(context, listEquipmentMain())), + BotaoCustom("Ver Clientes", + onPressed: () => _goto(context, ListClients())), + BotaoCustom("Ver Reparos", + onPressed: () => _goto(context, ListRepairs())), + ], + ), + ), + ], + ), + ) + )); + } + + _goto(context, page) { + setState(() { + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) => page)); + }); + } +} diff --git a/lib/screens/aboutESMS.dart b/lib/screens/aboutESMS.dart new file mode 100644 index 0000000..26e06ba --- /dev/null +++ b/lib/screens/aboutESMS.dart @@ -0,0 +1,144 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'dart:io' show Platform; + +class AboutScr extends StatefulWidget { + @override + _AboutScrState createState() => _AboutScrState(); +} + +class _AboutScrState extends State { + PackageInfo p; + String os; + Future loaded; + + Timer stuck; + Future loadVals() async { + if(Platform.isAndroid) + os = "Android"; + else if(Platform.isIOS) + os = "IOS"; + os += ' ${Platform.operatingSystemVersion}'; + + await PackageInfo.fromPlatform().then((value) { + p = value; + }); + return true && p != null; + } + + _reload() { + stuck = Timer(Duration(seconds: 2), () { + loaded = loadVals(); + stuck.cancel(); + setState(() {}); + }); + } + + @override + void initState() { + super.initState(); + loaded = loadVals(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Sobre"), + ), + body: _layout(), + ); + } + + _layout() { + return Container( + padding: EdgeInsets.all(10), + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) + return Center( + child: CircularProgressIndicator(), + ); + else if (p != null) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + flex: 8, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + fontWeight: FontWeight.w900, + color: Colors.redAccent[700], + fontSize: 12, + letterSpacing: 10), + text: "RELEASE ${p.version}",), + ), + RichText( + text: TextSpan( + style: TextStyle( + fontWeight: FontWeight.w100, + color: Colors.black, + fontSize: 100), + text: "ESMS"), + ), + RichText( + text: TextSpan( + style: TextStyle( + fontWeight: FontWeight.w400, + color: Colors.black, + fontSize: 12), + text: "Eletronics Servicing Management System"), + ), + Divider( + color: Colors.black38, + ), + RichText( + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 20), + text: + "Informações da Versão"), + ), + Container( + padding: EdgeInsets.all(30), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Divider(color: Colors.transparent,), + Text("Versão: ${p.version}"), + Text("Número da Build: ${p.buildNumber}"), + Text("Nome da Package: ${p.packageName}"), + Text("Versão Dart: ${Platform.version.substring(0,Platform.version.lastIndexOf('(dev)'))}"), + Text("Edição ${os}") + ], + ), + ) + ], + ) + ), + Divider(color: Colors.transparent,), + Expanded( + flex: 1, + child: Text("Desenvolvido por F. Raszeja, 2021") + ) + ], + )); + } + if (snapshot.data == false) { + _reload(); + } + return Container( + child: Text("Oops!"), + ); + }), + ); + } +} diff --git a/lib/screens/alterClient.dart b/lib/screens/alterClient.dart new file mode 100644 index 0000000..5466b2a --- /dev/null +++ b/lib/screens/alterClient.dart @@ -0,0 +1,215 @@ +import 'dart:async'; + +import 'package:esms_project/client.dart'; +import 'package:esms_project/screens/listClients.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:esms_project/widgets/widget_input.dart'; +import 'package:flutter/material.dart'; + +import 'clientDetail.dart'; + +class alterClient extends StatefulWidget { + Client c; + + alterClient(this.c); + @override + _alterClientState createState() => _alterClientState(); +} + +class _alterClientState extends State { + Timer d; + final values = new List.generate( + 4, (_) => TextEditingController()); + final _formCli = GlobalKey(); + + @override + void initState() { + values[0].text = widget.c.name; + values[1].text = widget.c.telephone; + values[2].text = widget.c.cellular; + values[3].text = widget.c.observations; + super.initState(); + } + + @override + void setState(fn) { + if (mounted) { + super.setState(fn); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Alterar Cliente"), + ), + body: _layout()); + } + + _layout() { + return Container( + padding: EdgeInsets.all(20), + height: double.infinity, + child: SingleChildScrollView( + child: Column( + children: [ + Form( + key: _formCli, + child: Column( + children: [ + InputValidado( + "Digite o nome do Cliente", + "Ex. João da Silva", + controller: values[0], + ), + InputTextosPhone( + "Digite um telefone", + "Ex. (15) 1234-5678", + controller: values[1], + ), + InputTextosPhone( + "Digite um celular", + "Ex. (15) 991234-5678", + controller: values[2], + ), + InputTextos( + "Observações:", + "Ex. Tem (15) 99123-4567 como outro número celular", + controller: values[3], + ), + ], + )), + Divider( + color: Colors.transparent, + ), + Botoes( + "Atualizar cliente", + onPressed: _updateClient, + ), + Botoes( + "Remover cliente", + onPressed: () { + _removeClient(); + }, + ) + ] + ) + )); + } + + _updateClient() { + setState(() { + if (_formCli.currentState.validate()) { + int temp = widget.c.id; + widget.c = new Client( + values[0].text, + values[1].text, + values[2].text, + values[3].text, + ); + widget.c.UpdateDB(temp); + int StuckCount = 0; + d = Timer(Duration(milliseconds: 300), () { + if (widget.c.status == 1) { + _showcontent(temp); + StuckCount = 0; + d.cancel(); + } + else + StuckCount++; + }); + if (StuckCount >= 2) + _displaySnackbar("Verifique os valores"); + } + }); + } + + _displaySnackbar(String text) { + setState(() { + final snackBar = + SnackBar(content: Text(text, style: TextStyle(fontSize: 16))); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + }); + } + + void _showcontent(temp) { + setState(() { + showDialog( + context: context, barrierDismissible: false, // user must tap button! + + builder: (BuildContext context) { + return new AlertDialog( + title: new Text('Aviso'), + content: new SingleChildScrollView( + child: new ListBody( + children: [ + new Text('Cliente atualizado.'), + ], + ), + ), + actions: [ + new TextButton( + child: new Text('OK'), + onPressed: () { + Navigator.of(context).popUntil((route) => route.isFirst); + if(values[0].text == "CLIENTE_REMOVIDO") + Navigator.of(context).push(new MaterialPageRoute( + builder: (context) => ListClients())); + else { + Navigator.of(context).push(new MaterialPageRoute( + builder: (context) => ListClients())); + Navigator.of(context).push(new MaterialPageRoute( + builder: (context) => ClientDetail(temp))); + } + + }, + ), + ], + ); + }, + ); + }); + } + + _removeClient() { + setState(() { + showDialog( + context: context, barrierDismissible: false, // user must tap button! + + builder: (BuildContext context) { + return new AlertDialog( + title: new Text('Confirmação'), + content: new SingleChildScrollView( + child: new ListBody( + children: [ + new Text('Tem certeza que quer remover o cliente ${widget.c + .name}?'), + ], + ), + ), + actions: [ + new TextButton( + child: new Text('Sim'), + onPressed: () { + values[0].text = "CLIENTE_REMOVIDO"; + values[1].text = ""; + values[2].text = ""; + values[3].text = ""; + _updateClient(); + + }, + ), + new TextButton( + child: new Text('Não'), + onPressed: () { + + }, + ), + ], + ); + }, + ); + }); + } +} diff --git a/lib/screens/alterEquipment.dart b/lib/screens/alterEquipment.dart new file mode 100644 index 0000000..813df7d --- /dev/null +++ b/lib/screens/alterEquipment.dart @@ -0,0 +1,364 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:esms_project/electronic.dart'; +import 'package:esms_project/screens/equipmentDetail.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:esms_project/widgets/widget_generate.dart'; +import 'package:esms_project/widgets/widget_input.dart'; +import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:intl/intl.dart'; +import 'package:path_provider/path_provider.dart'; + +class alterEquipment extends StatefulWidget { + Equipment e; + Repair r; + alterEquipment(this.e, {this.r}); + @override + _alterEquipmentState createState() => _alterEquipmentState(); +} + +class _alterEquipmentState extends State { + Timer d; + final values = new List.generate( + 6, (_) => TextEditingController()); + final _formEq = new GlobalKey(); + final _formRep = new GlobalKey(); + File _image; + + bool _writeRepair = false; + List imagens = []; + @override + void initState() { + imagens = widget.e.images; + values[0].text = widget.e.name; + values[1].text = widget.e.problem; + values[2].text = widget.e.observation; + values[3].text = DateFormat.yMd().format(widget.e.dateInput); + values[4].text = widget.e.dateExit == null + ? "" + : DateFormat.yMd().format(widget.e.dateExit); + if (widget.r != null) { + values[5].text = widget.r.repair == null ? "" : widget.r.repair; + _writeRepair = true; + } + super.initState(); + } + + @override + void setState(fn) { + if (mounted) { + super.setState(fn); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Alterar Informações"), + ), + body: _layout()); + } + + _layout() { + return Container( + padding: EdgeInsets.all(20), + height: double.infinity, + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 20, + fontStyle: FontStyle.normal, + fontWeight: FontWeight.w600), + text: "Preencha este formulário com informações do aparelho.", + ), + textAlign: TextAlign.center, + ), + Form( + key: _formEq, + child: Column( + children: [ + InputValidado( + "Nome do Aparelho", + "Ex.: Radio XYZ", + controller: values[0], + ), + InputValidado( + "Problema apresentado", + "Ex.: Tela quebrada", + controller: values[1], + ), + InputTextos( + "Observações", + "Ex.: Vem com cabos", + controller: values[2], + ), + InputData( + "Data de Entrada", + "Ex. " + DateFormat.yMd().format(DateTime.now()), + controller: values[3], + ), + InputDataNoValidate( + "Data de Saída", + "Ex. " + + DateFormat.yMd() + .format(DateTime.now().add(Duration(days: 30))), + controller: values[4], + ), + ], + )), + Divider( + color: Colors.transparent, + ), + RichText( + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 20, + fontStyle: FontStyle.normal, + fontWeight: FontWeight.w600), + text: "Deseja registrar o reparo?", + ), + textAlign: TextAlign.center, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + Radio( + groupValue: _writeRepair, + value: true, + onChanged: _onChangeRepair, + ), + Text("Sim", style: TextStyle(fontSize: 18)), + ], + ), + Row( + children: [ + Radio( + groupValue: _writeRepair, + value: false, + onChanged: _onChangeRepair, + ), + Text("Não", style: TextStyle(fontSize: 18)), + ], + ), + ], + ), + _Repair(), + Divider( + color: Colors.transparent, + ), + Botoes( + "Atualizar Aparelho", + onPressed: _update, + ), + if (imagens != null && imagens.length <= 10) + Botoes( + "Tire uma foto!", + onPressed: _snapPic, + ), + if (imagens[0].isNotEmpty) + Text("Você tirou " + imagens.length.toString() + " fotos."), + ], + ), + ), + ); + } + + bool _ValidateInputs() { + setState(() {}); + return widget.e != null && _formEq.currentState.validate(); + } + + bool _ValidateRepair() { + setState(() {}); + return _writeRepair && _formRep.currentState.validate(); + } + + _Repair() { + return _writeRepair + ? Container( + child: Form( + key: _formRep, + child: Column( + children: [ + InputValidado( + "Reparo realizado", + "Troca de peça X, Y, Z", + controller: values[5], + ) + ], + ), + ), + ) + : Container(); + } + + _onChangeRepair(bool value) { + setState(() { + _writeRepair = value; + }); + } + + Future _snapPic() async { + if (_ValidateInputs()) { + Directory dir = await getApplicationDocumentsDirectory(); + final imagem = await ImagePicker().getImage(source: ImageSource.camera); + + if (imagem != null) { + setState(() { + _image = File(imagem.path); + }); + final fileName = StringGenerator().getRandomString(10) + ".jpg"; + final savedImage = + await File(_image.path).copy('${dir.path}/Pictures/$fileName'); + + if (savedImage != null) { + if (imagens[0].isEmpty) + imagens[0] = fileName; + else + imagens.add(fileName); + _displaySnackbar("Foto adicionada com sucesso."); + } + } + } else { + _displaySnackbar("Verifique os campos."); + } + } + + _displaySnackbar(String text) { + setState(() { + final snackBar = + SnackBar(content: Text(text, style: TextStyle(fontSize: 16))); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + }); + } + + _update() { + setState(() { + if(!_writeRepair && widget.r != null) { + _deleteRepair(widget.r.id); + } + else if(_writeRepair || widget.r == null){ + _updateSt2(); + } + }); + } + _updateSt2() + { + if (_ValidateInputs()) { + int tmp = widget.e.id; + int tmp2 = widget.e.client_id; + widget.e = new Equipment( + tmp2, + values[0].text, + values[1].text, + values[2].text, + DateFormat.yMd().parse(values[3].text), + ); + widget.e.id = tmp; + if (values[4].text.isNotEmpty) + widget.e.EquipmentLeave(DateFormat.yMd().parse(values[4].text)); + widget.e.images = imagens; + widget.e.UpdateDB(tmp); + if (_ValidateRepair()) { + if (widget.r == null) { + widget.r = new Repair(tmp, values[5].text); + widget.r.SaveToDB(); + } else { + int tmp3 = widget.r.id; + widget.r = new Repair(tmp, values[5].text); + widget.r.UpdateDB(tmp3); + } + } + int TryCount = 0; + d = Timer(Duration(milliseconds: 200), () { + if ((!_writeRepair && widget.e.status == 1) || (widget.r.status == 1 && widget.e.status == 1)) { + TryCount = 0; + _showcontent(tmp); + d.cancel(); + } else + TryCount++; + }); + if (TryCount >= 2) _displaySnackbar("Erro na operação."); + } + } + void _deleteRepair(temp) + { + setState(() { + showDialog( + context: context, barrierDismissible: false, // user must tap button! + + builder: (BuildContext context) { + return new AlertDialog( + title: new Text('Aviso'), + content: new SingleChildScrollView( + child: new ListBody( + children: [ + new Text('Deseja remover informações sobre reparo?'), + ], + ), + ), + actions: [ + new TextButton( + child: new Text('Sim'), + onPressed: () { + widget.r.RemoveDB(temp); + _updateSt2(); + Navigator.of(context, rootNavigator: true).pop('dialog'); + }, + ), + new TextButton( + child: new Text('Não'), + onPressed: () { + _updateSt2(); + Navigator.of(context, rootNavigator: true).pop('dialog'); + }, + ), + ], + ); + }, + ); + }); + } + + void _showcontent(temp) { + setState(() { + showDialog( + context: context, barrierDismissible: false, // user must tap button! + + builder: (BuildContext context) { + return new AlertDialog( + title: new Text('Aviso'), + content: new SingleChildScrollView( + child: new ListBody( + children: [ + new Text('Equipamento atualizado.'), + ], + ), + ), + actions: [ + new TextButton( + child: new Text('OK'), + onPressed: () { + int count = 0; + Navigator.of(context).popUntil((_) => count++ >= 2); + Navigator.of(context).pushReplacement(new MaterialPageRoute( + builder: (context) => EquipmentDetail(temp))); + }, + ), + ], + ); + }, + ); + }); + } +} diff --git a/lib/screens/clientDetail.dart b/lib/screens/clientDetail.dart new file mode 100644 index 0000000..e26e505 --- /dev/null +++ b/lib/screens/clientDetail.dart @@ -0,0 +1,200 @@ +import 'dart:async'; + +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/client.dart'; +import 'package:esms_project/screens/alterClient.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:intl/intl.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import 'listEquipmentByClient.dart'; + +class ClientDetail extends StatefulWidget { + final int id; + ClientDetail(this.id); + + @override + _ClientDetailState createState() => _ClientDetailState(); +} + +class _ClientDetailState extends State { + final dbHandler dbh = dbHandler.instance; + Future loaded; + Timer stuck; + Client cli; + + Future _loadvars() async { + Future>> tmp = dbh.queryByID("client", widget.id); + tmp.then((List> value) { + cli = Client.fromJson(value[0]); + }); + return true && cli != null; + } + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + @override + void initState() { + super.initState(); + loaded = _loadvars(); + } + + _reload() { + stuck = Timer(Duration(seconds: 2), () { + loaded = _loadvars(); + stuck.cancel(); + setState(() {}); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Detalhes do Cliente"), + ), + body: _layout(), + ); + } + + _layout() { + return Container( + padding: EdgeInsets.all(30), + child: FutureBuilder( + future: loaded, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done && + cli != null) { + return Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Card( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + ListTile( + leading: const Icon(Icons.account_circle), + title: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 16), + text: cli.name)), + ), + ListTile( + leading: const Icon(Icons.phone), + title: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 12.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 16), + text: "Telefone: ${cli.telephone}", + ), + ), + onTap: () => + _launchUrl("tel:${cli.telephone}")), + ListTile( + leading: Icon(Icons.phone_android), + title: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 12.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 16), + text: "Celular: ${cli.cellular}")), + onTap: () => _launchUrl("tel:${cli.cellular}")), + ListTile( + leading: Icon(Icons.notes), + title: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 12.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 16), + text: + "Observações: ${cli.observations}")), + onTap: () => _modal( + cli.observations, "Observações", Icons.notes), + ), + ]), + ), + Botoes( + "Alterar", + onPressed: _update, + ), + Botoes( + "Ver Aparelhos", + onPressed: () => _list(cli.id), + ), + ], + ); + } + if (snapshot.data == false) { + _reload(); + } + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [CircularProgressIndicator(), Text("Carregando.")], + ), + ); + })); + } + + _modal(String value, String type, IconData icon) { + return showDialog( + context: context, + builder: (_) => SimpleDialog( + contentPadding: EdgeInsets.all(20), + semanticLabel: type, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(icon), + Text(type), + ], + ), + Divider(color: Colors.black38), + RichText( + strutStyle: StrutStyle(fontSize: 12.0), + text: TextSpan( + style: TextStyle(color: Colors.black, fontSize: 16), + text: value)), + Botoes( + "Fechar", + onPressed: () { + Navigator.of(context, rootNavigator: true).pop('dialog'); + }, + ) + ], + )); + } + + _launchUrl(String url) async { + await canLaunch(url) ? await launch(url) : print("Uh-oh!"); + } + + _update() { + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) => alterClient(cli))) + .whenComplete(_reload); + } + + _list(int id) { + setState(() { + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) => listEquipmentClient(id_client: widget.id,))) + .whenComplete(_loadvars); + }); + } +} diff --git a/lib/screens/createClient.dart b/lib/screens/createClient.dart new file mode 100644 index 0000000..7c91585 --- /dev/null +++ b/lib/screens/createClient.dart @@ -0,0 +1,103 @@ +import 'package:esms_project/client.dart'; +import 'package:esms_project/screens/listClients.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:esms_project/widgets/widget_input.dart'; +import 'package:flutter/material.dart'; +class CreateClient extends StatefulWidget { + @override + _CreateClientState createState() => _CreateClientState(); +} + +class _CreateClientState extends State { + final values = new List.generate( + 4, (_) => TextEditingController()); + Client c; + final _formCli = GlobalKey(); + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Adicionar Cliente"), + ), + body: _layout()); + } + _layout() { + return Container( + padding: EdgeInsets.all(20), + height: double.infinity, + child: SingleChildScrollView( + child: Column( + children: [ + Form( + key: _formCli, + child: Column( + children: [ + InputValidado( + "Digite o nome do Cliente", + "Ex. João da Silva", + controller: values[0], + ), + InputTextosPhone( + "Digite um telefone", + "Ex. (15) 1234-5678", + controller: values[1], + ), + InputTextosPhone( + "Digite um celular", + "Ex. (15) 991234-5678", + controller: values[2], + ), + InputTextos( + "Observações:", + "Ex. Tem (15) 99123-4567 como outro número celular", + controller: values[3], + ), + ], + )), + Divider( + color: Colors.transparent, + ), + Botoes( + "Cadastrar cliente", + onPressed: _addClient, + ) + ] + ) + )); + } + + _addClient() { + setState(() { + if (_formCli.currentState.validate()) { + c = new Client( + values[0].text, values[1].text, values[2].text, values[3].text); + c.SaveToDB(); + if (c.id != null || c.id != 0) { + _displaySnackbar("Cliente cadastrado."); + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (context) => ListClients())); + } else { + _displaySnackbar("Erro no cadastro."); + } + } else { + _displaySnackbar("Verifique o cadastro!"); + } + }); + } + + _displaySnackbar(String text) { + setState(() { + final snackBar = + SnackBar(content: Text(text, style: TextStyle(fontSize: 16))); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + }); + } +} diff --git a/lib/screens/createEquipment.dart b/lib/screens/createEquipment.dart new file mode 100644 index 0000000..be099f8 --- /dev/null +++ b/lib/screens/createEquipment.dart @@ -0,0 +1,360 @@ +import 'dart:io'; + +import 'package:esms_project/client.dart'; +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/electronic.dart'; +import 'package:esms_project/mainScreen.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:esms_project/widgets/widget_generate.dart'; +import 'package:esms_project/widgets/widget_input.dart'; +import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:intl/intl.dart'; +import 'package:path_provider/path_provider.dart'; + +class CreateEquipment extends StatefulWidget { + Client c; + CreateEquipment({this.c}); + @override + _CreateEquipmentState createState() => _CreateEquipmentState(); +} + +class _CreateEquipmentState extends State { + final values = new List.generate( + 9, (_) => TextEditingController()); + List imagens = []; + List> clients; + Client c; + bool _client = true; + bool _justregistered = false; + File _image; + final _formEq = GlobalKey(); + final _formCli = GlobalKey(); + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + @override + void initState() { + c = widget.c == null? null: widget.c; + if(c != null) + { + _client = true; + _justregistered = true; + values[3].text = c.name; + } + super.initState(); + } + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Adicionar Aparelho"), + ), + body: _layout()); + } + + _layout() { + return Container( + padding: EdgeInsets.all(20), + height: double.infinity, + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 20, + fontStyle: FontStyle.normal, + fontWeight: FontWeight.w600), + text: "Preencha este formulário com informações do aparelho.", + ), + textAlign: TextAlign.center, + ), + Form( + key: _formEq, + child: Column( + children: [ + InputValidado( + "Nome do Aparelho", + "Ex.: Radio XYZ", + controller: values[0], + ), + InputValidado( + "Problema apresentado", + "Ex.: Tela quebrada", + controller: values[1], + ), + InputTextos( + "Observações", + "Ex.: Vem com cabos", + controller: values[2], + ), + InputData( + "Data de Entrada", + "Ex. " + DateFormat.yMd().format(DateTime.now()), + controller: values[8], + ) + ], + )), + Divider( + color: Colors.transparent, + ), + RichText( + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 20, + fontStyle: FontStyle.normal, + fontWeight: FontWeight.w600), + text: "O cliente ja é cadastrado?", + ), + textAlign: TextAlign.center, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + Radio( + groupValue: _client, + value: true, + onChanged: _onChangeClient, + ), + Text("Sim", style: TextStyle(fontSize: 18)), + ], + ), + Row( + children: [ + Radio( + groupValue: _client, + value: false, + onChanged: _onChangeClient, + ), + Text("Não", style: TextStyle(fontSize: 18)), + ], + ), + ], + ), + Divider( + color: Colors.transparent, + ), + _clientCheck(), + Divider( + color: Colors.transparent, + ), + if (_justregistered == true) + Column( + children: [ + Botoes( + "Cadastrar Aparelho", + onPressed: _addEquipment, + ), + if (imagens != null && imagens.length <= 10) + Botoes( + "Tire uma foto!", + onPressed: _snapPic, + ), + ], + ), + if (imagens != null && imagens.length > 0) + Text("Você tirou " + imagens.length.toString() + " fotos.") + ], + ), + )); + } + + _onChangeClient(bool value) { + setState(() { + _client = value; + }); + } + + Future _GetClient() async { + if (values[3] != null && values[3].text.isNotEmpty) { + clients = await dbHandler.instance.queryByName("client", values[3].text); + List> temp = List.empty(growable: true); + setState(() { + if (clients != null) { + for (int i = 0; i < clients.length; i++) { + if (clients[i]['name'] != 'CLIENTE_REMOVIDO') + temp.add(clients[i]); + } + clients = temp; + } + FocusScope.of(context).unfocus(); + }); + } + } + + _clientCheck() { + return _client + ? Column( + children: [ + Row( + children: [ + Expanded( + child: InputTextos( + "Buscar por nome", + "Ex. João da Silva", + controller: values[3], + )), + IconButton(onPressed: _GetClient, icon: Icon(Icons.search)) + ], + ), + if (clients != null) + for (int i = 0; i < clients.length; i++) + Column( + children: [ + Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row(children: [ + Icon(Icons.account_circle_rounded), + Text( + " Cliente: " + clients[i]['name'].toString(), + style: TextStyle( + fontSize: 18, + color: Colors.black, + fontWeight: FontWeight.w300, + ), + ), + ]), + Botoes("Selecionar", onPressed: () => _loadCli(i)) + ], + ), + ], + ), + ], + ) + : Column( + children: [ + Form( + key: _formCli, + child: Column( + children: [ + InputValidado( + "Digite o nome do Cliente", + "Ex. João da Silva", + controller: values[4], + ), + InputTextosPhone( + "Digite um telefone", + "Ex. (15) 1234-5678", + controller: values[5], + ), + InputTextosPhone( + "Digite um celular", + "Ex. (15) 991234-5678", + controller: values[6], + ), + InputTextos( + "Observações:", + "Ex. Tem (15) 99123-4567 como outro número celular", + controller: values[7], + ), + ], + )), + Divider( + color: Colors.transparent, + ), + Botoes( + "Cadastrar cliente", + onPressed: _addClient, + ) + ], + ); + } + + _addClient() { + setState(() { + if (_formCli.currentState.validate()) { + _client = true; + c = new Client( + values[4].text, values[5].text, values[6].text, values[7].text); + c.SaveToDB(); + if (c.id != null || c.id != 0) { + values[3].text = values[4].text; + _displaySnackbar("Cliente cadastrado."); + _justregistered = true; + } else { + _displaySnackbar("Erro no cadastro."); + } + } else { + _displaySnackbar("Verifique o cadastro!"); + } + }); + } + + bool _ValidateInputs() { + setState(() {}); + return _formEq.currentState.validate() && c != null; + } + + Future _snapPic() async { + if (_ValidateInputs()) { + Directory dir = await getApplicationDocumentsDirectory(); + final imagem = await ImagePicker().getImage(source: ImageSource.camera); + + if (imagem != null) { + setState(() { + _image = File(imagem.path); + }); + + final fileName = StringGenerator().getRandomString(10) + ".jpg"; + final savedImage = await File(imagem.path).copy( + '${dir.path}/Pictures/$fileName'); + if(savedImage != null) { + imagens.add(fileName); + _displaySnackbar("Foto adicionada com sucesso."); + } + } + } + } + + _displaySnackbar(String text) { + setState(() { + final snackBar = + SnackBar(content: Text(text, style: TextStyle(fontSize: 16))); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + }); + } + + _addEquipment() { + setState(() { + if (_formEq.currentState.validate()) { + Equipment e = new Equipment( + c.id, + values[0].text, + values[1].text, + values[2].text, + DateFormat.yMd().parse(values[8].text), + ); + e.AddImageAsRange(imagens); + + if (e.SaveToDB() == 1) { + _displaySnackbar("Erro no cadastro!"); + } else { + _displaySnackbar("Cadastrado com sucesso."); + Navigator.of(context).pushReplacement(new MaterialPageRoute(builder: (context) => mainScreen())); + } + } + }); + } + + _loadCli(int index) { + setState(() { + values[3].text = clients[index]['name'].toString(); + c = Client.fromJson(clients[index]); + clients = null; + _justregistered = true; + }); + } +} diff --git a/lib/screens/equipmentDetail.dart b/lib/screens/equipmentDetail.dart new file mode 100644 index 0000000..a1abe4f --- /dev/null +++ b/lib/screens/equipmentDetail.dart @@ -0,0 +1,288 @@ +import 'dart:async'; + +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/electronic.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:esms_project/widgets/widget_caroussel.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import 'alterEquipment.dart'; + +class EquipmentDetail extends StatefulWidget { + final int id; + EquipmentDetail(this.id); + + @override + _EquipmentDetailState createState() => _EquipmentDetailState(); +} + +class _EquipmentDetailState extends State { + final dbHandler dbh = dbHandler.instance; + Future loaded; + Timer stuck, d; + bool openProblem = false; + bool openObservation = false; + Equipment eq; + Repair r; + Future _loadvars() async { + dbh + .queryByID("equipment", widget.id) + .then((List> value) { + eq = Equipment.fromJson(value[0]); + }); + dbh + .queryByID("v_repair", widget.id) + .then((List> value) { + r = Repair.fromView(value[0]); + }); + + return true && eq != null; + } + + _reload() { + stuck = Timer(Duration(seconds: 2), () { + loaded = _loadvars(); + stuck.cancel(); + setState(() {}); + }); + } + + @override + void setState(fn) { + if (mounted) { + super.setState(fn); + } + } + + @override + void initState() { + super.initState(); + loaded = _loadvars(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Detalhes do Aparelho"), + ), + body: _layout(), + ); + } + + _layout() { + return Container( + margin: EdgeInsets.all(10), + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + eq != null) { + return Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Card( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + ListTile( + title: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 16), + text: "N°" + eq.id.toString())), + ), + RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 16), + text: eq.name)), + Divider(color: Colors.black38), + Column(children: [ + if (eq.images.length > 0) + eq.images[0].isNotEmpty + ? SizedBox( + height: 270, + child: Caroussel(eq.images)) + : SizedBox( + height: 170, + child: Center( + child: RichText( + strutStyle: + StrutStyle(fontSize: 30.0), + text: TextSpan( + style: TextStyle( + color: Colors.black26, + fontSize: 30, + fontWeight: + FontWeight.w300, + fontStyle: + FontStyle.italic), + text: "Sem Imagem")), + )), + ]), + Divider(color: Colors.black38), + ListTile( + leading: const Icon(Icons.warning), + title: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 12.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 16), + text: "Problema : " + '${eq.problem}', + ), + ), + onTap: () => _modal('${eq.problem}', "Problema", + Icons.warning_amber_outlined), + ), + ListTile( + leading: Icon(Icons.info), + title: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 12.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, fontSize: 16), + text: "Observações : " + + '${eq.observation}')), + onTap: () => _modal('${eq.observation}', + "Observações", Icons.info_outline), + ), + ListTile( + leading: Icon(Icons.calendar_today), + title: Text("Data de Entrada: " + + '${DateFormat.yMMMd().format(eq.dateInput)}'), + ), + _Eval(), + Divider(color: Colors.black38), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Botoes( + "Alterar", + onPressed: _update, + ), + Botoes( + "Remover", + onPressed: _remove, + ) + ], + ), + Divider(color: Colors.transparent), + ]), + ), + ], + ); + } + if (snapshot.data == false) { + _reload(); + } + return Center( + child: CircularProgressIndicator(), + ); + })); + } + + _Eval() { + return eq.dateExit != null + ? ListTile( + leading: Icon(Icons.calendar_today_outlined), + title: Text("Data de Entrega: " + + '${DateFormat.yMMMd().format(eq.dateExit)}')) + : Container(width: 0, height: 0); + } + + _update() { + setState(() { + Navigator.of(context) + .push(new MaterialPageRoute( + builder: (context) => alterEquipment(eq, r: r))) + .whenComplete(_reload); + }); + } + + _remove() { + return showDialog( + context: context, + builder: (_) => SimpleDialog( + contentPadding: EdgeInsets.all(20), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(Icons.warning_amber_outlined), + Text("Confirmação de Ação") + ], + ), + Divider(color: Colors.black38), + RichText( + strutStyle: StrutStyle(fontSize: 12.0), + text: TextSpan( + style: TextStyle(color: Colors.black, fontSize: 16), + text: "Deseja realmente remover ${eq.name}?") + ), + Divider(color: Colors.transparent), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Botoes("Sim", onPressed: (){ + eq.RemoveDB(eq.id); + if(r != null) + r.RemoveDB(r.id); + d = Timer(Duration(milliseconds: 200), () + { + if ((r != null && r.status == 1 && eq.status == 1) || + (r == null && eq.status == 1)) { + d.cancel(); + int count = 0; + Navigator.of(context).popUntil((_) => count++ >= 2); + } + }); + /**/ + },), + Botoes("Não", onPressed: (){ + Navigator.of(context, rootNavigator: true).pop('dialog'); + },) + ], + ) + ], + ) + ); + } + + _modal(String value, String type, IconData icon) { + return showDialog( + context: context, + builder: (_) => SimpleDialog( + contentPadding: EdgeInsets.all(20), + semanticLabel: type, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(icon), + Text(type), + ], + ), + Divider(color: Colors.black38), + RichText( + strutStyle: StrutStyle(fontSize: 12.0), + text: TextSpan( + style: TextStyle(color: Colors.black, fontSize: 16), + text: value)), + Botoes( + "Fechar", + onPressed: () { + Navigator.of(context, rootNavigator: true).pop('dialog'); + }, + ) + ], + )); + } +} diff --git a/lib/screens/listClients.dart b/lib/screens/listClients.dart new file mode 100644 index 0000000..90909b5 --- /dev/null +++ b/lib/screens/listClients.dart @@ -0,0 +1,210 @@ +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/screens/clientDetail.dart'; +import 'package:esms_project/screens/createClient.dart'; +import 'package:flutter/material.dart'; +import 'package:esms_project/widgets/widget_button.dart'; + +class ListClients extends StatefulWidget { + @override + _ListClientsState createState() => _ListClientsState(); +} + +class _ListClientsState extends State { + final dbHandler dbh = dbHandler.instance; + Future loaded; + List> cliList = List.empty(growable: true); + + Future _loadvars() async { + cliList = List.empty(growable: true); + dbh.queryOrdered("client", "ASC", "name").then((value) { + List> tmp = value; + for(int i = 0; i < tmp.length; i++) + { + if(tmp[i]['name'] != "CLIENTE_REMOVIDO") + { + cliList.add(tmp[i]); + } + } + setState(() { + return true && cliList != null; + }); + }); + return false; + } + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + @override + void initState() { + super.initState(); + loaded = _loadvars(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Listagem de Clientes"), + actions: [ + IconButton( + icon: Icon(Icons.add_box_outlined), + onPressed: () { + setState(() { + Navigator.of(context) + .push(new MaterialPageRoute( + builder: (context) => CreateClient())) + .whenComplete(_loadvars); + }); + }, + ) + ], + ), + body: _body(), + ); + } + + _body() { + return Container( + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) + return Center( + child: CircularProgressIndicator(), + ); + else if (cliList != null && cliList.length != 0) { + return ListView.separated( + padding: const EdgeInsets.all(8), + itemCount: cliList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + padding: const EdgeInsets.only(left: 10), + height: 90, + color: Colors.black12, + child: InkWell( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 18.0), + text: TextSpan( + style: TextStyle(color: Colors.black, fontSize: 18.0), + text: "Cliente: " + + '${cliList[index]['name']}')), + ], + ), + Row( + children: [ + RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 18.0), + text: TextSpan( + style: TextStyle(color: Colors.black, fontSize: 18.0), + text: "Celular: " + + '${cliList[index]['cellular']}')) + ], + ) + ], + ), + onTap: () => + onPressWithArg(context, cliList[index]['id']), + )); + }, + separatorBuilder: (BuildContext context, int index) => + const Divider()); + } else { + return Container( + child: Center( + child: Column( + children: [ + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "Estou vazio!"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: + "Cadastre um cliente clicando no botão "), + ), + Icon( + Icons.add_box_outlined, + color: Colors.black26, + ), + ]), + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "\nOu tente recarregar a tela."), + ), + Botoes( + "Recarregar", + onPressed: () => _update(context), + ) + ], + ), + ) + ], + ))); + } + }, + ), + ); + } + + _update(BuildContext context) { + setState(() { + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (context) => ListClients())); + }); + } + + onPressWithArg(context, int id) { + setState(() { + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) => ClientDetail(id))) + .whenComplete(_loadvars); + }); + } +} diff --git a/lib/screens/listEquipment.dart b/lib/screens/listEquipment.dart new file mode 100644 index 0000000..d4e0f10 --- /dev/null +++ b/lib/screens/listEquipment.dart @@ -0,0 +1,236 @@ +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/screens/createEquipment.dart'; +import 'package:esms_project/screens/equipmentDetail.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:esms_project/electronic.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:intl/intl.dart'; + +class listEquipment extends StatefulWidget { + @override + _listEquipmentState createState() => _listEquipmentState(); +} + +class _listEquipmentState extends State { + final dbHandler dbh = dbHandler.instance; + Future loaded; + List> eqList; + + Future _loadvars() async { + dbh.queryAllEquipment().then((value) { + eqList = value; + setState(() { + return true && eqList != null; + }); + }); + return false; + } + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + @override + void initState() { + super.initState(); + loaded = _loadvars(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Aparelhos para Conserto"), + actions: [ + IconButton( + onPressed: () => _addItem(context), + icon: Icon(Icons.add_box_outlined)) + ], + ), + body: _body(), + ); + } + + _body() { + return Container( + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) + return Center( + child: CircularProgressIndicator(), + ); + else if (eqList != null && eqList.length != 0) { + return ListView.separated( + padding: const EdgeInsets.all(8), + itemCount: eqList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + padding: const EdgeInsets.only(left: 10), + height: 90, + color: Colors.black12, + child: InkWell( + child: Center( + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + Row( + children: [ + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: + "Aparelho: "+'${eqList[index]['equipment']}'))), + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Cliente: " + + '${eqList[index]['name']}'))), + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Data: " + + '${DateFormat.yMd().format(DateTime.tryParse(eqList[index]['dateInput']))}'))), + ], + ), + ]), + ), + onTap: () => onPressWithArg( + context, + eqList[index]['id'], + ))); + }, + separatorBuilder: (BuildContext context, int index) => + const Divider()); + } else { + return Container( + child: Center( + child: Column( + children: [ + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "Estou vazio!"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: + "Cadastre um aparelho clicando no botão "), + ), + Icon( + Icons.add_box_outlined, + color: Colors.black26, + ), + ]), + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "\nOu tente recarregar a tela."), + ), + Botoes( + "Recarregar", + onPressed: () => _update(context), + ) + ], + ), + ) + ], + ))); + } + }, + ), + ); + } + + _update(ctx) { + setState(() { + Navigator.pushReplacement( + ctx, MaterialPageRoute(builder: (context) => listEquipment())); + }); + } + + // + void load(int arg) async { + Equipment t = new Equipment(0, "", "", "", DateTime.now()); + t = await t.LoadFromDB(arg); + } + + void onPressWithArg(ctx, int id) { + setState(() { + Navigator.of(ctx) + .push( + new MaterialPageRoute(builder: (context) => EquipmentDetail(id))) + .whenComplete(_loadvars); + }); + } + + _addItem(ctx) { + setState(() { + Navigator.of(ctx) + .push(new MaterialPageRoute(builder: (context) => CreateEquipment())) + .whenComplete(_loadvars); + }); + } +} diff --git a/lib/screens/listEquipmentByClient.dart b/lib/screens/listEquipmentByClient.dart new file mode 100644 index 0000000..0e6a3d5 --- /dev/null +++ b/lib/screens/listEquipmentByClient.dart @@ -0,0 +1,283 @@ +import 'dart:async'; + +import 'package:esms_project/client.dart'; +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/screens/createEquipment.dart'; +import 'package:esms_project/screens/equipmentDetail.dart'; +import 'package:flutter/material.dart'; +import 'package:esms_project/electronic.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:intl/intl.dart'; + +class listEquipmentClient extends StatefulWidget { + int id_client; + String clientName; + listEquipmentClient({this.id_client,this.clientName}); + @override + _listEquipmentClientState createState() => _listEquipmentClientState(); +} + +class _listEquipmentClientState extends State { + final dbHandler dbh = dbHandler.instance; + Future loaded; + List> eqList; + Client c; + int count = 0; + Timer stuck; + Future _loadvars() async { + if(widget.id_client!=null) { + dbh.queryByID("client", widget.id_client).then((value) { + c = Client.fromJson(value[0]); + }); + widget.clientName = null; + dbh.queryEquipmentClient(widget.id_client).then((value) { + eqList = value; + }); + } + if(widget.clientName != null) + { + widget.id_client = null; + dbh.queryByName("v_equipment", widget.clientName).then((value) { + eqList = value; + }); + } + setState(() { + return true && eqList != null; + }); + } + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + _reload() { + if(count < 2) + stuck = Timer(Duration(seconds: 1), () { + if(eqList == null) + loaded = _loadvars(); + stuck.cancel(); + count++; + setState(() {}); + }); + } + + @override + void initState() { + super.initState(); + loaded = _loadvars(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Resultados da Pesquisa"), + actions: [ + if(widget.id_client != null) + IconButton( + onPressed: () => _addItem(context), + icon: Icon(Icons.add_box_outlined)) + ], + ), + body: _body(), + ); + } + + _body() { + return Container( + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) + return Center( + child: CircularProgressIndicator(), + ); + else if (eqList != null && eqList.length > 0) { + return ListView.separated( + padding: const EdgeInsets.all(8), + itemCount: eqList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + padding: const EdgeInsets.only(left: 10), + height: 90, + color: Colors.black12, + child: InkWell( + child: Center( + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: + '${eqList[index]['equipment']}'))), + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 18.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: + '${eqList[index]['problem']}'))), + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Data: " + + '${DateFormat.yMd().format(DateTime.tryParse(eqList[index]['dateInput']))}'))), + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Cliente: "+eqList[index]['name']) + ) + ) + ], + ), + ]), + ), + onTap: () => onPressWithArg( + context, + eqList[index]['id'], + ))); + }, + separatorBuilder: (BuildContext context, int index) => + const Divider()); + } + if (snapshot.data == null) { + _reload(); + } + return Container( + child: Center( + child: Column( + children: [ + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "Estou vazio!"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: + "Cadastre um aparelho clicando no botão "), + ), + Icon( + Icons.add_box_outlined, + color: Colors.black26, + ), + ]), + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "\nOu tente recarregar a tela."), + ), + Botoes( + "Recarregar", + onPressed: () => _update(context), + ) + ], + ), + ) + ], + ))); + } + ), + ); + } + + _update(ctx) { + setState(() { + Navigator.pushReplacement( + ctx, + MaterialPageRoute( + builder: (context) => listEquipmentClient(id_client: widget.id_client, clientName: widget.clientName,))); + }); + } + + // + void load(int arg) async { + Equipment t = new Equipment(0, "", "", "", DateTime.now()); + t = await t.LoadFromDB(arg); + } + + void onPressWithArg(ctx, int id) { + setState(() { + Navigator.of(ctx) + .push( + new MaterialPageRoute(builder: (context) => EquipmentDetail(id))) + .whenComplete(_loadvars); + }); + } + + _addItem(ctx) { + setState(() { + Navigator.of(ctx) + .push(new MaterialPageRoute(builder: (context) => CreateEquipment(c: c))) + .whenComplete(_loadvars); + }); + } +} diff --git a/lib/screens/listEquipmentByID.dart b/lib/screens/listEquipmentByID.dart new file mode 100644 index 0000000..16b6632 --- /dev/null +++ b/lib/screens/listEquipmentByID.dart @@ -0,0 +1,236 @@ +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/screens/equipmentDetail.dart'; +import 'package:flutter/material.dart'; +import 'package:esms_project/electronic.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:intl/intl.dart'; + +class listEquipmentID extends StatefulWidget { + final int id; + + listEquipmentID(this.id); + @override + _listEquipmentIDState createState() => _listEquipmentIDState(); +} + +class _listEquipmentIDState extends State { + final dbHandler dbh = dbHandler.instance; + Future loaded; + List> eqList; + + Future _loadvars() async { + dbh.queryByID("v_equipment", widget.id).then((value) { + eqList = value; + setState(() { + return true && eqList != null; + }); + }); + return false; + } + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + @override + void initState() { + super.initState(); + loaded = _loadvars(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Resultados da Pesquisa"), + ), + body: _body(), + ); + } + + _body() { + return Container( + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) + return Center( + child: CircularProgressIndicator(), + ); + else if (eqList != null && eqList.length != 0) { + return ListView.separated( + padding: const EdgeInsets.all(8), + itemCount: eqList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + padding: const EdgeInsets.only(left: 10), + height: 90, + color: Colors.black12, + child: InkWell( + child: Center( + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: "Aparelho: " + + '${eqList[index]['equipment']}'))), + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Cliente: " + + '${eqList[index]['name']}'))), + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Entrada: " + + '${DateFormat.yMd().format(DateTime.tryParse(eqList[index]['dateInput']))}'))), + if (eqList != null && DateTime.tryParse(eqList[index]['dateExit']) != null) + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Saída: " + + '${DateFormat.yMd().format(DateTime.tryParse(eqList[index]['dateExit']))}'))) + ], + ), + ]), + ), + onTap: () => onPressWithArg( + context, + eqList[index]['id'], + ))); + }, + separatorBuilder: (BuildContext context, int index) => + const Divider()); + } else { + return Container( + child: Center( + child: Column( + children: [ + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "Estou vazio!"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: + "Cadastre um aparelho clicando no botão "), + ), + Icon( + Icons.add_box_outlined, + color: Colors.black26, + ), + ]), + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "\nOu tente recarregar a tela."), + ), + Botoes( + "Recarregar", + onPressed: () => _update(context), + ) + ], + ), + ) + ], + ))); + } + }, + ), + ); + } + + _update(ctx) { + setState(() { + Navigator.pushReplacement(ctx, + MaterialPageRoute(builder: (context) => listEquipmentID(widget.id))); + }); + } + + // + void load(int arg) async { + Equipment t = new Equipment(0, "", "", "", DateTime.now()); + t = await t.LoadFromDB(arg); + } + + void onPressWithArg(ctx, int id) { + setState(() { + Navigator.of(ctx) + .push( + new MaterialPageRoute(builder: (context) => EquipmentDetail(id))) + .whenComplete(_loadvars); + }); + } +} diff --git a/lib/screens/listEquipmentDelivered.dart b/lib/screens/listEquipmentDelivered.dart new file mode 100644 index 0000000..440bf12 --- /dev/null +++ b/lib/screens/listEquipmentDelivered.dart @@ -0,0 +1,228 @@ +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/screens/equipmentDetail.dart'; +import 'package:flutter/material.dart'; +import 'package:esms_project/electronic.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:intl/intl.dart'; + +class listEquipmentDelivered extends StatefulWidget { + @override + _listEquipmentDeliveredState createState() => _listEquipmentDeliveredState(); +} + +class _listEquipmentDeliveredState extends State { + final dbHandler dbh = dbHandler.instance; + Future loaded; + List> eqList; + + Future _loadvars() async { + dbh.queryAllEquipmentDelivered().then((value) { + eqList = value; + setState(() { + return true && eqList != null; + }); + }); + return false; + } + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + @override + void initState() { + super.initState(); + loaded = _loadvars(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Aparelhos Entregues"), + ), + body: _body(), + ); + } + + _body() { + return Container( + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) + return Center( + child: CircularProgressIndicator(), + ); + else if (eqList != null && eqList.length != 0) { + return ListView.separated( + padding: const EdgeInsets.all(8), + itemCount: eqList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + padding: const EdgeInsets.only(left: 10), + height: 90, + color: Colors.black12, + child: InkWell( + child: Center( + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: + "Aparelho: "+'${eqList[index]['equipment']}'))), + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Cliente: " + + '${eqList[index]['name']}'))), + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Entrada: " + + '${DateFormat.yMd().format(DateTime.tryParse(eqList[index]['dateInput']))}'))), + Expanded( + flex: 1, + child: RichText( + overflow: TextOverflow.ellipsis, + strutStyle: + StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Colors.black), + text: "Entrega: " + + '${DateFormat.yMd().format(DateTime.tryParse(eqList[index]['dateExit']))}'))) + ], + ), + ]), + ), + onTap: () => onPressWithArg( + context, + eqList[index]['id'], + ))); + }, + separatorBuilder: (BuildContext context, int index) => + const Divider()); + } else { + return Container( + child: Center( + child: Column( + children: [ + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "Estou vazio!"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: + "Nenhum aparelho entregue até o momento."), + ), + ]), + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "\nTente recarregar a tela."), + ), + Botoes( + "Recarregar", + onPressed: () => _update(context), + ) + ], + ), + ) + ], + ))); + } + }, + ), + ); + } + + _update(ctx) { + setState(() { + Navigator.pushReplacement( + ctx, MaterialPageRoute(builder: (context) => listEquipmentDelivered())); + }); + } + + // + void load(int arg) async { + Equipment t = new Equipment(0, "", "", "", DateTime.now()); + t = await t.LoadFromDB(arg); + } + + void onPressWithArg(ctx, int id) { + setState(() { + Navigator.of(ctx) + .push( + new MaterialPageRoute(builder: (context) => EquipmentDetail(id))) + .whenComplete(_loadvars); + }); + } +} diff --git a/lib/screens/listRepairs.dart b/lib/screens/listRepairs.dart new file mode 100644 index 0000000..f7c964b --- /dev/null +++ b/lib/screens/listRepairs.dart @@ -0,0 +1,260 @@ +import 'dart:async'; + +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/screens/equipmentDetail.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:esms_project/widgets/widget_input.dart'; +import 'package:flutter/material.dart'; + +import '../electronic.dart'; + +class ListRepairs extends StatefulWidget { + @override + _ListRepairsState createState() => _ListRepairsState(); +} + +class _ListRepairsState extends State { + final dbHandler dbh = dbHandler.instance; + Future loaded; + + List> repList; + Future _loadvars() async { + dbh.queryOrdered("v_repair", "ASC", "name").then((value) { + repList = value; + setState(() { + return true && repList != null; + }); + }); + return false; + } + @override + void setState(fn) { + if (mounted) { + super.setState(fn); + } + } + + @override + void initState() { + super.initState(); + loaded = _loadvars(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Exemplares de Consertos"), + actions: [ + IconButton(onPressed: (){ + showSearch(context: context, delegate: CustomSearch(type: 0, loadList: repList)); + }, icon: Icon(Icons.search)) + ], + ), + body: _body(), + ); + } + + _body() { + return Container( + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) + return Center( + child: CircularProgressIndicator(), + ); + else if (repList != null && repList.length != 0) { + return ListView.separated( + padding: const EdgeInsets.all(8), + itemCount: repList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + padding: const EdgeInsets.only(left: 10), + height: 90, + color: Colors.black12, + child: InkWell( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 18.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: "Aparelho: " + + '${repList[index]['name']}')), + ], + ), + Row( + children: [ + RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 18.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: "Reparo: " + + '${repList[index]['repair']}')) + ], + ) + ], + ), + onTap: () => onPressWithArg( + repList[index]['repair'],repList[index]['id'],repList[index]['repair_id']), + )); + }, + separatorBuilder: (BuildContext context, int index) => + const Divider()); + } else { + return Container( + child: Center( + child: Column( + children: [ + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RichText( + strutStyle: StrutStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 32.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "Nenhum reparo cadastrado."), + ), + RichText( + strutStyle: StrutStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic), + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26), + text: "\nTente recarregar a tela."), + ), + Botoes( + "Recarregar", + onPressed: () => _update(context), + ) + ], + ), + ) + ], + ))); + } + }, + ), + ); + } + + _update(BuildContext context) { + setState(() { + Navigator.of(context).popUntil((route) => route.isFirst); + Navigator.of(context).push(new MaterialPageRoute(builder: (context)=> ListRepairs())); + }); + } + + onPressWithArg(String rep, int id, int repid) { + setState(() { + _modalInput(rep, id, repid); + }); + } + + _modalInput(String repair, int eq, int rep) { + return showDialog( + context: context, + builder: (_) => SimpleDialog( + contentPadding: EdgeInsets.all(20), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Detalhes do Reparo"), + IconButton( + iconSize: 20, + onPressed: () { + Navigator.of(context, rootNavigator: true) + .pop('dialog'); + }, + icon: Icon(Icons.close)) + ], + ), + Divider(color: Colors.black38), + RichText( + strutStyle: StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle(color: Colors.black, fontSize: 20.0, fontWeight: FontWeight.w300), + text:repair)), + Divider(color: Colors.transparent), + Botoes( + "Ver Aparelho", + onPressed: () { + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) => EquipmentDetail(eq))) + .whenComplete(_loadvars); + }, + ), + Botoes( + "Remover Reparo", + onPressed: () { + _confirmDelete(rep); + }, + ) + ], + ) + ); + } + _confirmDelete(int id) + { + return showDialog( + context: context, + builder: (_) => SimpleDialog( + contentPadding: EdgeInsets.all(20), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Deseja remover o reparo?"), + IconButton( + iconSize: 20, + onPressed: () { + Navigator.of(context, rootNavigator: true) + .pop('dialog'); + }, + icon: Icon(Icons.close)) + ], + ), + Divider(color: Colors.black38), + Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Botoes("Sim", onPressed: (){ + Repair r = new Repair(0,"temp"); + r.RemoveDB(id); + setState(() { + _update(context); + }); + },), Botoes("Não", onPressed: (){ + Navigator.of(context, rootNavigator: true) + .pop('dialog'); + }) + ],) + ] + ) + ); + } +} diff --git a/lib/widgets/button_styles.dart b/lib/widgets/button_styles.dart new file mode 100644 index 0000000..91b77fa --- /dev/null +++ b/lib/widgets/button_styles.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class ButtonStyles { + + ButtonStyle btnS = ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + side: BorderSide(color: Colors.redAccent, width: 1.2))), + backgroundColor: MaterialStateProperty.all(Colors.redAccent[700]),); + TextStyle txS = TextStyle( + color: Colors.white, fontSize: 20, fontWeight: FontWeight.w400); +} diff --git a/lib/widgets/widget_button.dart b/lib/widgets/widget_button.dart new file mode 100644 index 0000000..5e413b1 --- /dev/null +++ b/lib/widgets/widget_button.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +import 'button_styles.dart'; +class Botoes extends StatelessWidget { + final String texto; + final Function onPressed; + Botoes(this.texto, {this.onPressed}); + @override + Widget build(BuildContext context) { + return ElevatedButton( + child:Text( + texto, + style: TextStyle( + fontSize: 20, + color: Colors.white, + ), + ), + onPressed: onPressed + ); + } +} + +class BotaoCustom extends StatelessWidget { + final String texto; + final Function onPressed; + BotaoCustom(this.texto, {this.onPressed}); + @override + Widget build(BuildContext context) { + return ElevatedButton( + style: ButtonStyles().btnS, + child:Text(texto, style: ButtonStyles().txS), + onPressed: onPressed + ); + } +} diff --git a/lib/widgets/widget_caroussel.dart b/lib/widgets/widget_caroussel.dart new file mode 100644 index 0000000..cef5535 --- /dev/null +++ b/lib/widgets/widget_caroussel.dart @@ -0,0 +1,80 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; +import 'package:path_provider/path_provider.dart'; +class Caroussel extends StatefulWidget { + List images; + String path; + List finalImg = List.empty(growable: true); + Caroussel(this.images); + @override + _CarousselState createState() => _CarousselState(); +} +class _CarousselState extends State { + Future loaded; + Future getPath() async{ + final directory = await getApplicationDocumentsDirectory().then((Directory value){ + widget.path = value.path; + }); + for (int i = 0; i < widget.images.length; i++) { + widget.finalImg.add(Image.file(File(widget.path+"/Pictures/"+widget.images[i].trimLeft()))); + } + return true && widget.path.isNotEmpty; + } + + @override + void initState() { + super.initState(); + loaded = getPath(); + } + + @override + void setState(fn) { + if(mounted) { + super.setState(fn); + } + } + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.all(10), + child: FutureBuilder( + future: loaded, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + widget.finalImg.length > 0) { + return + ListView.builder( + shrinkWrap: true, + physics: const ScrollPhysics(), + scrollDirection: Axis.horizontal, + itemCount: widget.finalImg.length, + itemBuilder: (BuildContext context, int index) + { + return Container( + margin: EdgeInsets.only(right:5), + child: widget.finalImg[index], + ); + }, + ); + } + return Center( + child: CircularProgressIndicator(), + ); + })); + } +} +/* +* +* Center( + child: ListView( + physics: const ScrollPhysics(), + scrollDirection: Axis.horizontal, + children: [ + for(int i = 0; i < widget.finalImg.length; i++) + widget.finalImg[i], + ], + ), + );*/ diff --git a/lib/widgets/widget_generate.dart b/lib/widgets/widget_generate.dart new file mode 100644 index 0000000..3eb7c00 --- /dev/null +++ b/lib/widgets/widget_generate.dart @@ -0,0 +1,9 @@ +import 'dart:math'; + +class StringGenerator{ + static const _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890'; + Random _rnd = Random(); + + String getRandomString(int length) => String.fromCharCodes(Iterable.generate( + length, (_) => _chars.codeUnitAt(_rnd.nextInt(_chars.length)))); +} \ No newline at end of file diff --git a/lib/widgets/widget_input.dart b/lib/widgets/widget_input.dart new file mode 100644 index 0000000..c301401 --- /dev/null +++ b/lib/widgets/widget_input.dart @@ -0,0 +1,441 @@ +import 'dart:async'; + +import 'package:esms_project/dbhandler.dart'; +import 'package:esms_project/screens/equipmentDetail.dart'; +import 'package:esms_project/widgets/widget_button.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:intl/intl.dart'; +class InputTextos extends StatelessWidget { + String rotulo, hint; + TextEditingController controller; + bool readonly; + InputTextos(this.rotulo,this.hint, {this.controller, this.readonly}); + + @override + Widget build(BuildContext context) { + return TextFormField( + readOnly: readonly == null ? false : readonly, + controller: controller, + style : TextStyle( + color: Colors.black, + backgroundColor: Colors.transparent + ), + decoration : InputDecoration( + labelText: rotulo, + hintText: hint + ) + ); + } +} + +class CustomSearch extends SearchDelegate{ + dbHandler dbh= dbHandler.instance; + List> loadList; + int type; + CustomSearch({this.type, this.loadList}); + @override + List buildActions(BuildContext context) { + return[ + IconButton(onPressed: (){ + query = ''; + }, icon: Icon(Icons.clear)) + ]; + } + @override + String get searchFieldLabel => "Pesquisar"; + + @override + ThemeData appBarTheme(BuildContext context) { + return ThemeData( + primaryColor: Colors.red, + inputDecorationTheme: InputDecorationTheme( + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.red[300]), + ), + focusedBorder: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.white), + ), + border: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.redAccent), + ), + hintStyle: TextStyle( + color: Colors.white, fontWeight: FontWeight.w400), + ), + textTheme: TextTheme(headline6: TextStyle( + color: Colors.white, fontWeight: FontWeight.w400),) + ); + } + + @override + Widget buildLeading(BuildContext context) { + return IconButton( + onPressed: (){ + close(context, null); + }, + icon: Icon(Icons.arrow_back) + ); + } + + @override + Widget buildResults(BuildContext context) { + List> searchList = List.empty(growable: true); + + if(query.length < 3) + { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Text( + "Termo deve ser maior que 2 letras.", + ), + ) + ], + ); + } + + for(int i = 0; i < loadList.length; i++) + { + switch(type) + { + case 0: + { + if(loadList[i]['name'].toUpperCase().contains(query.toUpperCase())){ + searchList.add(loadList[i]); + } + break; + } + case 1: + { + if(loadList[i]['equipment'].toUpperCase().contains(query.toUpperCase())){ + searchList.add(loadList[i]); + } + break; + } + default: + break; + } + } + + if(searchList != null){ + return ListView.separated( + padding: const EdgeInsets.all(8), + itemCount: searchList.length, + itemBuilder: (BuildContext context, int index) { + return Container( + padding: const EdgeInsets.only(left: 10), + height: 90, + color: Colors.black12, + child: InkWell( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 18.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: "Aparelho: " + + '${searchList[index]['name']}')), + ], + ), + Row( + children: [ + RichText( + overflow: TextOverflow.ellipsis, + strutStyle: StrutStyle(fontSize: 18.0), + text: TextSpan( + style: TextStyle( + color: Colors.black, + fontSize: 18.0), + text: "Reparo: " + + '${searchList[index]['repair']}')) + ], + ) + ], + ), + onTap: () => onPressWithArg( + searchList[index]['repair'],searchList[index]['id'],searchList[index]['repair_id'],context), + )); + }, + separatorBuilder: (BuildContext context, int index) => + const Divider()); + } + + return Container( + padding: EdgeInsets.only(left:10,right:10), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Text( + "Insira um termo de busca válido", + style: TextStyle( + fontSize: 26.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26) + ), + ), + Center( + child: Text( + "(Ex. Aparelho XYZ, João da Silva)", + style: TextStyle( + fontSize: 24.0, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.italic, + color: Colors.black26) + ), + ), + + ], + ) + ); + } + + @override + Widget buildSuggestions(BuildContext context) { + if(query.length < 3) + { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Text( + "Termo deve ser maior que 2 letras.", + ), + ) + ], + ); + } + return Column(); + } + onPressWithArg(String rep, int id, int repid, context) { + _modalInput(rep, id, repid, context); + } + + _modalInput(String repair, int eq, int rep, context) { + return showDialog( + context: context, + builder: (_) => SimpleDialog( + contentPadding: EdgeInsets.all(20), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Detalhes do Reparo"), + ], + ), + Divider(color: Colors.black38), + RichText( + strutStyle: StrutStyle(fontSize: 16.0), + text: TextSpan( + style: TextStyle(color: Colors.black, fontSize: 20.0, fontWeight: FontWeight.w300), + text:repair)), + Divider(color: Colors.transparent), + Botoes( + "Ver Aparelho", + onPressed: () { + Navigator.of(context) + .push(new MaterialPageRoute(builder: (context) => EquipmentDetail(eq))); + }, + ), + ], + ) + ); + } +} + +class InputData extends StatelessWidget { + String rotulo, hint; + TextEditingController controller; + InputData(this.rotulo,this.hint, {this.controller}); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: TextFormField( + readOnly: true, + keyboardType: TextInputType.datetime, + validator: (value){ + try{ + DateFormat.yMd().parseStrict(value); + } + on FormatException catch (_) + { + return 'Valor inválido'; + } + }, + controller: controller, + style : TextStyle( + color: Colors.black, + backgroundColor: Colors.transparent + ), + decoration : InputDecoration( + labelText: rotulo, + hintText: hint + ) + ), + ), + IconButton(icon: Icon(Icons.calendar_today), onPressed: (){ + Future tmp = _showCalendar(context); + tmp.then((DateTime res){ + controller.text = DateFormat.yMd().format(res); + }); + }) + ], + ); + } + _showCalendar(context) + { + return showDatePicker( + context: context, + initialDate: DateTime.now(), firstDate: DateTime.now(), lastDate: DateTime(2050) + + ); + } +} + +class InputDataNoValidate extends StatelessWidget { + String rotulo, hint; + bool readonly; + TextEditingController controller; + InputDataNoValidate(this.rotulo,this.hint, {this.controller, this.readonly}); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: TextFormField( + readOnly: readonly == null ? false : readonly, + keyboardType: TextInputType.datetime, + validator: (value) { + if (value.isNotEmpty) + { + try{ + DateFormat.yMd().parseStrict(value); + } + on FormatException catch (_) + { + return 'Valor inválido'; + } + } + }, + controller: controller, + style : TextStyle( + color: Colors.black, + backgroundColor: Colors.transparent + ), + decoration : InputDecoration( + labelText: rotulo, + hintText: hint + ) + ), + ), + IconButton(icon: Icon(Icons.calendar_today), onPressed: (){ + Future tmp = _showCalendar(context); + tmp.then((DateTime res){ + controller.text = DateFormat.yMd().format(res); + }); + }) + ], + ); + } + _showCalendar(context) + { + return showDatePicker( + context: context, + initialDate: DateTime.now(), firstDate: DateTime.now(), lastDate: DateTime(2050) + + ); + } +} + +class InputValidado extends StatelessWidget { + String rotulo, hint; + TextEditingController controller; + bool readonly; + InputValidado(this.rotulo,this.hint, {this.controller, this.readonly}); + + @override + Widget build(BuildContext context) { + return TextFormField( + validator: (value){ + if(value.isEmpty) + return 'Preencha o valor'; + }, + readOnly: readonly == null ? false : readonly, + controller: controller, + style : TextStyle( + color: Colors.black, + backgroundColor: Colors.transparent + ), + decoration : InputDecoration( + labelText: rotulo, + hintText: hint + ) + ); + } +} + +class InputNumber extends StatelessWidget { + String rotulo, hint; + TextEditingController controller; + bool readonly; + InputNumber(this.rotulo,this.hint, {this.controller, this.readonly}); + + @override + Widget build(BuildContext context) { + return TextFormField( + validator: (value){ + if(int.tryParse(value) == null) + return 'Valor inválido'; + }, + keyboardType: TextInputType.number, + readOnly: readonly == null ? false : readonly, + controller: controller, + style : TextStyle( + color: Colors.black, + backgroundColor: Colors.transparent + ), + decoration : InputDecoration( + labelText: rotulo, + hintText: hint + ) + ); + } +} + +class InputTextosPhone extends StatelessWidget { + String rotulo, hint; + TextEditingController controller; + + InputTextosPhone(this.rotulo,this.hint, {this.controller}); + + @override + Widget build(BuildContext context) { + return TextFormField( + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'\+|\(|\)|\d|\s|\-')) + ], + keyboardType: TextInputType.phone, + controller: controller, + style : TextStyle( + color: Colors.black, + backgroundColor: Colors.transparent + ), + decoration : InputDecoration( + labelText: rotulo, + hintText: hint + ) + ); + } +} diff --git a/local.properties b/local.properties new file mode 100644 index 0000000..18ee7f5 --- /dev/null +++ b/local.properties @@ -0,0 +1,8 @@ +## This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Wed May 19 10:59:50 BRT 2021 +sdk.dir=D\:\\AndroidSDK diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..155268e --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,411 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.3" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + image_picker: + dependency: "direct main" + description: + name: image_picker + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.0+3" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.10" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + package_info_plus_linux: + dependency: transitive + description: + name: package_info_plus_linux + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + package_info_plus_macos: + dependency: transitive + description: + name: package_info_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + package_info_plus_web: + dependency: transitive + description: + name: package_info_plus_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + package_info_plus_windows: + dependency: transitive + description: + name: package_info_plus_windows + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + path: + dependency: "direct main" + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + path_provider: + dependency: "direct main" + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + sqflite: + dependency: "direct main" + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0+3" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0+2" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.6" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" +sdks: + dart: ">=2.13.0 <3.0.0" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..0676a5a --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,84 @@ +name: esms_project +description: Sistema de Registro e Ordem de Serviço + +# The following line prevents the package from being accidentally published to +# pub.dev using `pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.1+6 + +environment: + sdk: ">=2.7.0 <3.0.0" + +dependencies: + image_picker: ^0.8.0+3 + http: ^0.13.3 + path: ^1.8.0 + path_provider: ^2.0.1 + package_info_plus: ^1.0.2 + sqflite: ^2.0.0+3 + intl: ^0.17.0 + url_launcher: ^6.0.3 + flutter: + sdk: flutter + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/web/favicon.png differ diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/web/icons/Icon-192.png differ diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/web/icons/Icon-512.png differ diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..8642323 --- /dev/null +++ b/web/index.html @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + esms_project + + + + + + + diff --git a/web/manifest.json b/web/manifest.json new file mode 100644 index 0000000..4d5f985 --- /dev/null +++ b/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "esms_project", + "short_name": "esms_project", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "Sistema de Registro e Ordem de Serviço", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +}