diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..437cb45 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Exceptions to above rules. +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..bc6383a --- /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: cc3ca9a916cb1da851a1f36432154a534787da99 + channel: master + +project_type: app diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3287bb6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,13 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Flutter", + "request": "launch", + "type": "dart" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1d98db0 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# space + +Dream Job Application + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..bc2100d --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,7 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..0059a28 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,72 @@ +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 28 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "id.dreamjob.space" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + 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 '../..' +} + +apply plugin: 'com.android.application' + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + implementation 'com.google.firebase:firebase-analytics:17.2.0' +} + +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..0ef02f0 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,40 @@ +{ + "project_info": { + "project_number": "14225204287", + "firebase_url": "https://dreamjob-id.firebaseio.com", + "project_id": "dreamjob-id", + "storage_bucket": "dreamjob-id.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:14225204287:android:827ec48efa274b1828048a", + "android_client_info": { + "package_name": "id.dreamjob.space" + } + }, + "oauth_client": [ + { + "client_id": "14225204287-en96jgf210iiujr92vl01499pq4kkfq1.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDw_vdMGcLGlBmVLNzTqqJArV-CApB-ALE" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "14225204287-en96jgf210iiujr92vl01499pq4kkfq1.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..47f436f --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..383f8bc --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/id/dreamjob/space/MainActivity.kt b/android/app/src/main/kotlin/id/dreamjob/space/MainActivity.kt new file mode 100644 index 0000000..4a5dd3c --- /dev/null +++ b/android/app/src/main/kotlin/id/dreamjob/space/MainActivity.kt @@ -0,0 +1,13 @@ +package id.dreamjob.space + +import android.os.Bundle + +import io.flutter.app.FlutterActivity +import io.flutter.plugins.GeneratedPluginRegistrant + +class MainActivity: FlutterActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + GeneratedPluginRegistrant.registerWith(this) + } +} 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-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 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-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 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-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 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-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d 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-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e 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/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..00fa441 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..47f436f --- /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..7536a39 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,32 @@ +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.gms:google-services:4.2.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + 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..38c8d45 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +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..296b146 --- /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-5.6.2-all.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..5a2f14f --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/assets/background-1.png b/assets/background-1.png new file mode 100644 index 0000000..feace47 Binary files /dev/null and b/assets/background-1.png differ diff --git a/assets/background-2.png b/assets/background-2.png new file mode 100644 index 0000000..a3507e9 Binary files /dev/null and b/assets/background-2.png differ diff --git a/assets/blog.png b/assets/blog.png new file mode 100644 index 0000000..0753bfd Binary files /dev/null and b/assets/blog.png differ diff --git a/assets/ellipse_1.png b/assets/ellipse_1.png new file mode 100644 index 0000000..fc1ad2e Binary files /dev/null and b/assets/ellipse_1.png differ diff --git a/assets/ellipse_2.png b/assets/ellipse_2.png new file mode 100644 index 0000000..cb2bf2a Binary files /dev/null and b/assets/ellipse_2.png differ diff --git a/assets/gmail.png b/assets/gmail.png new file mode 100644 index 0000000..e9969bc Binary files /dev/null and b/assets/gmail.png differ diff --git a/assets/grunge.png b/assets/grunge.png new file mode 100644 index 0000000..b86676b Binary files /dev/null and b/assets/grunge.png differ diff --git a/assets/home.png b/assets/home.png new file mode 100644 index 0000000..ca6a54a Binary files /dev/null and b/assets/home.png differ diff --git a/assets/icon1.png b/assets/icon1.png new file mode 100644 index 0000000..2d9ec2c Binary files /dev/null and b/assets/icon1.png differ diff --git a/assets/icon10.png b/assets/icon10.png new file mode 100644 index 0000000..864c029 Binary files /dev/null and b/assets/icon10.png differ diff --git a/assets/icon11.png b/assets/icon11.png new file mode 100644 index 0000000..a5d2ac0 Binary files /dev/null and b/assets/icon11.png differ diff --git a/assets/icon12.png b/assets/icon12.png new file mode 100644 index 0000000..ad1a208 Binary files /dev/null and b/assets/icon12.png differ diff --git a/assets/icon13.png b/assets/icon13.png new file mode 100644 index 0000000..879099d Binary files /dev/null and b/assets/icon13.png differ diff --git a/assets/icon14.png b/assets/icon14.png new file mode 100644 index 0000000..b1bc517 Binary files /dev/null and b/assets/icon14.png differ diff --git a/assets/icon15.png b/assets/icon15.png new file mode 100644 index 0000000..412de28 Binary files /dev/null and b/assets/icon15.png differ diff --git a/assets/icon16.png b/assets/icon16.png new file mode 100644 index 0000000..8586814 Binary files /dev/null and b/assets/icon16.png differ diff --git a/assets/icon2.png b/assets/icon2.png new file mode 100644 index 0000000..10666a9 Binary files /dev/null and b/assets/icon2.png differ diff --git a/assets/icon3.png b/assets/icon3.png new file mode 100644 index 0000000..ce232c5 Binary files /dev/null and b/assets/icon3.png differ diff --git a/assets/icon4.png b/assets/icon4.png new file mode 100644 index 0000000..09487ae Binary files /dev/null and b/assets/icon4.png differ diff --git a/assets/icon5.png b/assets/icon5.png new file mode 100644 index 0000000..7a74920 Binary files /dev/null and b/assets/icon5.png differ diff --git a/assets/icon6.png b/assets/icon6.png new file mode 100644 index 0000000..f49f2f4 Binary files /dev/null and b/assets/icon6.png differ diff --git a/assets/icon7.png b/assets/icon7.png new file mode 100644 index 0000000..18976bb Binary files /dev/null and b/assets/icon7.png differ diff --git a/assets/icon8.png b/assets/icon8.png new file mode 100644 index 0000000..e422dea Binary files /dev/null and b/assets/icon8.png differ diff --git a/assets/icon9.png b/assets/icon9.png new file mode 100644 index 0000000..ee40493 Binary files /dev/null and b/assets/icon9.png differ diff --git a/assets/img_profil.png b/assets/img_profil.png new file mode 100644 index 0000000..bef2021 Binary files /dev/null and b/assets/img_profil.png differ diff --git a/assets/img_profil_2.png b/assets/img_profil_2.png new file mode 100644 index 0000000..2f4a16e Binary files /dev/null and b/assets/img_profil_2.png differ diff --git a/assets/img_profil_3.png b/assets/img_profil_3.png new file mode 100644 index 0000000..a25947a Binary files /dev/null and b/assets/img_profil_3.png differ diff --git a/assets/img_profil_4.png b/assets/img_profil_4.png new file mode 100644 index 0000000..7711758 Binary files /dev/null and b/assets/img_profil_4.png differ diff --git a/assets/img_profile-1.png b/assets/img_profile-1.png new file mode 100644 index 0000000..3c86db3 Binary files /dev/null and b/assets/img_profile-1.png differ diff --git a/assets/img_profile-2.png b/assets/img_profile-2.png new file mode 100644 index 0000000..4e8711f Binary files /dev/null and b/assets/img_profile-2.png differ diff --git a/assets/job.png b/assets/job.png new file mode 100644 index 0000000..93f347d Binary files /dev/null and b/assets/job.png differ diff --git a/assets/job2.png b/assets/job2.png new file mode 100644 index 0000000..3190260 Binary files /dev/null and b/assets/job2.png differ diff --git a/assets/ketapang.png b/assets/ketapang.png new file mode 100644 index 0000000..5106778 Binary files /dev/null and b/assets/ketapang.png differ diff --git a/assets/logo-hitam.png b/assets/logo-hitam.png new file mode 100644 index 0000000..b3b41c0 Binary files /dev/null and b/assets/logo-hitam.png differ diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000..119e397 Binary files /dev/null and b/assets/logo.png differ diff --git a/assets/logo_vertical.png b/assets/logo_vertical.png new file mode 100644 index 0000000..34fe5be Binary files /dev/null and b/assets/logo_vertical.png differ diff --git a/assets/mekuru.png b/assets/mekuru.png new file mode 100644 index 0000000..2782eb0 Binary files /dev/null and b/assets/mekuru.png differ diff --git a/assets/mekuru_2.png b/assets/mekuru_2.png new file mode 100644 index 0000000..1f77e83 Binary files /dev/null and b/assets/mekuru_2.png differ diff --git a/assets/nav_astro.png b/assets/nav_astro.png new file mode 100644 index 0000000..920069d Binary files /dev/null and b/assets/nav_astro.png differ diff --git a/assets/recent_job.png b/assets/recent_job.png new file mode 100644 index 0000000..e26f408 Binary files /dev/null and b/assets/recent_job.png differ diff --git a/assets/space_demo.flr b/assets/space_demo.flr new file mode 100644 index 0000000..fc32027 Binary files /dev/null and b/assets/space_demo.flr differ diff --git a/assets/up2u.png b/assets/up2u.png new file mode 100644 index 0000000..52825b8 Binary files /dev/null and b/assets/up2u.png differ diff --git a/assets/vector-1.png b/assets/vector-1.png new file mode 100644 index 0000000..5a1b5ac Binary files /dev/null and b/assets/vector-1.png differ diff --git a/assets/vector-10.png b/assets/vector-10.png new file mode 100644 index 0000000..61bebde Binary files /dev/null and b/assets/vector-10.png differ diff --git a/assets/vector-11.png b/assets/vector-11.png new file mode 100644 index 0000000..d725c1f Binary files /dev/null and b/assets/vector-11.png differ diff --git a/assets/vector-12.png b/assets/vector-12.png new file mode 100644 index 0000000..c5e2bf2 Binary files /dev/null and b/assets/vector-12.png differ diff --git a/assets/vector-13.png b/assets/vector-13.png new file mode 100644 index 0000000..3f676a5 Binary files /dev/null and b/assets/vector-13.png differ diff --git a/assets/vector-14.png b/assets/vector-14.png new file mode 100644 index 0000000..bd6fa7f Binary files /dev/null and b/assets/vector-14.png differ diff --git a/assets/vector-15.png b/assets/vector-15.png new file mode 100644 index 0000000..e60171e Binary files /dev/null and b/assets/vector-15.png differ diff --git a/assets/vector-16.png b/assets/vector-16.png new file mode 100644 index 0000000..5e912b6 Binary files /dev/null and b/assets/vector-16.png differ diff --git a/assets/vector-2.png b/assets/vector-2.png new file mode 100644 index 0000000..161147a Binary files /dev/null and b/assets/vector-2.png differ diff --git a/assets/vector-3.png b/assets/vector-3.png new file mode 100644 index 0000000..d00c740 Binary files /dev/null and b/assets/vector-3.png differ diff --git a/assets/vector-4.png b/assets/vector-4.png new file mode 100644 index 0000000..0b4a139 Binary files /dev/null and b/assets/vector-4.png differ diff --git a/assets/vector-5.png b/assets/vector-5.png new file mode 100644 index 0000000..1bb3f1c Binary files /dev/null and b/assets/vector-5.png differ diff --git a/assets/vector-6.png b/assets/vector-6.png new file mode 100644 index 0000000..aa70500 Binary files /dev/null and b/assets/vector-6.png differ diff --git a/assets/vector-7.png b/assets/vector-7.png new file mode 100644 index 0000000..93da4d4 Binary files /dev/null and b/assets/vector-7.png differ diff --git a/assets/vector-8.png b/assets/vector-8.png new file mode 100644 index 0000000..04406b8 Binary files /dev/null and b/assets/vector-8.png differ diff --git a/assets/vector-9.png b/assets/vector-9.png new file mode 100644 index 0000000..4b075e3 Binary files /dev/null and b/assets/vector-9.png differ diff --git a/fonts/Cocogoose.ttf b/fonts/Cocogoose.ttf new file mode 100644 index 0000000..6d4bf8c Binary files /dev/null and b/fonts/Cocogoose.ttf differ diff --git a/fonts/Quicksand-Bold.ttf b/fonts/Quicksand-Bold.ttf new file mode 100644 index 0000000..84359a0 Binary files /dev/null and b/fonts/Quicksand-Bold.ttf differ diff --git a/fonts/Quicksand-Regular.ttf b/fonts/Quicksand-Regular.ttf new file mode 100644 index 0000000..a11f89e Binary files /dev/null and b/fonts/Quicksand-Regular.ttf differ diff --git a/fonts/Quicksand-SemiBold.ttf b/fonts/Quicksand-SemiBold.ttf new file mode 100644 index 0000000..f4e03fd Binary files /dev/null and b/fonts/Quicksand-SemiBold.ttf differ diff --git a/fonts/TitilliumWeb-Bold.ttf b/fonts/TitilliumWeb-Bold.ttf new file mode 100644 index 0000000..ec5b093 Binary files /dev/null and b/fonts/TitilliumWeb-Bold.ttf differ diff --git a/fonts/TitilliumWeb-Regular.ttf b/fonts/TitilliumWeb-Regular.ttf new file mode 100644 index 0000000..a54ad4b Binary files /dev/null and b/fonts/TitilliumWeb-Regular.ttf differ diff --git a/fonts/VarelaRound.ttf b/fonts/VarelaRound.ttf new file mode 100644 index 0000000..bd68d51 Binary files /dev/null and b/fonts/VarelaRound.ttf differ diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..f78c148 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,31 @@ +*.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/Generated.xcconfig +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..6b4c0f7 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + 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..24075cb --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,519 @@ +// !$*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 */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 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 = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + 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 = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; 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 = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 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 = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + 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 = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 0910; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + 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\" 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 = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift 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; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + 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 = 8.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; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = id.dreamjob.space; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 4.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = id.dreamjob.space; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = id.dreamjob.space; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 4.0; + 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..1d526a1 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + 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/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} 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..dd47388 --- /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 + space + 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/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..7335fdf --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/lib/employer_app.dart b/lib/employer_app.dart new file mode 100644 index 0000000..f40b7dc --- /dev/null +++ b/lib/employer_app.dart @@ -0,0 +1,64 @@ +// import 'package:flutter/material.dart'; +// import 'package:provider/provider.dart'; +// import 'package:space/app.dart'; +// import 'package:space/main.dart'; +// import 'package:space/navigator_employer.dart'; +// import 'package:space/src/core/models/auth.dart'; + +// import 'package:space/src/core/models/jobs.dart'; +// import 'package:space/src/core/models/save.dart'; +// import 'package:space/src/ui/auth/employer/home_employer.dart'; +// import 'package:space/src/ui/employer/employer_edit_post.dart'; +// import 'package:space/src/ui/employer/employer_tabs.dart'; +// import 'package:space/src/ui/employer/employer_post_a_job.dart'; +// import 'package:space/src/ui/screens/splash_screen.dart'; + +// import 'package:space/src/ui/theme/theme.dart'; + +// void main() => runApp(EmployerApp()); + +// class EmployerApp extends StatelessWidget { +// @override +// Widget build(BuildContext context) { +// final theme = buildTheme(); +// return MultiProvider( +// providers: [ +// ChangeNotifierProvider.value( +// value: Auth(), +// ), +// ChangeNotifierProxyProvider( +// builder: (ctx, auth, previousJobs) =>Jobs( +// auth.token, +// auth.userId, +// previousJobs == null ? [] : previousJobs.posts, +// ), +// ), +// ChangeNotifierProvider.value( +// value: Save(), +// ) +// ], +// child: Consumer( +// builder: (ctx, auth, _) => MaterialApp( +// debugShowCheckedModeBanner: false, +// theme: theme, +// home: auth.isAuth +// ? EmployerNavigator() +// : FutureBuilder( +// future: auth.tryAutoLogin(), +// builder: (ctx, authResultSnapshot) => +// authResultSnapshot.connectionState == +// ConnectionState.waiting +// ? SplashScreen() +// : DreamApp(), +// ), +// routes: { +// HomePageEmployer.routeName: (ctx) => HomePageEmployer(), +// EmployerTabs.routeName: (ctx) => EmployerTabs(), +// PostaJob.routeName: (ctx) => PostaJob(), +// EditPost.routeName: (ctx) => EditPost(), +// }, +// ), +// ), +// ); +// } +// } diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..141d390 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:space/navigator_seeker.dart'; +import 'package:space/src/core/models/apply.dart'; +import 'package:space/src/core/models/auth.dart'; +import 'package:space/src/core/models/cart.dart'; + +import 'package:space/src/core/models/jobs.dart'; +import 'package:space/src/ui/auth/employer/home_employer.dart'; +import 'package:space/src/ui/auth/employer/login_signup_employer.dart'; +import 'package:space/src/ui/auth/seeker/home_seeker.dart'; +import 'package:space/src/ui/employer/layout/employer_edit_post.dart'; +import 'package:space/src/ui/employer/screens/employer_posted_screen.dart'; +import 'package:space/src/ui/employer/screens/employer_tabs.dart'; +import 'package:space/src/ui/seeker/layout/job_details.dart'; +import 'package:space/src/ui/seeker/screens/applys_screen.dart'; +import 'package:space/src/ui/seeker/screens/cart_screen.dart'; +import 'package:space/src/ui/seeker/screens/seeker_tabs.dart'; +import 'package:space/src/ui/components/splash_screen.dart'; + +import 'package:space/src/ui/theme/theme.dart'; + +void main() => runApp(DreamJobApp()); + +class DreamJobApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + final theme = buildTheme(); + return MultiProvider( + providers: [ + ChangeNotifierProvider.value( + value: Auth(), + ), + ChangeNotifierProxyProvider( + builder: (ctx, auth, previousJobs) => Jobs( + auth.token, + auth.userId, + previousJobs == null ? [] : previousJobs.posts, + ), + ), + // ChangeNotifierProvider.value( + // value: Save(), + // ) + ChangeNotifierProxyProvider( + builder: (ctx, auth, previousApplys) => Applys( + auth.token, + auth.userId, + previousApplys == null ? [] : previousApplys.applys, + ), + ), + ChangeNotifierProvider.value( + value: Cart(), + ), + ], + child: Consumer( + builder: (ctx, auth, _) => MaterialApp( + debugShowCheckedModeBanner: false, + theme: theme, + home: auth.isAuth + ? SeekerNavigator() + : FutureBuilder( + future: auth.tryAutoLogin(), + builder: (ctx, authResultSnapshot) => + authResultSnapshot.connectionState == + ConnectionState.waiting + ? SplashScreen() + : LoginSignUpEmployer(), + ), + routes: { + HomePageEmployer.routeName: (ctx) => HomePageEmployer(), + EmployerTabs.routeName: (ctx) => EmployerTabs(), + EmployerPostScreen.routeName: (ctx) => EmployerPostScreen(), + EditPost.routeName: (ctx) => EditPost(), + + HomePageSeeker.routeName: (ctx) => HomePageSeeker(), + JobDetails.routeName: (ctx) => JobDetails(), + // SaveScreen.routeName: (ctx) => SaveScreen(), + SeekerTabs.routeName: (ctx) => SeekerTabs(), + CartScreen.routeName: (ctx) => CartScreen(), + ApplysScreen.routeName: (ctx) => ApplysScreen(), + }, + ), + ), + ); + } +} diff --git a/lib/main1.dart b/lib/main1.dart new file mode 100644 index 0000000..3a6238c --- /dev/null +++ b/lib/main1.dart @@ -0,0 +1,22 @@ +// import 'package:flutter/material.dart'; +// import 'package:provider/provider.dart'; +// import 'package:space/app.dart'; +// import 'package:space/navigator_employer.dart'; +// import 'package:space/navigator_seeker.dart'; +// import 'package:space/src/core/models/auth.dart'; + +// import 'package:space/src/core/models/jobs.dart'; +// import 'package:space/src/core/models/save.dart'; +// import 'package:space/src/ui/auth/employer/home_employer.dart'; +// import 'package:space/src/ui/auth/seeker/home_seeker.dart'; +// import 'package:space/src/ui/employer/employer_edit_post.dart'; +// import 'package:space/src/ui/employer/employer_tabs.dart'; +// import 'package:space/src/ui/employer/employer_post_a_job.dart'; +// import 'package:space/src/ui/screens/job_details.dart'; +// import 'package:space/src/ui/screens/save_screen.dart'; +// import 'package:space/src/ui/screens/seeker_tabs.dart'; +// import 'package:space/src/ui/screens/splash_screen.dart'; + +// import 'package:space/src/ui/theme/theme.dart'; + +// void main() => runApp(DreamApp()); diff --git a/lib/navigator_employer.dart b/lib/navigator_employer.dart new file mode 100644 index 0000000..d284d27 --- /dev/null +++ b/lib/navigator_employer.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:flutter/services.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:space/src/ui/auth/employer/home_employer.dart'; +import 'package:space/src/ui/chat/inbox_ui_list.dart'; +import 'package:space/src/ui/components/landing_404_page.dart'; +import 'package:space/src/ui/employer/screens/employer_tabs.dart'; + +class EmployerNavigator extends StatefulWidget { + @override + _EmployerNavigatorState createState() => _EmployerNavigatorState(); +} + +class _EmployerNavigatorState extends State { + int _selectedIndex = 0; + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } + + final List _children = [ + HomePageEmployer(), + EmployerTabs(), + LandingErrorPage(), + InboxUiList(), + InboxUiList(), + ]; + @override + Widget build(BuildContext context) { + SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarBrightness: Brightness.dark, + statusBarIconBrightness: Brightness.dark, + systemNavigationBarIconBrightness: Brightness.dark, + systemNavigationBarColor: Colors.transparent, + )); + return Scaffold( + body: _children[_selectedIndex], + bottomNavigationBar: BottomNavigationBar( + unselectedItemColor: Color(0xff0c0c0c0), + showUnselectedLabels: true, + items: const [ + BottomNavigationBarItem( + icon: Icon(FeatherIcons.home, size: 24), + title: Text('HOME', + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(MdiIcons.accountBadgeHorizontalOutline, size: 24), + title: Text('APPLICANTS', + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(MdiIcons.accountSearchOutline, size: 24), + title: Text('SEARCH', + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.messageSquare, size: 24), + title: Text('INBOX', + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.bell, size: 24), + title: Text('NOTIFICATION', + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + ], + currentIndex: _selectedIndex, + selectedItemColor: Color(0xff4d4d4d), + onTap: _onItemTapped, + ), + ); + } +} diff --git a/lib/navigator_seeker.dart b/lib/navigator_seeker.dart new file mode 100644 index 0000000..9ddb0d3 --- /dev/null +++ b/lib/navigator_seeker.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:flutter/services.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:space/src/ui/auth/seeker/home_seeker.dart'; +import 'package:space/src/ui/chat/inbox_ui_list.dart'; +import 'package:space/src/ui/seeker/layout/job_search.dart'; +import 'package:space/src/ui/seeker/screens/seeker_tabs.dart'; + +class SeekerNavigator extends StatefulWidget { + @override + _SeekerNavigatorState createState() => _SeekerNavigatorState(); +} + +class _SeekerNavigatorState extends State { + int _selectedIndex = 0; + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } + + final List _children = [ + HomePageSeeker(), + SeekerTabs(), + JobSearch(), + InboxUiList(), + InboxUiList(), + ]; + @override + Widget build(BuildContext context) { + SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarBrightness: Brightness.dark, + statusBarIconBrightness: Brightness.dark, + systemNavigationBarIconBrightness: Brightness.dark, + systemNavigationBarColor: Colors.transparent, + )); + return Scaffold( + body: _children[_selectedIndex], + bottomNavigationBar: BottomNavigationBar( + unselectedItemColor: Color(0xff0c0c0c0), + showUnselectedLabels: true, + items: const [ + BottomNavigationBarItem( + icon: Icon(FeatherIcons.home, size: 24), + title: Text('HOME', + style: TextStyle( + height: 1.5, + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.briefcase, size: 24), + title: Text('JOBS', + style: TextStyle( + height: 1.5, + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(MdiIcons.fileDocumentBoxSearchOutline, size: 24), + title: Text('SEARCH', + style: TextStyle( + height: 1.5, + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.messageSquare, size: 24), + title: Text('INBOX', + style: TextStyle( + height: 1.5, + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.bell, size: 24), + title: Text('NOTIFICATION', + style: TextStyle( + height: 1.5, + fontFamily: 'VarelaRound', + fontSize: 8, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal)), + ), + ], + currentIndex: _selectedIndex, + selectedItemColor: Theme.of(context).colorScheme.onPrimary, + onTap: _onItemTapped, + ), + ); + } +} diff --git a/lib/root.dart b/lib/root.dart new file mode 100644 index 0000000..d965923 --- /dev/null +++ b/lib/root.dart @@ -0,0 +1,19 @@ +// import 'package:flutter/material.dart'; + +// import 'package:space/src/ui/screens/job_details.dart'; +// import 'package:space/src/ui/screens/save_screen.dart'; + +// class Root extends StatefulWidget { +// Root({Key key}) : super(key: key); + +// _RootState createState() => _RootState(); +// } + +// class _RootState extends State { +// @override +// Widget build(BuildContext context) { +// return +// ); +// } +// } + diff --git a/lib/routes.dart b/lib/routes.dart new file mode 100644 index 0000000..b506926 --- /dev/null +++ b/lib/routes.dart @@ -0,0 +1,45 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'package:provider/provider.dart'; + +// import 'package:space/root.dart'; +// import 'package:space/src/core/models/jobs.dart'; +// import 'package:space/src/core/models/save.dart'; +// import 'package:space/src/ui/screens/job_details.dart'; +// import 'package:space/src/ui/screens/save_screen.dart'; +// import 'package:space/src/ui/screens/seeker_tabs.dart'; +// import 'package:space/src/ui/theme/theme.dart'; + +// class Routes extends StatelessWidget { + +// @override +// Widget build(BuildContext context) { +// final theme = buildTheme(); +// SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( +// statusBarColor: Colors.black, +// statusBarBrightness: Brightness.dark, +// statusBarIconBrightness: Brightness.dark, +// systemNavigationBarIconBrightness: Brightness.dark, +// systemNavigationBarColor: Colors.transparent, +// )); +// return MultiProvider( +// providers: [ +// ChangeNotifierProvider.value( +// value: Jobs(), +// ), +// ChangeNotifierProvider.value( +// value: Save(), +// ) +// ], +// child: MaterialApp( +// debugShowCheckedModeBanner: false, +// theme: theme, +// home: SeekerTabs(), +// routes: { +// JobDetails.routeName: (ctx) => JobDetails(), +// SaveScreen.routeName: (ctx) => SaveScreen(), +// }, +// ) +// ); +// } +// } \ No newline at end of file diff --git a/lib/seeker_app.dart b/lib/seeker_app.dart new file mode 100644 index 0000000..0fbe129 --- /dev/null +++ b/lib/seeker_app.dart @@ -0,0 +1,61 @@ +// import 'package:flutter/material.dart'; +// import 'package:provider/provider.dart'; +// import 'package:space/main.dart'; +// import 'package:space/navigator_seeker.dart'; +// import 'package:space/src/core/models/auth.dart'; + +// import 'package:space/src/core/models/jobs.dart'; +// import 'package:space/src/core/models/save.dart'; +// import 'package:space/src/ui/auth/seeker/home_seeker.dart'; +// import 'package:space/src/ui/screens/job_details.dart'; +// import 'package:space/src/ui/screens/save_screen.dart'; +// import 'package:space/src/ui/screens/seeker_tabs.dart'; +// import 'package:space/src/ui/screens/splash_screen.dart'; + +// import 'package:space/src/ui/theme/theme.dart'; + +// class SeekerApp extends StatelessWidget { +// @override +// Widget build(BuildContext context) { +// final theme = buildTheme(); +// return MultiProvider( +// providers: [ +// ChangeNotifierProvider.value( +// value: Auth(), +// ), +// ChangeNotifierProxyProvider( +// builder: (ctx, auth, previousJobs) =>Jobs( +// auth.token, +// auth.userId, +// previousJobs == null ? [] : previousJobs.posts, +// ), +// ), +// ChangeNotifierProvider.value( +// value: Save(), +// ) +// ], +// child: Consumer( +// builder: (ctx, auth, _) => MaterialApp( +// debugShowCheckedModeBanner: false, +// theme: theme, +// home: auth.isAuth +// ? SeekerNavigator() +// : FutureBuilder( +// future: auth.tryAutoLogin(), +// builder: (ctx, authResultSnapshot) => +// authResultSnapshot.connectionState == +// ConnectionState.waiting +// ? SplashScreen() +// : DreamApp(), +// ), +// routes: { +// HomePageSeeker.routeName: (ctx) => HomePageSeeker(), +// JobDetails.routeName: (ctx) => JobDetails(), +// SaveScreen.routeName: (ctx) => SaveScreen(), +// SeekerTabs.routeName: (ctx) => SeekerTabs(), +// }, +// ), +// ), +// ); +// } +// } diff --git a/lib/src/app.dart b/lib/src/app.dart new file mode 100644 index 0000000..924e15c --- /dev/null +++ b/lib/src/app.dart @@ -0,0 +1,120 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'package:space/employer_app.dart'; +// import 'package:space/seeker_app.dart'; +// import 'package:space/src/ui/auth/employer/login_signup_employer.dart'; +// import 'package:space/src/ui/auth/seeker/login_signup_seeker.dart'; + +// class DreamApp extends StatelessWidget { +// @override +// Widget build(BuildContext context) { +// SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( +// statusBarColor: Colors.transparent, +// statusBarBrightness: Brightness.light, +// statusBarIconBrightness: Brightness.light, +// systemNavigationBarIconBrightness: Brightness.light, +// systemNavigationBarColor: Colors.black, +// )); +// return Material( +// child: Container( +// decoration: BoxDecoration( +// image: DecorationImage( +// fit: BoxFit.cover, +// image: AssetImage('assets/vector-5.png', ), +// ), +// ), +// child: Stack(children: [ +// Padding( +// padding: EdgeInsets.only(top: 50, right: 30), +// child: Stack( +// alignment: Alignment.topRight, +// children: [ +// Align( +// alignment: Alignment.topRight, +// child: Image.asset('assets/vector-11.png', scale: 1.4,)), +// Align( +// alignment: Alignment(0.6, -0.8), +// child: Image.asset('assets/vector-12.png', scale: 1.5,)), +// Align( +// alignment: Alignment(0.7, -0.5), +// child: Image.asset('assets/vector-13.png', scale: 1.5,)), +// Align( +// alignment: Alignment(0.2, -0.4), +// child: Image.asset('assets/vector-14.png', scale: 1.5,)), +// ], +// ), +// ), +// Stack( +// children:[ +// Align( +// alignment: Alignment(-0.8, 0.2), +// child: Image.asset('assets/vector-16.png', scale: 1.5,)), +// Align( +// alignment: Alignment(-0.4, -0), +// child: Image.asset('assets/vector-15.png', scale: 1.5,)), +// ], +// ), +// Padding( +// padding: EdgeInsets.only(bottom: 20), +// child: Align( +// alignment: Alignment.bottomCenter, +// child: Column( +// mainAxisAlignment: MainAxisAlignment.end, +// children: [ +// MaterialButton( +// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), +// color: Color(0xff22c0e8), +// minWidth: 220, +// onPressed: () { +// Navigator.push( +// context, +// MaterialPageRoute(builder: (context) => LoginSignUpSeeker()), +// ); +// }, +// child: +// Text("Look for Jobs", +// textAlign: TextAlign.center, +// style: TextStyle( +// color: Colors.white, fontSize: 13)), +// ), +// MaterialButton( +// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), +// color: Color(0xff57b22f), +// minWidth: 220, +// onPressed: () { +// Navigator.push( +// context, +// MaterialPageRoute(builder: (context) => LoginSignUpEmployer()) +// ); +// }, +// child: +// Text("Look for Employees", +// textAlign: TextAlign.center, +// style: TextStyle( +// color: Colors.white, fontSize: 13)), +// ), +// SizedBox(height: 20), +// Column( +// children: [ +// Text("Copyright © 2019 by Dreamjob", +// textAlign: TextAlign.center, +// style: TextStyle( +// color: Colors.white, fontSize: 10) +// ), +// Text("www.dreamjob.co.id", +// textAlign: TextAlign.center, +// style: TextStyle( +// color: Colors.cyan[400], fontSize: 10)), +// ], +// ), +// ], +// ), +// ), +// ), +// ], +// ), +// ), +// ); +// } +// } + \ No newline at end of file diff --git a/lib/src/core/helpers/custom_route.dart b/lib/src/core/helpers/custom_route.dart new file mode 100644 index 0000000..f80046a --- /dev/null +++ b/lib/src/core/helpers/custom_route.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; + +class CustomRoute extends MaterialPageRoute { + CustomRoute({ + WidgetBuilder builder, + RouteSettings settings, + }) : super( + builder: builder, + settings: settings, + ); + + @override + Widget buildTransitions( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) { + if (settings.isInitialRoute) { + return child; + } + return FadeTransition( + opacity: animation, + child: child, + ); + } +} + +class CustomPageTransitionBuilder extends PageTransitionsBuilder { + @override + Widget buildTransitions( + PageRoute route, + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) { + if (route.settings.isInitialRoute) { + return child; + } + return FadeTransition( + opacity: animation, + child: child, + ); + } +} \ No newline at end of file diff --git a/lib/src/core/models/apply.dart b/lib/src/core/models/apply.dart new file mode 100644 index 0000000..8c1f322 --- /dev/null +++ b/lib/src/core/models/apply.dart @@ -0,0 +1,82 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:http/http.dart' as http; +import 'package:space/src/core/models/job.dart'; + +import './cart.dart'; + +class Applys with ChangeNotifier { + List _applys = []; + final String authToken; + final String userId; + + Applys(this.authToken, this.userId, this._applys); + + List get applys { + return [..._applys]; + } + + Future fetchAndSetApplys() async { + final url = + 'https://dreamjob-id.firebaseio.com/applys/$userId.json?auth=$authToken'; + final response = await http.get(url); + final List loadedApplys = []; + final extractedData = json.decode(response.body) as Map; + if (extractedData == null) { + return; + } + extractedData.forEach((applyId, applyData) { + loadedApplys.add( + ApplyItem( + id: applyId, + amount: applyData['amount'], + dateTime: DateTime.parse(applyData['dateTime']), + jobs: (applyData['jobs'] as List) + .map( + (item) => CartItem( + id: item['id'], + price: item['price'], + quantity: item['quantity'], + title: item['title'], + ), + ) + .toList(), + ), + ); + }); + _applys = loadedApplys.reversed.toList(); + notifyListeners(); + } + + Future addApply(List cartJobs, double total) async { + final url = + 'https://dreamjob-id.firebaseio.com/applys/$userId.json?auth=$authToken'; + final timestamp = DateTime.now(); + final response = await http.post( + url, + body: json.encode({ + 'amount': total, + 'dateTime': timestamp.toIso8601String(), + 'jobs': cartJobs + .map((cp) => { + 'id': cp.id, + 'title': cp.title, + 'quantity': cp.quantity, + 'price': cp.price, + }) + .toList(), + }), + ); + _applys.insert( + 0, + ApplyItem( + id: json.decode(response.body)['name'], + amount: total, + dateTime: timestamp, + jobs: cartJobs, + ), + ); + notifyListeners(); + } +} diff --git a/lib/src/core/models/auth.dart b/lib/src/core/models/auth.dart new file mode 100644 index 0000000..09992ce --- /dev/null +++ b/lib/src/core/models/auth.dart @@ -0,0 +1,126 @@ +import 'dart:convert'; +import 'dart:async'; + +import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../models/http_exception.dart'; + +class Auth with ChangeNotifier { + Timer _authTimer; + DateTime _expiryDate; + String _token; + String _userId; + + bool get isAuth { + return token != null; + } + + String get token { + if (_expiryDate != null && + _expiryDate.isAfter(DateTime.now()) && + _token != null) { + return _token; + } + return null; + } + + String get userId { + return _userId; + } + + Future _authenticate( + String email, String password, String urlSegment) async { + final url = + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/$urlSegment?key=AIzaSyB0qHYowM14ES-m5ZSQ-rXP8Ga13MThCaE'; + try { + final response = await http.post( + url, + body: json.encode( + { + 'email': email, + 'password': password, + 'returnSecureToken': true, + }, + ), + ); + final responseData = json.decode(response.body); + if (responseData['error'] != null) { + throw HttpException(responseData['error']['message']); + } + _token = responseData['idToken']; + _userId = responseData['localId']; + _expiryDate = DateTime.now().add( + Duration( + seconds: int.parse( + responseData['expiresIn'], + ), + ), + ); + _autoLogout(); + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + final userData = json.encode( + { + 'token': _token, + 'userId': _userId, + 'expiryDate': _expiryDate.toIso8601String(), + }, + ); + print(json.decode(response.body)); + prefs.setString('userData', userData); + } catch (error) { + throw error; + } + } + + Future signup(String email, String password) async { + return _authenticate(email, password, 'signupNewUser'); + } + + Future login(String email, String password) async { + return _authenticate(email, password, 'verifyPassword'); + } + + Future tryAutoLogin() async { + final prefs = await SharedPreferences.getInstance(); + if (!prefs.containsKey('userData')) { + return false; + } + final extractedUserData = json.decode(prefs.getString('userData')) as Map; + final expiryDate = DateTime.parse(extractedUserData['expiryDate']); + + if (expiryDate.isBefore(DateTime.now())) { + return false; + } + _token = extractedUserData['token']; + _userId = extractedUserData['userId']; + _expiryDate = expiryDate; + _autoLogout(); + notifyListeners(); + return true; + } + + Future logout() async { + _token = null; + _userId = null; + _expiryDate = null; + if (_authTimer != null) { + _authTimer.cancel(); + _authTimer = null; + } + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + // prefs.remove('userData'); + prefs.clear(); + } + + void _autoLogout() { + if (_authTimer != null) { + _authTimer.cancel(); + } + final timeToExpiry = _expiryDate.difference(DateTime.now()).inSeconds; + _authTimer = Timer(Duration(seconds: timeToExpiry), logout); + } +} diff --git a/lib/src/core/models/cart.dart b/lib/src/core/models/cart.dart new file mode 100644 index 0000000..0b75af5 --- /dev/null +++ b/lib/src/core/models/cart.dart @@ -0,0 +1,94 @@ +import 'package:flutter/foundation.dart'; + +class CartItem { + final String id; + final String title; + final int quantity; + final double price; + + CartItem({ + @required this.id, + @required this.title, + @required this.quantity, + @required this.price, + }); +} + +class Cart with ChangeNotifier { + Map _items = {}; + + Map get items { + return {..._items}; + } + + int get itemCount { + return _items.length; + } + + double get totalAmount { + var total = 0.0; + _items.forEach((key, cartItem) { + total += cartItem.price * cartItem.quantity; + }); + return total; + } + + void addItem( + String productId, + double price, + String title, + ) { + if (_items.containsKey(productId)) { + // change quantity... + _items.update( + productId, + (existingCartItem) => CartItem( + id: existingCartItem.id, + title: existingCartItem.title, + price: existingCartItem.price, + quantity: existingCartItem.quantity + 1, + ), + ); + } else { + _items.putIfAbsent( + productId, + () => CartItem( + id: DateTime.now().toString(), + title: title, + price: price, + quantity: 1, + ), + ); + } + notifyListeners(); + } + + void removeItem(String productId) { + _items.remove(productId); + notifyListeners(); + } + + void removeSingleItem(String productId) { + if (!_items.containsKey(productId)) { + return; + } + if (_items[productId].quantity > 1) { + _items.update( + productId, + (existingCartItem) => CartItem( + id: existingCartItem.id, + title: existingCartItem.title, + price: existingCartItem.price, + quantity: existingCartItem.quantity - 1, + )); + } else { + _items.remove(productId); + } + notifyListeners(); + } + + void clear() { + _items = {}; + notifyListeners(); + } +} diff --git a/lib/src/core/models/http_exception.dart b/lib/src/core/models/http_exception.dart new file mode 100644 index 0000000..bb91764 --- /dev/null +++ b/lib/src/core/models/http_exception.dart @@ -0,0 +1,11 @@ +class HttpException implements Exception { + final String message; + + HttpException(this.message); + + @override + String toString() { + return message; + // return super.toString(); // Instance of HttpException + } +} \ No newline at end of file diff --git a/lib/src/core/models/job.dart b/lib/src/core/models/job.dart new file mode 100644 index 0000000..e40fe2e --- /dev/null +++ b/lib/src/core/models/job.dart @@ -0,0 +1,68 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:http/http.dart' as http; + +class Job with ChangeNotifier { + final String id; + final String title; + final String employerName; + final String location; + final String workingday; + final String workinghour; + final String description; + final String industry; + final String education; + final String skill; + final double salary; + final String type; + final String imageUrl; + final String gender; + final String typeSalary; + bool isSave; + + Job({ + @required this.id, + @required this.title, + this.employerName, + @required this.location, + @required this.workingday, + @required this.workinghour, + @required this.description, + @required this.industry, + @required this.education, + @required this.skill, + @required this.salary, + @required this.type, + @required this.typeSalary, + this.imageUrl, + @required this.gender, + this.isSave = false, + }); + + void _setSaveValue(bool newValue) { + isSave = newValue; + notifyListeners(); + } + + Future toggleSavePosts(String token, String userId) async { + final oldStatus = isSave; + isSave = !isSave; + notifyListeners(); + final url = + 'https://dreamjob-id.firebaseio.com/userSaves/$userId/$id.json?auth=$token'; + try { + final response = await http.put( + url, + body: json.encode( + isSave, + ), + ); + if (response.statusCode >= 400) { + _setSaveValue(oldStatus); + } + } catch (error) { + _setSaveValue(oldStatus); + } + } +} \ No newline at end of file diff --git a/lib/src/core/models/jobs.dart b/lib/src/core/models/jobs.dart new file mode 100644 index 0000000..eb648a3 --- /dev/null +++ b/lib/src/core/models/jobs.dart @@ -0,0 +1,166 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:space/src/core/models/http_exception.dart'; + +import 'package:space/src/core/models/job.dart'; + +// const String PARSE_APP_ID = '7lbdiypJa4ZfYMky5E7NxAGFWmnfP0CtTzk6mhRj'; +// const String PARSE_APP_URL = 'https://parseapi.back4app.com/classes/job'; +// const String CLIENT_KEY = 'UH2KRTDVttLRdEB5heG70tyAdB7pcjkHgtapP4mu'; +// const String LIVE_QUERY_URL = 'wss://dreamjob.back4app.io'; + +class Jobs with ChangeNotifier { + List _posts = []; + +final String authToken; +final String userId; + +Jobs(this.authToken, this.userId, this._posts); + + List get posts { + return [..._posts]; + } + + List get savePosts { + return _posts.where((jobPost) => jobPost.isSave).toList(); + } + + Job findById(String id) { + return _posts.firstWhere((job) => job.id == id); + } + + Future fetchAndSetJobs([bool filterByUser = false]) async { + final filterString = filterByUser ? 'orderBy"creatorId"&equalTo="$userId"' : ''; + var url = + 'https://dreamjob-id.firebaseio.com/jobs.json?auth=$authToken&$filterString'; + try { + final response = await http.get(url); + final extractedData = json.decode(response.body) as Map; + if (extractedData == null) { + return; + } + url = + 'https://dreamjob-id.firebaseio.com/userSaves/$userId.json?auth=$authToken'; + final saveResponse = await http.get(url); + final saveData = json.decode(saveResponse.body); + final List loadedJobs = []; + extractedData.forEach((jobId, jobData) { + loadedJobs.add(Job( + id: jobId, + title: jobData['title'], + industry: jobData['industry'], + workingday: jobData['workingday'], + workinghour: jobData['workinghour'], + gender: jobData['gender'], + typeSalary: jobData['typeSalary'], + type: jobData['type'], + location: jobData['location'], + education: jobData['education'], + skill: jobData['skill'], + description: jobData['description'], + salary: jobData['salary'], + imageUrl: jobData['imageUrl'], + isSave: + saveData == null ? false : saveData[jobId] ?? false, + )); + }); + _posts = loadedJobs; + notifyListeners(); + } catch (error) { + print(error); + throw error; + } + } + + Future addJob(Job job) async { + final url = 'https://dreamjob-id.firebaseio.com/jobs.json?auth=$authToken'; + try { + final response = await http.post( + url, + body: json.encode({ + 'title': job.title, + 'gender': job.gender, + 'industry': job.industry, + 'workingday': job.workingday, + 'workinghour': job.workinghour, + 'type': job.type, + 'location': job.location, + 'education': job.education, + 'skill': job.skill, + 'description': job.description, + 'salary': job.salary, + // 'imageUrl': job.imageUrl, + 'creatorId' : userId, + }), + ); + final newJob = Job( + title: job.title, + typeSalary: job.typeSalary, + gender: job.gender, + industry: job.industry, + workingday: job.workingday, + workinghour: job.workinghour, + type: job.type, + location: job.location, + education: job.education, + skill: job.skill, + description: job.description, + salary: job.salary, + // imageUrl: job.imageUrl, + id: json.decode(response.body)['name'], + ); + _posts.add(newJob); + _posts.insert(0, newJob); + notifyListeners(); + } catch (error) { + print(error); + throw error; + } +} + + Future updateJob(String id, Job newJob) async { + final jobIndex = _posts.indexWhere((job) => job.id == id); + if (jobIndex >= 0) { + final url = + 'https://dreamjob-id.firebaseio.com/jobs/$id.json?auth=$authToken'; + await http.patch(url, + body: json.encode({ + 'title': newJob.title, + 'typeSalary': newJob.typeSalary, + 'gender': newJob.gender, + 'industry': newJob.industry, + 'workingday': newJob.workingday, + 'workinghour': newJob.workinghour, + 'type': newJob.type, + 'location': newJob.location, + 'education': newJob.education, + 'skill': newJob.skill, + 'description': newJob.description, + 'salary': newJob.salary, + // 'imageUrl': newJob.imageUrl, + })); + _posts[jobIndex] = newJob; + notifyListeners(); + } else { + print('...'); + } + } + + Future deleteJob(String id) async { + final url = + 'https://dreamjob-id.firebaseio.com/jobs/$id.json?auth=$authToken'; + final existingJobIndex = _posts.indexWhere((job) => job.id == id); + var existingJob = _posts[existingJobIndex]; + _posts.removeAt(existingJobIndex); + notifyListeners(); + final response = await http.delete(url); + if (response.statusCode >= 400) { + _posts.insert(existingJobIndex, existingJob); + notifyListeners(); + throw HttpException('Could not delete post.'); + } + existingJob = null; + } +} \ No newline at end of file diff --git a/lib/src/core/models/save.dart b/lib/src/core/models/save.dart new file mode 100644 index 0000000..644ac85 --- /dev/null +++ b/lib/src/core/models/save.dart @@ -0,0 +1,81 @@ +import 'package:flutter/foundation.dart'; + +class SavePost { + final String id; + final String jobId; + final String title; + final String employerName; + final String location; + final double salary; + final String type; + final String imageUrl; + + SavePost({ + @required this.id, + this.jobId, + @required this.title, + @required this.employerName, + @required this.location, + @required this.salary, + @required this.type, + @required this.imageUrl, + }); +} + +class Save with ChangeNotifier { + Map _posts = {}; + + Map get posts { + return {..._posts}; + } + + void addPosts( + String jobId, + double salary, + String title, + String employerName, + String type, + String location, + String imageUrl, + ) { + if (_posts.containsKey(jobId)) { + // change quantity... + _posts.update( + jobId, + (existingSavePost) => SavePost( + id: existingSavePost.id, + salary: existingSavePost.salary, + title: existingSavePost.title, + employerName: existingSavePost.employerName, + type: existingSavePost.type, + location: existingSavePost.location, + imageUrl: existingSavePost.imageUrl, + ), + ); + } else { + _posts.putIfAbsent( + jobId, + () => SavePost( + id: DateTime.now().toString(), + title: title, + employerName: employerName, + salary: salary, + location: location, + imageUrl: imageUrl, + type: type, + ) + ); + } + notifyListeners(); + } + + void removeItem(String jobId) { + _posts.remove(jobId); + notifyListeners(); + } + + void clear() { + _posts = {}; + notifyListeners(); + } +} diff --git a/lib/src/core/resources/jobs_provider.dart b/lib/src/core/resources/jobs_provider.dart new file mode 100644 index 0000000..b4768c4 --- /dev/null +++ b/lib/src/core/resources/jobs_provider.dart @@ -0,0 +1,27 @@ +// import 'package:flutter/material.dart'; +// import 'package:provider/provider.dart'; + +// import 'package:space/src/ui/layout/job_list.dart'; +// import 'package:space/src/core/models/jobs.dart'; + +// class JobsList extends StatelessWidget { +// final bool showSavs; + +// JobsList(this.showSavs); + +// @override +// Widget build(BuildContext context) { +// final jobsData = Provider.of(context); +// final jobs = showSavs ? jobsData.savePosts : jobsData.posts; +// return ListView.builder( +// itemCount: jobs.length, +// itemBuilder: (ctx, i) => ChangeNotifierProvider.value( +// value: jobs[i], +// //builder: (c) => jobs[i], +// child: JobList(), +// ), +// ); +// } +// } + + diff --git a/lib/src/core/services/location_service.dart b/lib/src/core/services/location_service.dart new file mode 100644 index 0000000..3022280 --- /dev/null +++ b/lib/src/core/services/location_service.dart @@ -0,0 +1,61 @@ +import 'dart:async'; + +import 'package:location/location.dart'; + +class UserLocation { + UserLocation({ + this.latitude, + this.longitude, + }); + + final double latitude; + final double longitude; +} + +class LocationService { + UserLocation _currentLocation; + StreamController _locationController = + StreamController(); + + Stream get locationStream => _locationController.stream; + + UserLocation _previousLocation; + + var location = Location(); + + LocationService() { + // Request permission to use location + location.requestPermission().then((granted) { + if (granted) { + // If granted listen to the onLocationChanged stream and emit over our controller + location.onLocationChanged().listen((locationData) { + if (locationData != null) { + if (locationData.longitude != _previousLocation?.longitude && + locationData.latitude != _previousLocation?.latitude) { + final newLocation = UserLocation( + latitude: locationData.latitude, + longitude: locationData.longitude, + ); + _locationController.add(newLocation); + _previousLocation = newLocation; + } + } + }); + } + }); + } + + Future getLocation() async { + try { + var userLocation = await location.getLocation(); + _currentLocation = UserLocation( + latitude: userLocation.latitude, + longitude: userLocation.longitude, + ); + } on Exception catch (e) { + print('Could not get location: ${e.toString()}'); + } + + return _currentLocation; + } +} diff --git a/lib/src/ui/auth/employer/home_employer.dart b/lib/src/ui/auth/employer/home_employer.dart new file mode 100644 index 0000000..f8d023c --- /dev/null +++ b/lib/src/ui/auth/employer/home_employer.dart @@ -0,0 +1,793 @@ +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:flutter/material.dart'; + +import 'package:space/src/ui/employer/widgets/employer_app_drawer.dart'; +import 'package:space/src/ui/components/horizontal_screen.dart'; +import 'package:space/src/ui/components/recommended_screen.dart'; +import 'package:space/src/ui/seeker/layout/seeker_profile_view.dart'; + +class HomePageEmployer extends StatefulWidget { + static const routeName = '/home_page_employer'; + + @override + _HomePageEmployerState createState() => _HomePageEmployerState(); +} + +class _HomePageEmployerState extends State { + TextStyle style = TextStyle( + fontFamily: 'VarelaRound', fontSize: 20.0, color: Color(0xff3b3b3b)); + TextStyle style2 = TextStyle( + fontFamily: 'TitilliumWeb', fontSize: 20.0, color: Color(0xff3b3b3b)); + int _current = 0; + + final List imgList = [ + Image.asset('assets/home.png', fit: BoxFit.contain), + Image.asset('assets/vector-3.png', fit: BoxFit.contain), + Image.asset('assets/job.png', fit: BoxFit.contain), + Image.asset('assets/job2.png', fit: BoxFit.contain), + Image.asset('assets/blog.png', fit: BoxFit.contain), + ]; + + List map(List list, Function handler) { + List result = []; + for (var i = 0; i < list.length; i++) { + result.add(handler(i, list[i])); + } + + return result; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: EmployerDrawer(), + backgroundColor: Colors.grey[200], + appBar: AppBar( + automaticallyImplyLeading: false, + elevation: 0.0, + backgroundColor: Colors.grey[200], + leading: Builder( + builder: (context) => IconButton( + icon: Icon(Icons.menu), + onPressed: () => Scaffold.of(context).openDrawer(), + ), + ), + title: TextFormField( + textInputAction: TextInputAction.search, + style: style.copyWith( + fontSize: 16, + color: Color(0xffc9c8c8), + decoration: TextDecoration.none, + ), + decoration: InputDecoration( + focusedBorder: InputBorder.none, + contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), + prefixIcon: IconButton( + onPressed: () {}, + icon: Icon( + FeatherIcons.search, + size: 18, + ), + color: Color(0xffc9c8c8)), + fillColor: Colors.white, + filled: true, + hintText: 'Try "Barista"', + hintStyle: style.copyWith(color: Color(0xffc9c8c8), fontSize: 16), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xffc5cfda)), + )), + ), + ), + body: ListView( + children: [ + Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Column(children: [ + CarouselSlider( + items: imgList, + autoPlay: true, + enlargeCenterPage: true, + aspectRatio: 2.0, + onPageChanged: (index) { + setState(() { + _current = index; + }); + }, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 35), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: map( + imgList, + (index, url) { + return Container( + width: 8.0, + height: 8.0, + margin: EdgeInsets.symmetric(horizontal: 2.0), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _current == index + ? Color.fromRGBO(0, 0, 0, 0.9) + : Color.fromRGBO(0, 0, 0, 0.4)), + ); + }, + ), + ), + Text('See All', + style: style2.copyWith( + fontSize: 10, + color: Color(0xffc9c8c8), + letterSpacing: 1)), + ], + ), + ), + ]), + SizedBox(height: 10), + Container( + margin: EdgeInsets.only(top: 10), + height: 45, + child: ListTile( + leading: Container( + child: Text('Recent Job', + style: style2.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: 1))), + trailing: Container( + margin: EdgeInsets.only(bottom: 5), + child: Text('See All', + style: style2.copyWith( + fontSize: 10, + color: Color(0xffc9c8c8), + letterSpacing: 1))), + onTap: () {}, + )), + SizedBox(height: 180, child: HorizontalScreen()), + Container( + height: 50, + child: ListTile( + leading: Text('Recomended Job', + style: style2.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: 1)), + trailing: Container( + margin: EdgeInsets.only(bottom: 5), + child: Text('See All', + style: style2.copyWith( + fontSize: 10, + color: Color(0xffc9c8c8), + letterSpacing: 1))), + onTap: () {}, + )), + SizedBox( + height: 180, + child: RecommendedScreen(), + ), + Container( + margin: EdgeInsets.only(top: 10), + height: 45, + child: ListTile( + leading: Container( + child: Text('Feed your Dreams', + style: style2.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: 1))), + trailing: Container( + margin: EdgeInsets.only(bottom: 5), + child: Text('See All', + style: style2.copyWith( + fontSize: 10, + color: Color(0xffc9c8c8), + letterSpacing: 1))), + onTap: () {}, + )), + Container( + padding: EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + Text( + 'Success story from people around you, encourage, giving nutritions to your dreams.', + style: style.copyWith(fontSize: 13)), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10, left: 16, right: 16), + padding: EdgeInsets.only(bottom: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(5), + bottomRight: Radius.circular(5))), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width, + height: 200, + child: Image.asset('assets/blog.png', + fit: BoxFit.cover)), + Padding( + padding: EdgeInsets.all(10), + child: Text("How to success and winning competition", + style: style.copyWith( + color: Color(0xff3b3b3b), + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: 0.5, + ))), + Padding( + padding: EdgeInsets.all(10), + child: Text( + 'Success story from people around you, encourage, giving nutritions to your dreams. Lorem ipsum dollor', + style: style.copyWith( + color: Color(0xff3b3b3b), fontSize: 12))), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10), + height: 45, + child: ListTile( + leading: Container( + child: Text('People around you', + style: style2.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: 1))), + trailing: Container( + margin: EdgeInsets.only(bottom: 5), + child: Text('See All', + style: style2.copyWith( + fontSize: 10, + color: Color(0xffc9c8c8), + letterSpacing: 1))), + onTap: () {}, + )), + Material( + child: Container( + height: 120, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Uray Bawadi', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_2.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Yudi Salim', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_3.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Aprianto', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_4.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Gamabunta', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Uray Bawadi', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_2.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Yudi Salim', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_3.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Aprianto', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_4.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Gamabunta', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Uray Bawadi', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_2.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Yudi Salim', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_3.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Aprianto', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new SeekerProfileView())); + }, + child: CircleAvatar( + backgroundColor: + Color(0xff48576a), + radius: 30.0, + child: Image.asset( + 'assets/img_profil_4.png', + scale: 1.3))), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + ], + ), + Text( + 'Gamabunta', + style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + ]), + ), + ), + ), + SizedBox(height: 30) + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/src/ui/auth/employer/login_employer.dart b/lib/src/ui/auth/employer/login_employer.dart new file mode 100644 index 0000000..bc1b4df --- /dev/null +++ b/lib/src/ui/auth/employer/login_employer.dart @@ -0,0 +1,202 @@ +import 'package:flutter/material.dart'; + +import 'package:space/src/ui/auth/employer/ui_get_started_employer.dart'; + + +class LoginEmployer extends StatefulWidget { + + static const routeName = 'signup_or_login'; + + @override + _LoginEmployerState createState() => _LoginEmployerState(); +} + +class _LoginEmployerState extends State { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + final textBody = + Column(children: [ + Column( + children: [ + Text('LOGIN TO YOUR ACCOUNT', + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: style.copyWith( + color: Color(0xff2c4057), fontSize: 12) + ), + ], + ), + Row(children: [ + Expanded( + child: new Container( + margin: const EdgeInsets.symmetric(horizontal: 70), + child: Divider( + thickness: 2, + color: Color(0xff22c0e8), + height: 30)), + ) + ] + ) + ] + ); + + + final emailField = new TextFormField( + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: 'Username', + hintStyle: style.copyWith(color: Color(0xff8997a7), fontSize: 12), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Email can\'t be empty' : null + ); + + final passwordField = TextFormField( + obscureText: true, + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: 'Password', + hintStyle: style.copyWith(color: Color(0xff8997a7), fontSize: 12), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Password can\'t be empty' : null + ); + + final loginButton = Material( + elevation: 3.0, + borderRadius: BorderRadius.circular(30.0), + color: Color(0xff57b22f), + child: MaterialButton( + padding: EdgeInsets.fromLTRB(60.0, 15.0, 20.0, 15.0), + onPressed: () { Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => UiGetStartedEmployer())); + }, + child: Row( + children: [ + Text('Login Now', + textAlign: TextAlign.center, + style: style.copyWith( + color: Colors.white, fontSize: 14)), + const Expanded( + child: Icon(Icons.arrow_forward, color: Colors.white, size: 18,)), + ], + ), + ), + ); + + final linkForgot = Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MaterialButton( + padding: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0), + onPressed: (){}, + child: Text('FORGOT PASSWORD?', + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: style.copyWith( + color: Colors.cyan[400], fontSize: 9))), + Text('|', style: style.copyWith(fontSize: 8, color: Colors.blueGrey)), + MaterialButton( + padding: EdgeInsets.fromLTRB(5.0, 5.0, 0.0, 5.0), + onPressed: () {Navigator.pushNamed(context, 'space/register_account');}, + child: Text('REGISTER AN ACCOUNT', + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: style.copyWith( + color: Colors.blueGrey, fontSize: 9))), + ], + ), + ); + + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Scaffold( + body: SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Container( + padding: EdgeInsets.only(left: 60, right: 60), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + textBody, + SizedBox( + height: 10.0, + ), + SizedBox(height: 50.0), + emailField, + SizedBox(height: 20.0), + passwordField, + SizedBox( + height: 30.0, + ), + loginButton, + SizedBox( + height: 5.0, + ), + linkForgot, + SizedBox( + height: 80.0, + ), + + Column ( + children: [ + Text('Copyright © 2019 by Dreamjob', + textAlign: TextAlign.center, + style: style.copyWith( + color: Colors.blueGrey, fontSize: 10) + ), + Text('www.dreamjob.com', + textAlign: TextAlign.center, + style: style.copyWith( + color: Colors.cyan[400], fontSize: 10)), + ], + ), + SizedBox( + height: 5 + ), + ], + ),), + ), + ), + ); + } + +); + } + } + diff --git a/lib/src/ui/auth/employer/login_signup_employer.dart b/lib/src/ui/auth/employer/login_signup_employer.dart new file mode 100644 index 0000000..bcc00fd --- /dev/null +++ b/lib/src/ui/auth/employer/login_signup_employer.dart @@ -0,0 +1,384 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; + +import 'package:space/src/core/models/http_exception.dart'; +import 'package:space/src/core/models/auth.dart'; + +enum AuthMode { Signup, Login } + +class LoginSignUpEmployer extends StatelessWidget { + static const routeName = '/auth'; + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/vector-5.png'), + fit: BoxFit.cover, + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + body: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.only(top: 20, bottom: 10), + child:Container( + alignment: Alignment.center, + child: Image.asset('assets/logo_vertical.png'), + height: 80, + ), + ), + Flexible( + child: AuthCard(), + ), + ], + ), + ), + ); + } +} + +class AuthCard extends StatefulWidget { + const AuthCard({ + Key key, + }) : super(key: key); + + @override + _AuthCardState createState() => _AuthCardState(); +} + +class _AuthCardState extends State { + final GlobalKey _formKey = GlobalKey(); + AuthMode _authMode = AuthMode.Login; + Map _authData = { + 'email': '', + 'password': '', + }; + var _isLoading = false; + final _passwordController = TextEditingController(); + + void _showErrorDialog(String message) { + showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text('An Error Occurred!'), + content: Text(message), + actions: [ + FlatButton( + child: Text('Okay'), + onPressed: () { + Navigator.of(ctx).pop(); + }, + ) + ], + ), + ); + } + + Future _submit() async { + if (!_formKey.currentState.validate()) { + // Invalid! + return; + } + _formKey.currentState.save(); + setState(() { + _isLoading = true; + }); + try { + if (_authMode == AuthMode.Login) { + // Log user in + await Provider.of(context, listen: false).login( + _authData['email'], + _authData['password'], + ); + } else { + // Sign user up + await Provider.of(context, listen: false).signup( + _authData['email'], + _authData['password'], + ); + } + } on HttpException catch (error) { + var errorMessage = 'Authentication failed'; + if (error.toString().contains('EMAIL_EXISTS')) { + errorMessage = 'This email address is already in use.'; + } else if (error.toString().contains('INVALID_EMAIL')) { + errorMessage = 'This is not a valid email address'; + } else if (error.toString().contains('WEAK_PASSWORD')) { + errorMessage = 'This password is too weak.'; + } else if (error.toString().contains('EMAIL_NOT_FOUND')) { + errorMessage = 'Could not find a user with that email.'; + } else if (error.toString().contains('INVALID_PASSWORD')) { + errorMessage = 'Invalid password.'; + } + _showErrorDialog(errorMessage); + } catch (error) { + const errorMessage = + 'Could not authenticate you. Please try again later.'; + _showErrorDialog(errorMessage); + } + + setState(() { + _isLoading = false; + }); + } + + void _switchAuthMode() { + if (_authMode == AuthMode.Login) { + setState(() { + _authMode = AuthMode.Signup; + }); + } else { + setState(() { + _authMode = AuthMode.Login; + }); + } + } + + @override + Widget build(BuildContext context) { + return Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + children: [ + Column(children: [ + Text((_authMode == AuthMode.Login ? 'LOGIN AN ACCOUNT' : 'SIGN UP AN ACCOUNT'), + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.white, fontSize: 14) + ), + ], + ), + Row(children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(left: 120, right: 120), + child: Divider( + thickness: 2, + color: Color(0xff22c0e8), + height: 30)), + ) + ] + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 5), + child: TextFormField( + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + errorStyle: TextStyle(color: Theme.of(context).errorColor), + hintText: 'E-mail', + hintStyle: TextStyle(color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + errorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8)), + borderRadius: BorderRadius.all(Radius.circular(30))), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.transparent), + borderRadius: BorderRadius.all(Radius.circular(30))), + ), + keyboardType: TextInputType.emailAddress, + validator: (value) { + if (value.isEmpty || !value.contains('@')) { + return 'Invalid email!'; + } + }, + onSaved: (value) { + _authData['email'] = value; + }, + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 5), + child: TextFormField( + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + errorStyle: TextStyle(color: Theme.of(context).errorColor), + hintText: 'Password', + hintStyle: TextStyle(color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + errorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8)), + borderRadius: BorderRadius.all(Radius.circular(30))), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.transparent), + borderRadius: BorderRadius.all(Radius.circular(30))), + ), + obscureText: true, + controller: _passwordController, + validator: (value) { + if (value.isEmpty || value.length < 5) { + return 'Password is too short!'; + } + }, + onSaved: (value) { + _authData['password'] = value; + }, + ), + ), + if (_authMode == AuthMode.Signup) + + Padding( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 5), + child: TextFormField( + enabled: _authMode == AuthMode.Signup, + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + errorStyle: TextStyle(color: Theme.of(context).errorColor), + hintText: 'Confirm Password', + hintStyle: TextStyle(color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + errorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8)), + borderRadius: BorderRadius.all(Radius.circular(30))), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.transparent), + borderRadius: BorderRadius.all(Radius.circular(30))), + ), + obscureText: true, + validator: _authMode == AuthMode.Signup + ? (value) { + if (value != _passwordController.text) { + return 'Passwords do not match!'; + } + } + : null, + ), + ), + SizedBox( + height: 20, + ), + if (_isLoading) + CircularProgressIndicator( + backgroundColor: Color(0xff22c0e8), + ) + else + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MaterialButton( + minWidth: 160, + child: + Text(_authMode == AuthMode.Login ? 'Login' : 'Sign Up'), + onPressed: _submit, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + padding: + EdgeInsets.symmetric(horizontal: 30.0, vertical: 8.0), + color: (_authMode == AuthMode.Login ? Color(0xff57b22f) : Color(0xff22c0e8)), + textColor: Colors.white, + ), + SizedBox(width: 10), + MaterialButton( + minWidth: 160, + child: Text( + '${_authMode == AuthMode.Login ? 'Sign up' : 'Login'} an account'), + onPressed: _switchAuthMode, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 4), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + color: (_authMode == AuthMode.Login ? Color(0xff22c0e8) : Color(0xff57b22f)), + textColor: Colors.white, + ), + ], + ), + SizedBox(height: 15), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(left: 20, right: 10), + child: Divider(thickness: 0.5, color: Colors.white,), + ), + ), + Text('OR', style: TextStyle(fontSize: 11, color: Colors.white70)), + Expanded( + child: Container( + margin: EdgeInsets.only(right: 20, left: 10), + child: Divider(thickness: 0.5, color: Colors.white,), + ), + ), + ], + ), + SizedBox(height: 15), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + color: Color(0xff2d67a5), + minWidth: 160, + onPressed: () {}, + child: Row( + children: [ + Icon(MdiIcons.facebook, size: 20, color: Colors.white), + Text("Login with Facebook", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, fontSize: 11)), + ], + ), + ), + + SizedBox(width: 10), + + MaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + color: Colors.white, + minWidth: 160, + onPressed: () {}, + child: Row( + children: [ + Image.asset('assets/gmail.png', height: 12), + Text(" Login with Gmail", + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0xff8997a7), fontSize: 11)), + ], + ), + ), + ], + ), + SizedBox(height: 70) + ], + ), + ), + + ); + } +} + diff --git a/lib/src/ui/auth/employer/register_employer.dart b/lib/src/ui/auth/employer/register_employer.dart new file mode 100644 index 0000000..f0b2451 --- /dev/null +++ b/lib/src/ui/auth/employer/register_employer.dart @@ -0,0 +1,278 @@ +import 'package:flutter/material.dart'; + + +class RegisterEmployer extends StatefulWidget { + + static const routeName = 'register_employer'; + + @override + _RegisterEmployerState createState() => _RegisterEmployerState(); +} + +class _RegisterEmployerState extends State { +TextStyle style = TextStyle(fontFamily: 'VarelaRound'); + + String dropdownValue = 'Seeker'; + + @override + Widget build(BuildContext context) { + + final textBody = + Column(children: [ + Column(children: [ + Text("REGISTER AN ACCOUNT", + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: style.copyWith( + color: Color(0xff2c4057), fontSize: 12) + ), + ], + ), + Row(children: [ + Expanded( + child: new Container( + margin: const EdgeInsets.only(left: 70.0, right: 70.0), + child: Divider( + thickness: 2, + color: Color(0xff22c0e8), + height: 30)), + ) + ] + ) + ] + ); + + + final usernameField = new TextFormField( + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: "Choose a Username", + hintStyle: style.copyWith(color: Color(0xff8997a7)), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Column can\'t be empty' : null + ); + + final emailField = TextFormField( + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: "Enter Your Email Address", + hintStyle: style.copyWith(color: Color(0xff8997a7)), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Column can\'t be empty' : null + ); + + final passwordField = new TextFormField( + obscureText: true, + style: style.copyWith( + + color: Colors.black45, + fontSize: 12, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: "Password", + hintStyle: style.copyWith(color: Color(0xff8997a7), fontSize: 12), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Column can\'t be empty' : null + ); + + final confirmPassword = new TextFormField( + obscureText: true, + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: "Confirm Password", + hintStyle: style.copyWith(color: Color(0xff8997a7), fontSize: 12), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Column can\'t be empty' : null + ); + + final selectField = FormField( + builder: (FormFieldState state) { + return InputDecorator( + decoration: InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 0.0, 30.0, 0.0), + errorStyle: style.copyWith(color: Colors.redAccent, fontSize: 12), + hintStyle: style.copyWith(color: Color(0xff8997a7)), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: dropdownValue, + onChanged: (String newValue) { + setState(() { + dropdownValue = newValue; + }); + }, + icon: Icon(Icons.expand_more, color: Colors.blueGrey, size: 18,), + items: ['Seeker', 'Employer'] + .map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value, style: style.copyWith( + color: Color(0xff8997a7), + fontSize: 12, + letterSpacing: 0.25, + )), + ); + }).toList(), + ), + ), + ); + } + ); + + final regButton = Material( + elevation: 3.0, + borderRadius: BorderRadius.all(Radius.circular(50)), + color: Color(0xff22c0e8), + child: MaterialButton( + padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), + onPressed: () { + // showDialog( + // context: context,builder: (_) => FlareGiffyDialog( + // flarePath: 'assets/space_demo.flr', + // flareAnimation: 'loading', + // title: Text('Sedang Loading', + // style: style.copyWith( + // fontSize: 22.0, fontWeight: FontWeight.w500), + // ), + // description: Text('Silahkan tunggu...', + // textAlign: TextAlign.center, + // style: style.copyWith(), + // ), + // onOkButtonPressed: () {}, + // ) ); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text('Register Now', + textAlign: TextAlign.center, + style: style.copyWith( + + color: Color(0xffffffff), + fontSize: 14, + fontWeight: FontWeight.w500, + ) + ), + Icon(Icons.arrow_forward, color: Colors.white, size: 18,), + ], + ), + ), + ); + +return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Scaffold( + body: SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Container( + padding: EdgeInsets.only(left: 60, right: 60, bottom: 30), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + textBody, + SizedBox( + height: 10.0, + ), + usernameField, + SizedBox( + height: 25.0), + emailField, + SizedBox( + height: 25.0), + passwordField, + SizedBox( + height: 25.0), + confirmPassword, + SizedBox( + height: 25.0, + ), + selectField, + SizedBox( + height: 25.0), + regButton, + SizedBox( + height: 15.0, + ), + Text("LOGIN TO YOUR EXISTING ACCOUNT", + style: style.copyWith( + color: Color(0xff8997a7), + fontSize: 9, + + fontStyle: FontStyle.normal, + letterSpacing: 0.55, + ) + ), + ], + + ), + ), + ), + ), + ); + } + ); + } + } diff --git a/lib/src/ui/auth/employer/ui_get_started_employer.dart b/lib/src/ui/auth/employer/ui_get_started_employer.dart new file mode 100644 index 0000000..ef1b816 --- /dev/null +++ b/lib/src/ui/auth/employer/ui_get_started_employer.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:space/navigator_employer.dart'; + +class UiGetStartedEmployer extends StatelessWidget { + + @override + Widget build(BuildContext context) { + TextStyle style = TextStyle(fontFamily: 'Quicksand-Regular', fontSize: 20.0); + return new Scaffold( + body: Padding( + padding: EdgeInsets.fromLTRB(50, 30, 50, 30), + child: Container( + height: MediaQuery.of(context).size.height, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 70), + child: Image.asset('assets/logo_vertical.png') + ), + Text('Are you ready to find your dream team?', + textAlign: TextAlign.center, + style: style.copyWith(fontSize: 40, color: Color(0xff3b3b3b), fontWeight: FontWeight.bold)), + Text('Find your best team now is easiers. Easy to post a job, get in touch via chat, interviewing anywhere via live. Just type and upload.', + textAlign: TextAlign.center, + style: style.copyWith(fontSize: 17.2, color: Color(0x99383839), fontWeight: FontWeight.w600)), + ButtonTheme( + minWidth: 190, + height: 55, + child: RaisedButton( + color: Color(0xff57b22f), + onPressed: () { Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => EmployerNavigator())); + }, + child: Text('Get Started', style: style.copyWith(fontSize: 24, color: Colors.white, fontWeight: FontWeight.bold)), + ), + ), + ButtonTheme( + minWidth: 190, + height: 55, + child: OutlineButton( + highlightedBorderColor: Color(0xff57b22f), + borderSide: BorderSide(color: Color(0xff57b22f)), + onPressed: () { Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => EmployerNavigator())); + }, + child: Text('Try Trial', style: style.copyWith(fontSize: 24, color: Color(0xff57b22f), fontWeight: FontWeight.bold)), + ), + ), + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/auth/seeker/home_seeker.dart b/lib/src/ui/auth/seeker/home_seeker.dart new file mode 100644 index 0000000..d6c2e85 --- /dev/null +++ b/lib/src/ui/auth/seeker/home_seeker.dart @@ -0,0 +1,666 @@ +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:flutter/material.dart'; + +import 'package:space/src/ui/seeker/widgets/seeker_app_drawer.dart'; +import 'package:space/src/ui/components/horizontal_screen.dart'; +import 'package:space/src/ui/components/recommended_screen.dart'; +import 'package:space/src/ui/seeker/layout/seeker_profile_view.dart'; + +class HomePageSeeker extends StatefulWidget { + + static const routeName = 'home_page_seeker'; + + @override + _HomePageSeekerState createState() => _HomePageSeekerState(); +} + +class _HomePageSeekerState extends State { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0, color: Color(0xff3b3b3b)); + TextStyle style2= TextStyle(fontFamily: 'TitilliumWeb', fontSize: 20.0, color: Color(0xff3b3b3b)); + int _current = 0; + + final List imgList = [ + Image.asset('assets/home.png', fit: BoxFit.contain), + Image.asset('assets/vector-3.png', fit: BoxFit.contain), + Image.asset('assets/job.png', fit: BoxFit.contain), + Image.asset('assets/job2.png', fit: BoxFit.contain), + Image.asset('assets/blog.png', fit: BoxFit.contain), +]; + +List map(List list, Function handler) { + List result = []; + for (var i = 0; i < list.length; i++) { + result.add(handler(i, list[i])); + } + + return result; +} + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: AppDrawer(), + backgroundColor: Colors.grey[200], + appBar: AppBar( + automaticallyImplyLeading: false, + elevation: 0.0, + backgroundColor: Colors.grey[200], + leading: Builder( + builder: (context) => IconButton( + icon: Icon(Icons.menu), + onPressed: () => Scaffold.of(context).openDrawer(), + ), + ), + title: TextFormField( + textInputAction: TextInputAction.search, + style: style.copyWith( + fontSize: 16, + color: Color(0xffc9c8c8), + decoration: TextDecoration.none, + ), + decoration: InputDecoration( + focusedBorder: InputBorder.none, + contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), + prefixIcon: IconButton( + onPressed: (){ + + }, + icon: Icon(FeatherIcons.search, size: 18,), + color: Color(0xffc9c8c8)), + fillColor: Colors.white, + filled: true, + hintText: 'Try "Barista"', + hintStyle: style.copyWith(color: Color(0xffc9c8c8), fontSize: 16), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xffc5cfda)), + )), + ), + ), + body: ListView( + children: [ + Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + + Column( + children: [ + CarouselSlider( + items: imgList, + autoPlay: true, + enlargeCenterPage: true, + aspectRatio: 2.0, + onPageChanged: (index) { + setState(() { + _current = index; + }); + }, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 35), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: map( + imgList, + (index, url) { + return Container( + width: 8.0, + height: 8.0, + margin: EdgeInsets.symmetric(horizontal: 2.0), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _current == index + ? Color.fromRGBO(0, 0, 0, 0.9) + : Color.fromRGBO(0, 0, 0, 0.4)), + ); + }, + ), + ), + Text('See All', + style: style2.copyWith(fontSize: 10, color: Color(0xffc9c8c8), letterSpacing: 1)), + ],), + ), + ]), + SizedBox(height: 10), + Container( + margin: EdgeInsets.only(top: 10), + height: 45, + child: ListTile( + leading: Container( + child: Text('Recent Job', + style: style2.copyWith(fontSize: 16, fontWeight: FontWeight.bold, letterSpacing: 1))), + trailing: Container( + margin: EdgeInsets.only(bottom: 5), + child: Text('See All', + style: style2.copyWith(fontSize: 10, color: Color(0xffc9c8c8), letterSpacing: 1))), + onTap: () {}, + )), + + SizedBox( + height: 180, + child: HorizontalScreen()), + + Container( + height: 50, + child: ListTile( + leading: Text('Recomended Job', style: style2.copyWith(fontSize: 16, fontWeight: FontWeight.bold, letterSpacing: 1)), + trailing: Container( + margin: EdgeInsets.only(bottom: 5), + child: Text('See All', + style: style2.copyWith(fontSize: 10, color: Color(0xffc9c8c8), letterSpacing: 1))), + onTap: () {}, + )), + + SizedBox( + height: 180, + child: RecommendedScreen(), + ), + + Container( + margin: EdgeInsets.only(top: 10), + height: 45, + child: ListTile( + leading: Container( + child: Text('Feed your Dreams', + style: style2.copyWith(fontSize: 16, fontWeight: FontWeight.bold, letterSpacing: 1))), + trailing: Container( + margin: EdgeInsets.only(bottom: 5), + child: Text('See All', + style: style2.copyWith(fontSize: 10, color: Color(0xffc9c8c8), letterSpacing: 1))), + onTap: () {}, + )), + + Container( + padding: EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + Text( + 'Success story from people around you, encourage, giving nutritions to your dreams.', + style: style.copyWith(fontSize: 13)), + ], + ), + ), + + Container( + margin: EdgeInsets.only(top: 10, left: 16, right: 16), + padding: EdgeInsets.only(bottom: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(5), bottomRight: Radius.circular(5)) + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width, + height: 200, + child: Image.asset('assets/blog.png', fit: BoxFit.cover)), + Padding( + padding: EdgeInsets.all(10), + child: Text("How to success and winning competition", + style: style.copyWith( + color: Color(0xff3b3b3b), + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: 0.5, + ))), + Padding( + padding: EdgeInsets.all(10), + child: Text('Success story from people around you, encourage, giving nutritions to your dreams. Lorem ipsum dollor', + style: style.copyWith( + color: Color(0xff3b3b3b), + fontSize: 12))), + ], + ),), + + Container( + margin: EdgeInsets.only(top: 10), + height: 45, + child: ListTile( + leading: Container( + child: Text('People around you', + style: style2.copyWith(fontSize: 16, fontWeight: FontWeight.bold, letterSpacing: 1))), + trailing: Container( + margin: EdgeInsets.only(bottom: 5), + child: Text('See All', + style: style2.copyWith(fontSize: 10, color: Color(0xffc9c8c8), letterSpacing: 1))), + onTap: () {}, + )), + + Material( + child: Container( + height: 120, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Uray Bawadi', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_2.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Yudi Salim', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_3.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Aprianto', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_4.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Gamabunta', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Uray Bawadi', style: style.copyWith(fontSize: 10), + ), + ], + ),), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_2.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Yudi Salim', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_3.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Aprianto', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_4.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Gamabunta', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Uray Bawadi', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_2.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Yudi Salim', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_3.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Aprianto', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment(0.6, -1), + children: [ + MaterialButton( + shape: CircleBorder(), + onPressed: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + child: CircleAvatar( + backgroundColor: Color(0xff48576a), + radius: 30.0, + child: Image.asset('assets/img_profil_4.png', scale: 1.3) + )), + CircleAvatar( + backgroundColor: Color(0xff22c0e8), + radius: 10, + child: Icon( + Icons.add, color: Colors.white, size: 16, + ), + ), + ], + ), + Text( + 'Gamabunta', style: style.copyWith(fontSize: 10), + ), + ], + ), + ), + ] + ), + ), + ), + ), + SizedBox(height: 30) + + ], + ), + ), + ], + ), + ); + + } + +} diff --git a/lib/src/ui/auth/seeker/login_seeker.dart b/lib/src/ui/auth/seeker/login_seeker.dart new file mode 100644 index 0000000..daa65ee --- /dev/null +++ b/lib/src/ui/auth/seeker/login_seeker.dart @@ -0,0 +1,257 @@ +import 'package:flutter/material.dart'; + +import 'package:space/src/ui/auth/seeker/ui_get_started_seeker.dart'; + + +class LoginSeeker extends StatefulWidget { + + static const routeName = 'login_seeker'; + + @override + _LoginSeekerState createState() => _LoginSeekerState(); +} + +class _LoginSeekerState extends State { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + final GlobalKey _formKey = GlobalKey(); + Map _authData = { + 'email': '', + 'password': '', + }; + var _isLoading = false; + final _passwordController = TextEditingController(); + + void _showErrorDialog(String message) { + showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text('An Error Occurred!'), + content: Text(message), + actions: [ + FlatButton( + child: Text('Ok'), + onPressed: () { + Navigator.of(ctx).pop(); + }, + ) + ], + ), + ); + } + + Future _submit() async { + if (!_formKey.currentState.validate()) { + // Invalid! + return; + } + _formKey.currentState.save(); + setState(() { + _isLoading = true; + }); + + setState(() { + _isLoading = false; + }); + } + + @override + Widget build(BuildContext context) { + final textBody = + Column(children: [ + Column( + children: [ + Text('LOGIN TO YOUR ACCOUNT', + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: style.copyWith( + color: Color(0xff2c4057), fontSize: 12) + ), + ], + ), + Row(children: [ + Expanded( + child: new Container( + margin: const EdgeInsets.symmetric(horizontal: 70), + child: Divider( + thickness: 2, + color: Color(0xff22c0e8), + height: 30)), + ) + ] + ) + ] + ); + + + final emailField = new TextFormField( + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: 'Email Address', + hintStyle: style.copyWith(color: Color(0xff8997a7), fontSize: 12), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + keyboardType: TextInputType.emailAddress, + validator: (value) { + if (value.isEmpty || !value.contains('@')) { + return 'Invalid email!'; + } + }, + onSaved: (value) { + _authData['email'] = value; + }, + ); + final passwordField = TextFormField( + obscureText: true, + controller: _passwordController, + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: 'Password', + hintStyle: style.copyWith(color: Color(0xff8997a7), fontSize: 12), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) { + if (value.isEmpty || value.length < 5) { + return 'Password is too short!'; + } + }, + onSaved: (value) { + _authData['password'] = value; + }, + ); + + final loginButton = Material( + elevation: 3.0, + borderRadius: BorderRadius.circular(30.0), + color: Color(0xff57b22f), + child: MaterialButton( + padding: EdgeInsets.fromLTRB(60.0, 15.0, 20.0, 15.0), + onPressed: () { Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => UiGetStartedSeeker())); + }, + child: Row( + children: [ + Text('Login Now', + textAlign: TextAlign.center, + style: style.copyWith( + color: Colors.white, fontSize: 14)), + const Expanded( + child: Icon(Icons.arrow_forward, color: Colors.white, size: 18,)), + ], + ), + ), + ); + + final linkForgot = Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MaterialButton( + padding: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0), + onPressed: _submit, + child: Text('FORGOT PASSWORD?', + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: style.copyWith( + color: Colors.cyan[400], fontSize: 9))), + Text('|', style: style.copyWith(fontSize: 8, color: Colors.blueGrey)), + MaterialButton( + padding: EdgeInsets.fromLTRB(5.0, 5.0, 0.0, 5.0), + onPressed: () {Navigator.pushNamed(context, 'space/register_account');}, + child: Text('REGISTER AN ACCOUNT', + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: style.copyWith( + color: Colors.blueGrey, fontSize: 9))), + ], + ), + ); + + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Scaffold( + body: SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Container( + padding: EdgeInsets.only(left: 60, right: 60), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + textBody, + SizedBox( + height: 10.0, + ), + SizedBox(height: 50.0), + emailField, + SizedBox(height: 20.0), + passwordField, + SizedBox( + height: 30.0, + ), + loginButton, + SizedBox( + height: 5.0, + ), + linkForgot, + SizedBox( + height: 80.0, + ), + + Column ( + children: [ + Text('Copyright © 2019 by Dreamjob', + textAlign: TextAlign.center, + style: style.copyWith( + color: Colors.blueGrey, fontSize: 10) + ), + Text('www.dreamjob.com', + textAlign: TextAlign.center, + style: style.copyWith( + color: Colors.cyan[400], fontSize: 10)), + ], + ), + SizedBox( + height: 5 + ), + ], + ),), + ), + ), + ); + } + +); + } + } + diff --git a/lib/src/ui/auth/seeker/login_signup_seeker.dart b/lib/src/ui/auth/seeker/login_signup_seeker.dart new file mode 100644 index 0000000..b4cdf63 --- /dev/null +++ b/lib/src/ui/auth/seeker/login_signup_seeker.dart @@ -0,0 +1,383 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; + +import 'package:space/src/core/models/http_exception.dart'; +import 'package:space/src/core/models/auth.dart'; + +enum AuthMode { Signup, Login } + +class LoginSignUpSeeker extends StatelessWidget { + static const routeName = '/auth'; + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/vector-5.png'), + fit: BoxFit.cover, + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + body: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.only(top: 20, bottom: 10), + child:Container( + alignment: Alignment.center, + child: Image.asset('assets/logo_vertical.png'), + height: 80, + ), + ), + Flexible( + child: AuthCard(), + ), + ], + ), + ), + ); + } +} + +class AuthCard extends StatefulWidget { + const AuthCard({ + Key key, + }) : super(key: key); + + @override + _AuthCardState createState() => _AuthCardState(); +} + +class _AuthCardState extends State { + final GlobalKey _formKey = GlobalKey(); + AuthMode _authMode = AuthMode.Login; + Map _authData = { + 'email': '', + 'password': '', + }; + var _isLoading = false; + final _passwordController = TextEditingController(); + + void _showErrorDialog(String message) { + showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text('An Error Occurred!'), + content: Text(message), + actions: [ + FlatButton( + child: Text('Okay'), + onPressed: () { + Navigator.of(ctx).pop(); + }, + ) + ], + ), + ); + } + + Future _submit() async { + if (!_formKey.currentState.validate()) { + // Invalid! + return; + } + _formKey.currentState.save(); + setState(() { + _isLoading = true; + }); + try { + if (_authMode == AuthMode.Login) { + // Log user in + await Provider.of(context, listen: false).login( + _authData['email'], + _authData['password'], + ); + } else { + // Sign user up + await Provider.of(context, listen: false).signup( + _authData['email'], + _authData['password'], + ); + } + } on HttpException catch (error) { + var errorMessage = 'Authentication failed'; + if (error.toString().contains('EMAIL_EXISTS')) { + errorMessage = 'This email address is already in use.'; + } else if (error.toString().contains('INVALID_EMAIL')) { + errorMessage = 'This is not a valid email address'; + } else if (error.toString().contains('WEAK_PASSWORD')) { + errorMessage = 'This password is too weak.'; + } else if (error.toString().contains('EMAIL_NOT_FOUND')) { + errorMessage = 'Could not find a user with that email.'; + } else if (error.toString().contains('INVALID_PASSWORD')) { + errorMessage = 'Invalid password.'; + } + _showErrorDialog(errorMessage); + } catch (error) { + const errorMessage = + 'Could not authenticate you. Please try again later.'; + _showErrorDialog(errorMessage); + } + + setState(() { + _isLoading = false; + }); + } + + void _switchAuthMode() { + if (_authMode == AuthMode.Login) { + setState(() { + _authMode = AuthMode.Signup; + }); + } else { + setState(() { + _authMode = AuthMode.Login; + }); + } + } + + @override + Widget build(BuildContext context) { + return Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + children: [ + Column(children: [ + Text((_authMode == AuthMode.Login ? 'LOGIN AN ACCOUNT' : 'SIGN UP AN ACCOUNT'), + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.white, fontSize: 14) + ), + ], + ), + Row(children: [ + Expanded( + child: new Container( + margin: const EdgeInsets.only(left: 120, right: 120), + child: Divider( + thickness: 2, + color: Color(0xff22c0e8), + height: 30)), + ) + ] + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 5), + child: TextFormField( + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + errorStyle: TextStyle(color: Theme.of(context).errorColor), + hintText: 'E-mail', + hintStyle: TextStyle(color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + errorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8)), + borderRadius: BorderRadius.all(Radius.circular(30))), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.transparent), + borderRadius: BorderRadius.all(Radius.circular(30))), + ), + keyboardType: TextInputType.emailAddress, + validator: (value) { + if (value.isEmpty || !value.contains('@')) { + return 'Invalid email!'; + } + }, + onSaved: (value) { + _authData['email'] = value; + }, + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 5), + child: TextFormField( + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + errorStyle: TextStyle(color: Theme.of(context).errorColor), + hintText: 'Password', + hintStyle: TextStyle(color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + errorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8)), + borderRadius: BorderRadius.all(Radius.circular(30))), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.transparent), + borderRadius: BorderRadius.all(Radius.circular(30))), + ), + obscureText: true, + controller: _passwordController, + validator: (value) { + if (value.isEmpty || value.length < 5) { + return 'Password is too short!'; + } + }, + onSaved: (value) { + _authData['password'] = value; + }, + ), + ), + if (_authMode == AuthMode.Signup) + + Padding( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 5), + child: TextFormField( + enabled: _authMode == AuthMode.Signup, + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + errorStyle: TextStyle(color: Theme.of(context).errorColor), + hintText: 'Confirm Password', + hintStyle: TextStyle(color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + errorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Theme.of(context).errorColor), + borderRadius: BorderRadius.all(Radius.circular(30))), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8)), + borderRadius: BorderRadius.all(Radius.circular(30))), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.transparent), + borderRadius: BorderRadius.all(Radius.circular(30))), + ), + obscureText: true, + validator: _authMode == AuthMode.Signup + ? (value) { + if (value != _passwordController.text) { + return 'Passwords do not match!'; + } + } + : null, + ), + ), + SizedBox( + height: 20, + ), + if (_isLoading) + CircularProgressIndicator( + backgroundColor: Color(0xff22c0e8), + ) + else + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MaterialButton( + minWidth: 160, + child: + Text(_authMode == AuthMode.Login ? 'Login' : 'Sign Up'), + onPressed: _submit, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + padding: + EdgeInsets.symmetric(horizontal: 30.0, vertical: 8.0), + color: (_authMode == AuthMode.Login ? Color(0xff57b22f) : Color(0xff22c0e8)), + textColor: Colors.white, + ), + SizedBox(width: 10), + MaterialButton( + minWidth: 160, + child: Text( + '${_authMode == AuthMode.Login ? 'Sign up' : 'Login'} an account'), + onPressed: _switchAuthMode, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 4), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + color: (_authMode == AuthMode.Login ? Color(0xff22c0e8) : Color(0xff57b22f)), + textColor: Colors.white, + ), + ], + ), + SizedBox(height: 15), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(left: 20, right: 10), + child: Divider(thickness: 0.5, color: Colors.white,), + ), + ), + Text('OR', style: TextStyle(fontSize: 11, color: Colors.white70)), + Expanded( + child: Container( + margin: EdgeInsets.only(right: 20, left: 10), + child: Divider(thickness: 0.5, color: Colors.white,), + ), + ), + ], + ), + SizedBox(height: 15), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + color: Color(0xff2d67a5), + minWidth: 160, + onPressed: () {}, + child: Row( + children: [ + Icon(MdiIcons.facebook, size: 20, color: Colors.white), + Text("Login with Facebook", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, fontSize: 11)), + ], + ), + ), + + SizedBox(width: 10), + + MaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + color: Colors.white, + minWidth: 160, + onPressed: () {}, + child: Row( + children: [ + Image.asset('assets/gmail.png', height: 12), + Text(" Login with Gmail", + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0xff8997a7), fontSize: 11)), + ], + ), + ), + ], + ), + SizedBox(height: 70) + ], + ), + ), + + ); + } +} diff --git a/lib/src/ui/auth/seeker/register_seeker.dart b/lib/src/ui/auth/seeker/register_seeker.dart new file mode 100644 index 0000000..f864cf2 --- /dev/null +++ b/lib/src/ui/auth/seeker/register_seeker.dart @@ -0,0 +1,233 @@ +import 'package:flutter/material.dart'; + +class RegisterSeeker extends StatefulWidget { + + static const routeName = 'register_seeker'; + + @override + _RegisterSeekerState createState() => _RegisterSeekerState(); +} + +class _RegisterSeekerState extends State { +TextStyle style = TextStyle(fontFamily: 'VarelaRound'); + + @override + Widget build(BuildContext context) { + + final textBody = + Column(children: [ + Column(children: [ + Text("REGISTER AN ACCOUNT", + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: style.copyWith( + color: Color(0xff2c4057), fontSize: 12) + ), + ], + ), + Row(children: [ + Expanded( + child: new Container( + margin: const EdgeInsets.only(left: 70.0, right: 70.0), + child: Divider( + thickness: 2, + color: Color(0xff22c0e8), + height: 30)), + ) + ] + ) + ] + ); + + + final usernameField = TextFormField( + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: "Choose a Username", + hintStyle: style.copyWith(color: Color(0xff8997a7)), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Column can\'t be empty' : null + ); + + final emailField = TextFormField( + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: "Enter Your Email Address", + hintStyle: style.copyWith(color: Color(0xff8997a7)), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Column can\'t be empty' : null + ); + + final passwordField = new TextFormField( + obscureText: true, + style: style.copyWith( + + color: Colors.black45, + fontSize: 12, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: "Password", + hintStyle: style.copyWith(color: Color(0xff8997a7), fontSize: 12), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Column can\'t be empty' : null + ); + + final confirmPassword = new TextFormField( + obscureText: true, + style: style.copyWith( + color: Colors.black45, + fontSize: 12, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + ), + decoration: new InputDecoration( + contentPadding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + hintText: "Confirm Password", + hintStyle: style.copyWith(color: Color(0xff8997a7), fontSize: 12), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(30.0)), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + )), + validator: (value) => value.isEmpty ? 'Column can\'t be empty' : null + ); + + final regButton = Material( + elevation: 3.0, + borderRadius: BorderRadius.all(Radius.circular(50)), + color: Color(0xff22c0e8), + child: MaterialButton( + padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), + onPressed: () { + // showDialog( + // context: context,builder: (_) => FlareGiffyDialog( + // flarePath: 'assets/space_demo.flr', + // flareAnimation: 'loading', + // title: Text('Sedang Loading', + // style: style.copyWith( + // fontSize: 22.0, fontWeight: FontWeight.w500), + // ), + // description: Text('Silahkan tunggu...', + // textAlign: TextAlign.center, + // style: style.copyWith(), + // ), + // onOkButtonPressed: () {}, + // ) ); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text('Register Now', + textAlign: TextAlign.center, + style: style.copyWith( + + color: Color(0xffffffff), + fontSize: 14, + fontWeight: FontWeight.w500, + ) + ), + Icon(Icons.arrow_forward, color: Colors.white, size: 18,), + ], + ), + ), + ); + +return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Scaffold( + body: SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Container( + padding: EdgeInsets.only(left: 60, right: 60, bottom: 30), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + textBody, + SizedBox( + height: 10.0, + ), + usernameField, + SizedBox( + height: 25.0), + emailField, + SizedBox( + height: 25.0), + passwordField, + SizedBox( + height: 25.0), + confirmPassword, + SizedBox( + height: 25.0, + ), + regButton, + SizedBox( + height: 15.0, + ), + Text("LOGIN TO YOUR EXISTING ACCOUNT", + style: style.copyWith( + color: Color(0xff8997a7), + fontSize: 9, + + fontStyle: FontStyle.normal, + letterSpacing: 0.55, + ) + ), + SizedBox( + height: 50.0, + ), + ], + + ), + ), + ), + ), + ); + } + ); + } + } diff --git a/lib/src/ui/auth/seeker/ui_get_started_seeker.dart b/lib/src/ui/auth/seeker/ui_get_started_seeker.dart new file mode 100644 index 0000000..b0bd8d7 --- /dev/null +++ b/lib/src/ui/auth/seeker/ui_get_started_seeker.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:space/navigator_seeker.dart'; + +class UiGetStartedSeeker extends StatelessWidget { + + @override + Widget build(BuildContext context) { + TextStyle style = TextStyle(fontFamily: 'Quicksand-Regular', fontSize: 20.0); + return Scaffold( + body: Padding( + padding: EdgeInsets.fromLTRB(40, 50, 40, 50), + child: Container( + height: MediaQuery.of(context).size.height, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 60), + child: Image.asset('assets/logo_vertical.png') + ), + Text('Are you ready to chase your dreams?', + textAlign: TextAlign.center, + style: style.copyWith(fontSize: 40, color: Color(0xff3b3b3b), fontWeight: FontWeight.bold)), + Text('Make your dreams come true by start working. Find jobs which suit you. Easy to apply, no paper, no writing. Just type and upload.', + textAlign: TextAlign.center, + style: style.copyWith(fontSize: 17.2, color: Color(0x99383839), fontWeight: FontWeight.w600)), + ButtonTheme( + minWidth: 190, + height: 55, + child: RaisedButton( + color: Color(0xff57b22f), + onPressed: () { Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => SeekerNavigator())); + }, + child: Text('Get Started', style: style.copyWith(fontSize: 24, color: Colors.white, fontWeight: FontWeight.bold)), + ), + ), + ButtonTheme( + minWidth: 190, + height: 55, + child: OutlineButton( + highlightedBorderColor: Color(0xff57b22f), + borderSide: BorderSide(color: Color(0xff57b22f)), + onPressed: () { Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => SeekerNavigator())); + }, + child: Text('Try Trial', style: style.copyWith(fontSize: 24, color: Color(0xff57b22f), fontWeight: FontWeight.bold)), + ), + ), + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/chat/inbox_ui_chat.dart b/lib/src/ui/chat/inbox_ui_chat.dart new file mode 100644 index 0000000..c43cdfb --- /dev/null +++ b/lib/src/ui/chat/inbox_ui_chat.dart @@ -0,0 +1,299 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + + +class InboxUiList extends StatefulWidget { + const InboxUiList({ Key key, String title }) : super(key: key); + @override + _InboxUiListState createState() => _InboxUiListState(); +} + +class _InboxUiListState extends State with SingleTickerProviderStateMixin { + + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + + return new Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context,true); + }, + icon: Icon(FeatherIcons.chevronLeft, color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Row(children:[ + Stack( + alignment: Alignment(1, -1), + children:[ + CircleAvatar( + backgroundColor: Color(0xff757575), + radius: 20.0, + child: Image.asset('assets/img_profile-2.png', scale: 3.3,), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.white, + ), + child: Icon(Icons.brightness_1, size: 10, color: Color(0xff81c784)), + ), + + ], + ), + Container( + padding: EdgeInsets.only(left: 20), + child:Text('Mekuru Ramen', style: style.copyWith(color: Color(0xff2c4057), + fontSize: 18, fontWeight: FontWeight.w600,letterSpacing: 1)), + ), + ], + ), + centerTitle: true, + actions: [ + // action button + IconButton( + icon: Icon(Icons.videocam, color: Color(0xff4d4d4d), size: 33), + onPressed: () {}, + ), + ], + ), + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(top: 15), + child: Column( + children: [ + Stack( + children: [ + Container( + alignment: AlignmentDirectional.topEnd, + margin: EdgeInsets.fromLTRB(0, 10, 15, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + new Container( + width: 350, + padding: EdgeInsets.fromLTRB(35, 15, 15, 15), + margin: EdgeInsets.only(bottom: 5), + decoration: new BoxDecoration( + color: Color(0xffffffff), + borderRadius: BorderRadius.circular(5), + boxShadow: [BoxShadow( + color: Color(0x11000000), + offset: Offset(2.121320343559643,2.1213203435596424), + blurRadius: 21, + spreadRadius: 0 + ) ], + ), + child: Column( + children: [ + Text('Hello, nice to see you again today. Hope you are well.', + style: style.copyWith(fontSize: 16, color: Color(0xff757575))), + + ], + ), + ), + Text('03:41 PM', style: style.copyWith(fontSize: 12, color: Color(0xff757575))), + ], + ), + ), + Stack( + alignment: AlignmentDirectional.topStart, + children: [ + Container(), + Container( + margin: EdgeInsets.only(top: 20, left: 30), + child: Stack( + alignment: Alignment(1, -1), + children:[ + CircleAvatar( + backgroundColor: Color(0xff757575), + radius: 20.0, + child: Image.asset('assets/img_profile-2.png', scale: 3.3,), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.white, + ), + child: Icon(Icons.brightness_1, size: 10, color: Color(0xff81c784)), + ), + ], + ), + ), + ], + ), + ], + ), + + Stack( + children: [ + Container( + alignment: AlignmentDirectional.topStart, + margin: EdgeInsets.fromLTRB(10, 10, 0, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + new Container( + width: 350, + padding: EdgeInsets.fromLTRB(15, 15, 35, 15), + margin: EdgeInsets.only(bottom: 5), + decoration: new BoxDecoration( + color: Color(0xffffffff), + borderRadius: BorderRadius.circular(5), + boxShadow: [BoxShadow( + color: Color(0x11000000), + offset: Offset(2.121320343559643,2.1213203435596424), + blurRadius: 21, + spreadRadius: 0 + ) ], + ), + child: Column( + children: [ + Text('This is my office location. You can visit as per your time.', + style: style.copyWith(fontSize: 16, color: Color(0xff757575))), + new Container( + height: 200, + decoration: new BoxDecoration( + color: Color(0xffbdbdbd), + boxShadow: [BoxShadow( + color: Color(0x11000000), + offset: Offset(2.121320343559643,2.1213203435596424), + blurRadius: 21, + spreadRadius: 0 + ) ], + ) + ), + ], + ), + ), + Text('03:42 PM', style: style.copyWith(fontSize: 12, color: Color(0xff757575))), + ], + ), + ), + Stack( + alignment: AlignmentDirectional.topEnd, + children: [ + Container(), + Container( + margin: EdgeInsets.only(top: 20, right: 30), + child: Stack( + alignment: Alignment(1, -1), + children:[ + CircleAvatar( + backgroundColor: Color(0xff757575), + radius: 20.0, + child: Image.asset('assets/img_profile-1.png', scale: 3.3,), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.white, + ), + child: Icon(Icons.brightness_1, size: 10, color: Color(0xff81c784)), + ), + ], + ), + ), + ], + ), + ], + ), + + Stack( + children: [ + Container( + alignment: AlignmentDirectional.topEnd, + margin: EdgeInsets.fromLTRB(0, 10, 15, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + new Container( + width: 350, + padding: EdgeInsets.fromLTRB(35, 15, 15, 15), + margin: EdgeInsets.only(bottom: 5), + decoration: new BoxDecoration( + color: Color(0xffffffff), + borderRadius: BorderRadius.circular(5), + boxShadow: [BoxShadow( + color: Color(0x11000000), + offset: Offset(2.121320343559643,2.1213203435596424), + blurRadius: 21, + spreadRadius: 0 + ) ], + ), + child: Column( + children: [ + Text('Sure, I will visit the location in evening. Is that alright for you.', + style: style.copyWith(fontSize: 16, color: Color(0xff757575))), + + ], + ), + ), + Text('03:43 PM', style: style.copyWith(fontSize: 12, color: Color(0xff757575))), + ], + ), + ), + Stack( + alignment: AlignmentDirectional.topStart, + children: [ + Container(), + Container( + margin: EdgeInsets.only(top: 20, left: 30), + child: Stack( + alignment: Alignment(1, -1), + children:[ + CircleAvatar( + backgroundColor: Color(0xff757575), + radius: 20.0, + child: Image.asset('assets/img_profile-2.png', scale: 3.3,), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.white, + ), + child: Icon(Icons.brightness_1, size: 10, color: Color(0xff81c784)), + ), + ], + ), + ), + ], + ), + ], + ), + + ], + ), + ), + ), + floatingActionButton: Container( + padding: EdgeInsets.fromLTRB(40, 10, 10, 0), + child: new TextField( + style: style.copyWith(fontSize: 16, color: Color(0xff757575)), + decoration: new InputDecoration( + suffixIcon: Padding( + padding: const EdgeInsetsDirectional.only(end: 12.0), + child: Icon(Icons.place), + ), + + border: new OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(100.0), + ), + ), + filled: true, + hintStyle: style.copyWith(color: Color(0xffaaaaaa), fontSize: 16), + hintText: "Message", + fillColor: Colors.white), + ), + ), + + + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/chat/inbox_ui_empty.dart b/lib/src/ui/chat/inbox_ui_empty.dart new file mode 100644 index 0000000..018b41c --- /dev/null +++ b/lib/src/ui/chat/inbox_ui_empty.dart @@ -0,0 +1,345 @@ +// import 'package:flutter/material.dart'; +// import 'dart:async'; + +// import 'package:agora_rtm/agora_rtm.dart'; + + +// class InboxNoMessage extends StatefulWidget { +// @override +// _InboxNoMessageState createState() => _InboxNoMessageState(); +// } + +// class _InboxNoMessageState extends State with SingleTickerProviderStateMixin { + +// TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); +// bool _isLogin = false; +// bool _isInChannel = false; + +// final _userNameController = TextEditingController(); +// final _peerUserIdController = TextEditingController(); +// final _peerMessageController = TextEditingController(); +// final _channelNameController = TextEditingController(); +// final _channelMessageController = TextEditingController(); + +// final _infoStrings = []; + +// AgoraRtmClient _client; +// AgoraRtmChannel _channel; + +// @override +// void initState() { +// super.initState(); +// _createClient(); +// } + +// @override +// Widget build(BuildContext context) { + +// return new Scaffold( +// backgroundColor: Colors.white, +// body: Container( +// padding: EdgeInsets.only(top: 50, left: 30, right: 30), +// child: Column( +// children: [ +// _buildLogin(), +// _buildQueryOnlineStatus(), +// _buildSendPeerMessage(), +// _buildJoinChannel(), +// _buildGetMembers(), +// _buildSendChannelMessage(), +// _buildInfoList(), +// ], +// ), + +// ), +// ); +// } + + +// void _createClient() async { +// _client = +// await AgoraRtmClient.createInstance('6389279af2b74d949734539ba2fb66d8'); +// _client.onMessageReceived = (AgoraRtmMessage message, String peerId) { +// _log("Peer msg: " + peerId + ", msg: " + message.text); +// }; +// _client.onConnectionStateChanged = (int state, int reason) { +// _log('Connection state changed: ' + +// state.toString() + +// ', reason: ' + +// reason.toString()); +// if (state == 5) { +// _client.logout(); +// _log('Logout.'); +// setState(() { +// _isLogin = false; +// }); +// } +// }; +// } + +// Future _createChannel(String name) async { +// AgoraRtmChannel channel = await _client.createChannel(name); +// channel.onMemberJoined = (AgoraRtmMember member) { +// _log( +// "Member joined: " + member.userId + ', channel: ' + member.channelId); +// }; +// channel.onMemberLeft = (AgoraRtmMember member) { +// _log("Member left: " + member.userId + ', channel: ' + member.channelId); +// }; +// channel.onMessageReceived = +// (AgoraRtmMessage message, AgoraRtmMember member) { +// _log("Channel msg: " + member.userId + ", msg: " + message.text); +// }; +// return channel; +// } + +// static TextStyle textStyle = TextStyle(fontSize: 18, color: Colors.blue); + +// Widget _buildLogin() { +// return Row(children: [ +// _isLogin +// ? new Expanded( +// child: new Text('User Id: ' + _userNameController.text, +// style: textStyle)) +// : new Expanded( +// child: new TextField( +// controller: _userNameController, +// decoration: InputDecoration(hintText: 'Input your user id'))), +// new OutlineButton( +// child: Text(_isLogin ? 'Logout' : 'Login', style: textStyle), +// onPressed: _toggleLogin, +// ) +// ]); +// } + +// Widget _buildQueryOnlineStatus() { +// if (!_isLogin) { +// return Container(); +// } +// return Row(children: [ +// new Expanded( +// child: new TextField( +// controller: _peerUserIdController, +// decoration: InputDecoration(hintText: 'Input peer user id'))), +// new OutlineButton( +// child: Text('Query Online', style: textStyle), +// onPressed: _toggleQuery, +// ) +// ]); +// } + +// Widget _buildSendPeerMessage() { +// if (!_isLogin) { +// return Container(); +// } +// return Row(children: [ +// new Expanded( +// child: new TextField( +// controller: _peerMessageController, +// decoration: InputDecoration(hintText: 'Input peer message'))), +// new OutlineButton( +// child: Text('Send to Peer', style: textStyle), +// onPressed: _toggleSendPeerMessage, +// ) +// ]); +// } + +// Widget _buildJoinChannel() { +// if (!_isLogin) { +// return Container(); +// } +// return Row(children: [ +// _isInChannel +// ? new Expanded( +// child: new Text('Channel: ' + _channelNameController.text, +// style: textStyle)) +// : new Expanded( +// child: new TextField( +// controller: _channelNameController, +// decoration: InputDecoration(hintText: 'Input channel id'))), +// new OutlineButton( +// child: Text(_isInChannel ? 'Leave Channel' : 'Join Channel', +// style: textStyle), +// onPressed: _toggleJoinChannel, +// ) +// ]); +// } + +// Widget _buildSendChannelMessage() { +// if (!_isLogin || !_isInChannel) { +// return Container(); +// } +// return Row(children: [ +// new Expanded( +// child: new TextField( +// controller: _channelMessageController, +// decoration: InputDecoration(hintText: 'Input channel message'))), +// new OutlineButton( +// child: Text('Send to Channel', style: textStyle), +// onPressed: _toggleSendChannelMessage, +// ) +// ]); +// } + +// Widget _buildGetMembers() { +// if (!_isLogin || !_isInChannel) { +// return Container(); +// } +// return Row(children: [ +// new OutlineButton( +// child: Text('Get Members in Channel', style: textStyle), +// onPressed: _toggleGetMembers, +// ) +// ]); +// } + +// Widget _buildInfoList() { +// return Expanded( +// child: Container( +// child: ListView.builder( +// itemExtent: 24, +// itemBuilder: (context, i) { +// return ListTile( +// contentPadding: const EdgeInsets.all(0.0), +// title: Text(_infoStrings[i]), +// ); +// }, +// itemCount: _infoStrings.length, +// ))); +// } + +// void _toggleLogin() async { +// if (_isLogin) { +// try { +// await _client.logout(); +// _log('Logout success.'); + +// setState(() { +// _isLogin = false; +// _isInChannel = false; +// }); +// } catch (errorCode) { +// _log('Logout error: ' + errorCode.toString()); +// } +// } else { +// String userId = _userNameController.text; +// if (userId.isEmpty) { +// _log('Please input your user id to login.'); +// return; +// } + +// try { +// await _client.login(null, userId); +// _log('Login success: ' + userId); +// setState(() { +// _isLogin = true; +// }); +// } catch (errorCode) { +// _log('Login error: ' + errorCode.toString()); +// } +// } +// } + +// void _toggleQuery() async { +// String peerUid = _peerUserIdController.text; +// if (peerUid.isEmpty) { +// _log('Please input peer user id to query.'); +// return; +// } +// try { +// Map result = +// await _client.queryPeersOnlineStatus([peerUid]); +// _log('Query result: ' + result.toString()); +// } catch (errorCode) { +// _log('Query error: ' + errorCode.toString()); +// } +// } + +// void _toggleSendPeerMessage() async { +// String peerUid = _peerUserIdController.text; +// if (peerUid.isEmpty) { +// _log('Please input peer user id to send message.'); +// return; +// } + +// String text = _peerMessageController.text; +// if (text.isEmpty) { +// _log('Please input text to send.'); +// return; +// } + +// try { +// AgoraRtmMessage message = AgoraRtmMessage.fromText(text); +// _log(message.text); +// await _client.sendMessageToPeer(peerUid, message, false); +// _log('Send peer message success.'); +// } catch (errorCode) { +// _log('Send peer message error: ' + errorCode.toString()); +// } +// } + +// void _toggleJoinChannel() async { +// if (_isInChannel) { +// try { +// await _channel.leave(); +// _log('Leave channel success.'); +// _client.releaseChannel(_channel.channelId); +// _channelMessageController.text = null; + +// setState(() { +// _isInChannel = false; +// }); +// } catch (errorCode) { +// _log('Leave channel error: ' + errorCode.toString()); +// } +// } else { +// String channelId = _channelNameController.text; +// if (channelId.isEmpty) { +// _log('Please input channel id to join.'); +// return; +// } + +// try { +// _channel = await _createChannel(channelId); +// await _channel.join(); +// _log('Join channel success.'); + +// setState(() { +// _isInChannel = true; +// }); +// } catch (errorCode) { +// _log('Join channel error: ' + errorCode.toString()); +// } +// } +// } + +// void _toggleGetMembers() async { +// try { +// List members = await _channel.getMembers(); +// _log('Members: ' + members.toString()); +// } catch (errorCode) { +// _log('GetMembers failed: ' + errorCode.toString()); +// } +// } + +// void _toggleSendChannelMessage() async { +// String text = _channelMessageController.text; +// if (text.isEmpty) { +// _log('Please input text to send.'); +// return; +// } +// try { +// await _channel.sendMessage(AgoraRtmMessage.fromText(text)); +// _log('Send channel message success.'); +// } catch (errorCode) { +// _log('Send channel message error: ' + errorCode.toString()); +// } +// } + +// void _log(String info) { +// print(info); +// setState(() { +// _infoStrings.insert(0, info); +// }); +// } +// } diff --git a/lib/src/ui/chat/inbox_ui_list.dart b/lib/src/ui/chat/inbox_ui_list.dart new file mode 100644 index 0000000..4f255ae --- /dev/null +++ b/lib/src/ui/chat/inbox_ui_list.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; + + +class InboxUiList extends StatefulWidget { + + @override + _InboxUiListState createState() => _InboxUiListState(); +} + +class _InboxUiListState extends State with SingleTickerProviderStateMixin { + + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + + return Scaffold( + backgroundColor: Colors.white, + body: Container( + padding: EdgeInsets.only(top: 50, left: 30, right: 30), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Inbox', style: style.copyWith(fontSize: 32, fontWeight: FontWeight.w600, color: Color(0xff3b3b3b))), + + SingleChildScrollView( + child:Container( + child: Column(children: [ + + SizedBox( + height: 30, + ), + ListTile( + leading: Stack( + alignment: Alignment(1, -1), + children:[ + CircleAvatar( + backgroundColor: Color(0xff757575), + radius: 20.0, + child: Image.asset('assets/img_profile-1.png', scale: 3.3,), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.white, + ), + child: Icon(Icons.brightness_1, size: 10, color: Color(0xff81c784)), + ), + + ], + ), + title: Text('Mekuru Ramen', style: style.copyWith(fontSize: 16, color: Color(0xff757575))), + subtitle: Text('Hello, New job offers for you', style: style.copyWith(fontSize: 14, color: Color(0xff757575))), + trailing: Text('03:57 AM', style: style.copyWith(fontSize: 12, color: Color(0xff757575))), + ), + + Container( + height: 30, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + + ListTile( + leading: Stack( + alignment: Alignment(1, -1), + children:[ + CircleAvatar( + backgroundColor: Color(0xff757575), + radius: 20.0, + child: Image.asset('assets/img_profile-1.png', scale: 3.3,), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.white, + ), + child: Icon(Icons.brightness_1, size: 10, color: Color(0xfffca467)), + ), + + ], + ), + title: Text('Diamonds Group', style: style.copyWith(fontSize: 16, color: Color(0xff757575))), + subtitle: Text('Hello, New job offers for you', style: style.copyWith(fontSize: 14, color: Color(0xff757575))), + trailing: Text('03:57 AM', style: style.copyWith(fontSize: 12, color: Color(0xff757575))), + ), + + Container( + height: 30, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + + ListTile( + leading: Stack( + alignment: Alignment(1, -1), + children:[ + CircleAvatar( + backgroundColor: Color(0xff757575), + radius: 20.0, + child: Image.asset('assets/img_profile-1.png', scale: 3.3,), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.white, + ), + child: Icon(Icons.brightness_1, size: 10, color: Color(0xfffc6767)), + ), + + ], + ), + title: Text('Pull n Beat', style: style.copyWith(fontSize: 16, color: Color(0xff757575))), + subtitle: Text('Hello, New job offers for you', style: style.copyWith(fontSize: 14, color: Color(0xff757575))), + trailing: Text('03:57 AM', style: style.copyWith(fontSize: 12, color: Color(0xff757575))), + ), + Container( + height: 30, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + ], + ), + ), + ), + ],) + ), + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/chat/video_ongoing_call.dart b/lib/src/ui/chat/video_ongoing_call.dart new file mode 100644 index 0000000..e395e8c --- /dev/null +++ b/lib/src/ui/chat/video_ongoing_call.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + ), + home: const Oncalling(), +); + } +} + + +class Oncalling extends StatefulWidget { + const Oncalling({ Key key, String title }) : super(key: key); + @override + _OncallingState createState() => _OncallingState(); +} + +class _OncallingState extends State with SingleTickerProviderStateMixin { + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 24.0, color: Colors.white); + + @override + Widget build(BuildContext context) { + + return new Scaffold( + body: Container( + padding: EdgeInsets.only(bottom: 30, left: 30), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/background-2.png'), + fit: BoxFit.cover + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MaterialButton( + padding: EdgeInsets.all(10), + onPressed: (){}, + child: Icon(Icons.mic_off, color: Colors.white, size: 35), + color: Colors.transparent, + shape: CircleBorder(side: BorderSide(color: Colors.white)) + ), + SizedBox( + height: 10, + ), + MaterialButton( + padding: EdgeInsets.all(10), + onPressed: (){}, + child: Icon(Icons.call_end, color: Colors.white, size: 35), + color: Color(0xfffd2e61), + shape: CircleBorder() + ), + SizedBox( + height: 10, + ), + MaterialButton( + padding: EdgeInsets.all(10), + onPressed: (){}, + child: Icon(Icons.volume_up, color: Colors.white, size: 35), + color: Colors.transparent, + shape: CircleBorder(side: BorderSide(color: Colors.white)) + ), + SizedBox( + height: 10, + ), + Container( + height: 200, + width: 140, + child: Image.asset('assets/ketapang.png', fit: BoxFit.cover), + ) + ],), + + + + + + + ), + + + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/chat/video_ui_calling.dart b/lib/src/ui/chat/video_ui_calling.dart new file mode 100644 index 0000000..c048be5 --- /dev/null +++ b/lib/src/ui/chat/video_ui_calling.dart @@ -0,0 +1,102 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + ), + home: const Calling(), +); + } +} + + +class Calling extends StatefulWidget { + const Calling({ Key key, String title }) : super(key: key); + @override + _CallingState createState() => _CallingState(); +} + +class _CallingState extends State with SingleTickerProviderStateMixin { + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 24.0, color: Colors.white); + + @override + Widget build(BuildContext context) { + + return new Scaffold( + body: Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/background-2.png'), + colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.7), BlendMode.multiply), + fit: BoxFit.cover + ), + ), + child: Container( + margin: EdgeInsets.only(top: 80, bottom: 60), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + CircleAvatar( + backgroundColor: Colors.white, + radius: 80, + child: Image.asset('assets/mekuru_2.png', fit: BoxFit.cover), + ), + SizedBox( + height:20 + ), + Text('Mekuru Ramen', style: style.copyWith()), + SizedBox( + height:20 + ), + Text('contacting...', style: style.copyWith(fontSize: 18)), + ],), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + MaterialButton( + padding: EdgeInsets.all(20), + onPressed: (){}, + child: Icon(Icons.mic_off, color: Colors.white, size: 35), + color: Colors.transparent, + shape: CircleBorder(side: BorderSide(color: Colors.white)) + ), + MaterialButton( + padding: EdgeInsets.all(20), + onPressed: (){}, + child: Icon(Icons.call_end, color: Colors.white, size: 35), + color: Color(0xfffd2e61), + shape: CircleBorder() + ), + MaterialButton( + padding: EdgeInsets.all(20), + onPressed: (){}, + child: Icon(Icons.volume_up, color: Colors.white, size: 35), + color: Colors.transparent, + shape: CircleBorder(side: BorderSide(color: Colors.white)) + ), + ],), + + + + ],), + ), + + ), + + + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/chat/video_ui_incoming.dart b/lib/src/ui/chat/video_ui_incoming.dart new file mode 100644 index 0000000..c0eed62 --- /dev/null +++ b/lib/src/ui/chat/video_ui_incoming.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + ), + home: const IncomingCall(), +); + } +} + + +class IncomingCall extends StatefulWidget { + const IncomingCall({ Key key, String title }) : super(key: key); + @override + _IncomingCallState createState() => _IncomingCallState(); +} + +class _IncomingCallState extends State with SingleTickerProviderStateMixin { + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 24.0, color: Colors.white); + + @override + Widget build(BuildContext context) { + + return new Scaffold( + body: Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/background-2.png'), + colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.7), BlendMode.multiply), + fit: BoxFit.cover + ), + ), + child: Container( + margin: EdgeInsets.only(top: 130, bottom: 60), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + CircleAvatar( + backgroundColor: Colors.white, + radius: 80, + child: Image.asset('assets/mekuru_2.png', fit: BoxFit.cover), + ), + SizedBox( + height:20 + ), + Text('Mekuru Ramen', style: style.copyWith()), + ],), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + MaterialButton( + padding: EdgeInsets.all(20), + onPressed: (){}, + child: Icon(Icons.phone, color: Colors.white, size: 35), + color: Color(0xff57b22f), + shape: CircleBorder() + ), + MaterialButton( + padding: EdgeInsets.all(20), + onPressed: (){}, + child: Icon(Icons.call_end, color: Colors.white, size: 35), + color: Color(0xfffd2e61), + shape: CircleBorder() + ) + ],), + + + + ],), + ), + + ), + + + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/components/badge.dart b/lib/src/ui/components/badge.dart new file mode 100644 index 0000000..591cc67 --- /dev/null +++ b/lib/src/ui/components/badge.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; + +class Badge extends StatelessWidget { + const Badge({ + Key key, + @required this.child, + @required this.value, + this.color, + }) : super(key: key); + + final Widget child; + final String value; + final Color color; + + @override + Widget build(BuildContext context) { + return Stack( + alignment: Alignment.center, + children: [ + child, + Positioned( + right: 4, + top: 4, + child: Container( + padding: EdgeInsets.all(2.0), + // color: Theme.of(context).accentColor, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: color != null ? color : Theme.of(context).accentColor, + ), + constraints: BoxConstraints( + minWidth: 16, + minHeight: 16, + ), + child: Text( + value, + textAlign: TextAlign.center, + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 10, + color: Theme.of(context).primaryTextTheme.title.color), + ), + ), + ) + ], + ); + } +} diff --git a/lib/src/ui/components/horizontal_list.dart b/lib/src/ui/components/horizontal_list.dart new file mode 100644 index 0000000..dbf4b56 --- /dev/null +++ b/lib/src/ui/components/horizontal_list.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_money_formatter/flutter_money_formatter.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/job.dart'; +import 'package:space/src/ui/seeker/layout/job_details.dart'; + +class HorizontalList extends StatelessWidget { + @override + Widget build(BuildContext context) { + final job = Provider.of(context, listen: false); + return Row( + children: [ + Container( + padding: EdgeInsets.all(5), + child: MaterialButton( + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), + onPressed: () { + Navigator.of(context) + .pushNamed(JobDetails.routeName, arguments: job.id); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Container( + padding: EdgeInsets.all(10), + height: 100, + width: 100, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20)), + child: Text('Image.network(job.imageUrl)'), + )), + Text('job.employerName', + style: TextStyle( + fontSize: 12, fontWeight: FontWeight.bold, height: 2)), + Text(job.title, + style: + TextStyle(fontSize: 10, fontWeight: FontWeight.bold)), + Row( + children: [ + Text('Salary: ', style: TextStyle(fontSize: 8)), + Text( + FlutterMoneyFormatter( + amount: job.salary, + settings: MoneyFormatterSettings( + symbol: 'Rp', + thousandSeparator: '.', + fractionDigits: 0)) + .output + .symbolOnLeft, + style: TextStyle(fontSize: 8)), + ], + ), + Text(job.workingday, style: TextStyle(fontSize: 8)), + Text(job.workinghour, style: TextStyle(fontSize: 8)), + ], + ), + ), + ), + ], + ); + } +} diff --git a/lib/src/ui/components/horizontal_screen.dart b/lib/src/ui/components/horizontal_screen.dart new file mode 100644 index 0000000..25703f0 --- /dev/null +++ b/lib/src/ui/components/horizontal_screen.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/jobs.dart'; +import 'package:space/src/ui/components/horizontal_list.dart'; + +class HorizontalScreen extends StatefulWidget { + _HorizontalScreenState createState() => _HorizontalScreenState(); +} + +class _HorizontalScreenState extends State { + var _isInit = true; + var _isLoading = false; + + @override + void didChangeDependencies() { + if (_isInit) { + setState(() { + _isLoading = true; + }); + Provider.of(context).fetchAndSetJobs().then((_) { + setState(() { + _isLoading = false; + }); + }); + } + _isInit = false; + super.didChangeDependencies(); + } + + @override + Widget build(BuildContext context) { + final jobData = Provider.of(context); + final jobs = jobData.posts; + return Scaffold( + backgroundColor: Colors.transparent, + body: _isLoading + ? Center( + child: CircularProgressIndicator(), + ) + : ListView.builder( + padding: EdgeInsets.symmetric(horizontal: 5), + scrollDirection: Axis.horizontal, + itemCount: jobs.length, + itemBuilder: (ctx, i) => ChangeNotifierProvider.value( + // builder: (c) => jobs[i], + value: jobs[i], + child: HorizontalList( + // jobs[i].id, + // jobs[i].title, + // jobs[i].imageUrl, + ), + ), + ), + ); + } +} diff --git a/lib/src/ui/components/landing_404_page.dart b/lib/src/ui/components/landing_404_page.dart new file mode 100644 index 0000000..26b008b --- /dev/null +++ b/lib/src/ui/components/landing_404_page.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; + +class LandingErrorPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + return new Scaffold( + body: Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + image: DecorationImage( + alignment: Alignment(-1, 0), + image: AssetImage('assets/vector-3.png'), + fit: BoxFit.cover), + ), + child: Stack( + children: [ + Stack( + alignment: Alignment(6, 4), + children: [ + Image.asset('assets/ellipse_1.png', width: 270), + Container( + height: 275, + width: 275, + child: Stack( + alignment: Alignment(4, 4.2), + children: [ + Image.asset('assets/ellipse_2.png', width: 270), + Container( + height: 140, + padding: EdgeInsets.symmetric(horizontal: 15), + margin: EdgeInsets.only(bottom: 90, left: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('404', + style: style.copyWith( + fontSize: 70, color: Colors.white)), + Text('Sorry! The Page Not Found :(', + style: style.copyWith( + fontSize: 15, color: Colors.white)), + Text( + 'The Link You Folowed Probably Broken, or the page has been removed.', + textAlign: TextAlign.center, + style: style.copyWith( + fontSize: 11.5, color: Colors.white), + ), + ], + ), + ), + ], + ), + ), + ], + ), + Container( + width: 280, + height: 300, + child: Stack( + alignment: Alignment(1.8, -0.2), + children: [ + Container( + width: 125, + height: 60, + padding: EdgeInsets.only(top: 15), + child: Material( + borderRadius: BorderRadius.circular(30), + color: Color(0xff4e4f4f), + child: MaterialButton( + padding: + EdgeInsets.only(top: 13, left: 5, right: 5), + onPressed: () {}, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/icon1.png', + width: 22, + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text('info@online.com', + style: style.copyWith( + fontSize: 9, + color: Colors.white)), + Text('online support', + style: style.copyWith( + fontSize: 6, + color: Color(0xffffa500))), + ], + ), + ], + )), + )) + ], + )), + Container( + width: 280, + height: 300, + child: Stack(alignment: Alignment(2.2, 0.2), children: [ + Container( + width: 125, + height: 60, + padding: EdgeInsets.only(top: 15), + child: Material( + borderRadius: BorderRadius.circular(30), + color: Color(0xff4e4f4f), + child: MaterialButton( + padding: + EdgeInsets.only(top: 13, left: 5, right: 5), + onPressed: () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/icon2.png', + width: 22, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('62 822 1234 567', + style: style.copyWith( + fontSize: 9, color: Colors.white)), + Text('Mon-Fri 9am-8pm', + style: style.copyWith( + fontSize: 6, + color: Color(0xff90ee90))), + ], + ), + ], + )), + )) + ])) + ], + ), + ), + ); + } +} diff --git a/lib/src/ui/components/landing_no_connection.dart b/lib/src/ui/components/landing_no_connection.dart new file mode 100644 index 0000000..086edc9 --- /dev/null +++ b/lib/src/ui/components/landing_no_connection.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; + +class LandingNoConnection extends StatefulWidget { + @override + _LandingNoConnectionState createState() => _LandingNoConnectionState(); +} + +class _LandingNoConnectionState extends State + with SingleTickerProviderStateMixin { + TextStyle style = TextStyle(fontFamily: 'Cocogoose', fontSize: 20.0); + TextStyle style1 = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + int _selectedIndex = 0; + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } + + @override + Widget build(BuildContext context) { + return new Scaffold( + body: Container( + padding: EdgeInsets.fromLTRB(70, 60, 70, 0), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/vector-3.png'), + alignment: AlignmentDirectional.topEnd, + fit: BoxFit.fitHeight), + ), + child: Column( + children: [ + Image.asset('assets/vector-4.png'), + Container( + height: 170, + child: Column( + children: [ + SizedBox( + height: 20, + ), + Text('Oops !!', + style: style.copyWith(fontSize: 30, color: Colors.white)), + Text('It’s look like you are in the moon !!', + textAlign: TextAlign.center, + style: + style1.copyWith(fontSize: 16, color: Colors.white)), + SizedBox( + height: 20, + ), + Text( + 'No Internet connection. Make sure that Wifi or cellular mobile data is turned on, then try again', + textAlign: TextAlign.center, + style: style1.copyWith(fontSize: 16, color: Colors.white)) + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/src/ui/components/loading_transition.dart b/lib/src/ui/components/loading_transition.dart new file mode 100644 index 0000000..cb9b024 --- /dev/null +++ b/lib/src/ui/components/loading_transition.dart @@ -0,0 +1,82 @@ +import 'dart:ui' show lerpDouble; +import 'package:flutter/material.dart'; + +class LoadingTransition extends ImplicitlyAnimatedWidget { + LoadingTransition({ + @required this.child, + this.duration = const Duration(milliseconds: 300), + }) : super( + curve: Curves.easeInOut, + duration: duration, + ); + + final Widget child; + final Duration duration; + + @override + _LoadingTransitionState createState() => _LoadingTransitionState(); +} + +class _LoadingTransitionState + extends AnimatedWidgetBaseState { + LoadingTransitionOpacityTween opacityTween; + LoadingTransitionChildTween childTween; + Key _currentKey; + + bool get _isOldWidget => widget.child.key == _currentKey; + + @override + void initState() { + super.initState(); + setState(() => _currentKey = widget.child.key); + controller.addStatusListener((status) { + if (status == AnimationStatus.completed) + setState(() => _currentKey = widget.child.key); + }); + } + + @override + Widget build(BuildContext context) { + final opacity = !_isOldWidget ? opacityTween.evaluate(animation) : 1.0; + return Opacity( + opacity: opacity, + child: childTween.evaluate(animation), + ); + } + + @override + void forEachTween(visitor) { + opacityTween = visitor(opacityTween, 1.0, + (opacity) => LoadingTransitionOpacityTween(begin: opacity)); + childTween = visitor(childTween, widget.child, + (child) => LoadingTransitionChildTween(begin: child)); + } +} + +@visibleForTesting +class LoadingTransitionOpacityTween extends Tween { + LoadingTransitionOpacityTween({double begin, double end}) + : super(begin: begin, end: end); + + double lerp(double t) { + if (t < 0.5) { + return lerpDouble(1.0, 0.0, t * 2); + } else { + return lerpDouble(0.0, 1.0, (t - 0.5) * 2); + } + } +} + +@visibleForTesting +class LoadingTransitionChildTween extends Tween { + LoadingTransitionChildTween({Widget begin, Widget end}) + : super(begin: begin, end: end); + + Widget lerp(double t) { + if (t < 0.5) { + return begin; + } else { + return end; + } + } +} diff --git a/lib/src/ui/components/recommended_job.dart b/lib/src/ui/components/recommended_job.dart new file mode 100644 index 0000000..8a94e04 --- /dev/null +++ b/lib/src/ui/components/recommended_job.dart @@ -0,0 +1,64 @@ +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/job.dart'; +import 'package:space/src/ui/seeker/layout/job_details.dart'; + +class RecommendedJob extends StatelessWidget { + @override + Widget build(BuildContext context) { + final job = Provider.of(context, listen: false); + return Container( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + child: ListTile( + onTap: () { + Navigator.of(context) + .pushNamed(JobDetails.routeName, arguments: job.id); + }, + leading: SizedBox( + height: 40, + // child: Image.network(job.imageUrl, fit: BoxFit.cover), + ), + title: Container( + padding: EdgeInsets.only(bottom: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(job.title, style: TextStyle(fontSize: 18, height: 2)), + Text('1w', + style: + TextStyle(fontSize: 10, color: Color(0xffc9c8c8))), + ], + ), + Text( + 'job.employerName', + style: TextStyle( + fontSize: 12, color: Color(0xff5f5f5f), height: 1), + ), + Row( + children: [ + Padding( + padding: EdgeInsets.only(top: 1), + child: Icon(FeatherIcons.mapPin, + size: 11, color: Color(0xff8997a7))), + Text(job.location, + style: TextStyle( + fontSize: 10, + color: Color(0xff5f5f5f), + height: 1.5)), + ], + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/src/ui/components/recommended_screen.dart b/lib/src/ui/components/recommended_screen.dart new file mode 100644 index 0000000..884cb09 --- /dev/null +++ b/lib/src/ui/components/recommended_screen.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/jobs.dart'; +import 'package:space/src/ui/components/recommended_job.dart'; + +class RecommendedScreen extends StatefulWidget { + + _RecommendedScreenState createState() => _RecommendedScreenState(); +} + +class _RecommendedScreenState extends State { + var _isInit = true; + var _isLoading = false; + + + @override + void didChangeDependencies() { + if (_isInit) { + setState(() { + _isLoading = true; + }); + Provider.of(context).fetchAndSetJobs().then((_) { + setState(() { + _isLoading = false; + }); + }); + } + _isInit = false; + super.didChangeDependencies(); + } + + @override + Widget build(BuildContext context) { + final jobData = Provider.of(context); + final jobs = jobData.posts; + return Scaffold( + backgroundColor: Colors.transparent, + body: _isLoading + ? Center( + child: CircularProgressIndicator(), + ) + : ListView.builder( + controller: ScrollController(initialScrollOffset: 0), + itemCount: 2, + itemBuilder: (ctx, i) => ChangeNotifierProvider.value( + // builder: (c) => jobs[i], + value: jobs[i], + child: RecommendedJob( + // jobs[i].id, + // jobs[i].title, + // jobs[i].imageUrl, + ), + ), + + ), + ); + } +} diff --git a/lib/src/ui/components/refresh_button.dart b/lib/src/ui/components/refresh_button.dart new file mode 100644 index 0000000..a3e2e86 --- /dev/null +++ b/lib/src/ui/components/refresh_button.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; + +class RefreshButton extends StatefulWidget { + RefreshButton({ + Key key, + @required this.onPressed, + }) : super(key: key); + + final VoidCallback onPressed; + + @override + _RefreshButtonState createState() => _RefreshButtonState(); +} + +class _RefreshButtonState extends State with SingleTickerProviderStateMixin { + AnimationController _controller; + Animation _rotation; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(milliseconds: 500), + vsync: this, + ) + ..addListener(() => setState(() {})) + ..addStatusListener((status) { + if (status == AnimationStatus.completed) { + _controller.reset(); + } + }); + _rotation = CurvedAnimation( + parent: _controller, + curve: Curves.fastOutSlowIn, + ); + } + + @override + Widget build(BuildContext context) { + return IconButton( + color: Theme.of(context).primaryColor, + icon: RotationTransition( + turns: _rotation, + child: Icon(Icons.refresh), + ), + tooltip: 'Refresh', + onPressed: widget.onPressed != null + ? () => _handlePressed() + : null, + ); + } + + void _handlePressed() { + _controller.forward(); + widget.onPressed(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } +} diff --git a/lib/src/ui/components/saved_job.dart b/lib/src/ui/components/saved_job.dart new file mode 100644 index 0000000..866720e --- /dev/null +++ b/lib/src/ui/components/saved_job.dart @@ -0,0 +1,84 @@ +// import 'package:flutter/material.dart'; + +// import 'package:space/src/core/models/job.dart'; +// import 'package:space/src/ui/screens/job_details.dart'; + +// import 'package:morpheus/morpheus.dart'; + +// /// Builds a [ListTile] that pushes a position screen when tapped. The tile +// /// allows the user to remove the position from the saved list without going +// /// directly to the position screen. +// class SavedJob extends StatelessWidget { +// const SavedJob({ +// Key key, +// @required this.job, +// this.animation, +// @required this.parentKey, +// }) : super(key: key); + +// /// The [position] that contains the data that will populate the tile as well +// /// as the [PositionDetails] screen that is pushed on tap. +// final Job job; + +// /// The animation used to transition the tile in or out of the 'saved' list. +// final Animation animation; + +// /// A [GlobalKey] used when pushing the [PositionDetails] screen via a +// /// [MorpheusPageRoute]. +// final GlobalKey parentKey; + +// @override +// Widget build(BuildContext context) { +// final Widget tile = ListTile( +// key: parentKey, +// title: Text(job.title), +// subtitle: Text(job.location), +// onTap: () => _showPositionDetails(context), + +// // TODO: Add a trailing button that lets the user remove the position from the positions list. +// trailing: IconTheme( +// data: Theme.of(context).primaryIconTheme, +// child: IconButton( +// icon: Icon(Icons.remove), +// tooltip: 'Remove from saved', +// onPressed: () => Scaffold.of(context).showSnackBar(SnackBar( +// content: Text('This button currently does nothing.'), +// )), +// ), +// ), +// ); + +// // Return only the tile if no animation has been provided to listen to. +// if (animation == null) { +// return tile; +// } else { +// // Build animation used when animating the tile in or out of the list. +// final Animation transitionAnimation = Tween( +// begin: 0.0, +// end: 1.0, +// ).animate(CurvedAnimation( +// parent: animation, +// curve: Curves.fastOutSlowIn, +// reverseCurve: Curves.fastOutSlowIn.flipped, +// )); + +// return SizeTransition( +// sizeFactor: transitionAnimation, +// child: FadeTransition( +// opacity: transitionAnimation, +// child: tile, +// ), +// ); +// } +// } + +// /// Pushes a [PositionDetails] screen showing a detailed overview of +// /// [position]. +// Future _showPositionDetails(BuildContext context) async { +// await Navigator.of(context).push(MorpheusPageRoute( +// builder: (context) => JobDetails(), +// parentKey: parentKey, +// transitionDuration: const Duration(milliseconds: 400), +// )); +// } +// } diff --git a/lib/src/ui/components/seeker_app_bar.dart b/lib/src/ui/components/seeker_app_bar.dart new file mode 100644 index 0000000..1224b59 --- /dev/null +++ b/lib/src/ui/components/seeker_app_bar.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:space/src/core/models/cart.dart'; +import 'package:space/src/ui/seeker/screens/cart_screen.dart'; + +import 'badge.dart'; + + +class SeekerAppBar extends StatelessWidget { + @override + Widget build(BuildContext context) { + return SliverAppBar( + floating: true, + pinned: true, + snap: true, + forceElevated: true, + centerTitle: true, + title: SizedBox( + child: Image.asset('assets/logo_vertical.png'), + height: 30, + ), + actions: [ + Consumer( + builder: (_, cart, ch) => Badge( + child: ch, + value: cart.itemCount.toString(), + ), + child: IconButton( + icon: Icon( + Icons.shopping_cart, + ), + onPressed: () { + Navigator.of(context).pushNamed(CartScreen.routeName); + }, + ), + ), + ], + bottom: TabBar( + indicatorColor: Colors.yellow[700], + labelColor: Colors.yellow[700], + labelStyle: TextStyle(fontSize: 14, color: Colors.yellow[700]), + unselectedLabelStyle: TextStyle(color: Color(0xff000000)), + tabs: [ + Tab(text: 'New'), + Tab(text: 'Applied'), + Tab(text: 'Saved'), + ], + ), + ); + } +} diff --git a/lib/src/ui/components/splash_screen.dart b/lib/src/ui/components/splash_screen.dart new file mode 100644 index 0000000..e287656 --- /dev/null +++ b/lib/src/ui/components/splash_screen.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class SplashScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: Text('Loading...'), + ), + ); + } +} diff --git a/lib/src/ui/components/uploaded_page.dart b/lib/src/ui/components/uploaded_page.dart new file mode 100644 index 0000000..75c5f89 --- /dev/null +++ b/lib/src/ui/components/uploaded_page.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +class LandingUploaded extends StatefulWidget { + const LandingUploaded({ Key key, String title }) : super(key: key); + @override + _LandingUploadedState createState() => _LandingUploadedState(); +} + +class _LandingUploadedState extends State with SingleTickerProviderStateMixin { + + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { +return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return new Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context,true); + }, + icon: Icon(FeatherIcons.chevronLeft, color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Text('Profile', style: style.copyWith(color: Color(0xff2c4057), + fontSize: 14, fontWeight: FontWeight.w500,letterSpacing: 1,)), + ), + + body: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Container( + child: Column(children: [ + Stack( + children: [ + Container( + padding: EdgeInsets.only(top: 25, left: 50), + child: Image.asset('assets/background-1.png'), + ), + Container( + padding: EdgeInsets.only(left: 60, top: 15, right: 60, bottom: 30), + child: Image.asset('assets/vector-1.png'), + ), + ], + ), + Stack(children: [ + Container( + margin: EdgeInsets.only(top: 10), + width: 80, + height: 80, + decoration: BoxDecoration( + color: Colors.grey[100], + borderRadius: BorderRadius.circular(90) + ), + ), + Container( + margin: EdgeInsets.only(top: 20, left: 10), + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.grey[300], + borderRadius: BorderRadius.circular(90) + ), + ), + Container( + margin: EdgeInsets.only(top: 30, left: 23), + child: Icon(FeatherIcons.uploadCloud, color: Color(0xff8997a7), size: 35) + ), + ],), + Container( + margin: EdgeInsets.only(top: 20), + padding: EdgeInsets.symmetric(horizontal: 30), + child: Column( + children: [ + Text('Good Luck !', style: style.copyWith(fontSize: 35, color: Color(0xff8997a7))), + Text("Your CV has succesfully uploaded and under review. Don’t lost your chances, always check your inbox and notifications!Thanks for apply in this job.", + textAlign: TextAlign.center, + style: style.copyWith(color: Color(0xff8997a7), fontSize: 15, height: 1.7)) + ],), + ), + ],), + ), + ), + ); + } + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/employer/layout/employer_app_bar.dart b/lib/src/ui/employer/layout/employer_app_bar.dart new file mode 100644 index 0000000..7c5b17a --- /dev/null +++ b/lib/src/ui/employer/layout/employer_app_bar.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:space/src/ui/employer/layout/employer_edit_post.dart'; + +class EmployerAppBar extends StatelessWidget { + @override + Widget build(BuildContext context) { + final scaffold = Scaffold.of(context); + return SliverAppBar( + iconTheme: IconThemeData(color: Color(0xff3b3b3b)), + leading: Builder( + builder: (context) => IconButton( + icon: Icon(Icons.menu), + onPressed: () => scaffold.openDrawer(), + ), + ), + floating: true, + pinned: true, + snap: true, + forceElevated: true, + centerTitle: true, + title: SizedBox( + child: Image.asset('assets/logo_vertical.png'), + height: 30, + ), + actions: [ + IconButton( + icon: Icon(Icons.add), + onPressed: () { + Navigator.of(context).pushNamed( + EditPost.routeName, + ); + }, + ), + ], + bottom: TabBar( + unselectedLabelColor: Color(0xff3b3b3b), + indicatorColor: Colors.yellow[700], + labelColor: Colors.yellow[700], + labelStyle: TextStyle(fontSize: 14, color: Colors.yellow[700]), + unselectedLabelStyle: TextStyle(color: Color(0xff000000)), + tabs: [ + Tab(text: 'Applicants'), + Tab(text: 'Interviewed'), + Tab(text: 'Posted'), + ], + ), + ); + } +} diff --git a/lib/src/ui/employer/layout/employer_edit_post.dart b/lib/src/ui/employer/layout/employer_edit_post.dart new file mode 100644 index 0000000..f0a81e6 --- /dev/null +++ b/lib/src/ui/employer/layout/employer_edit_post.dart @@ -0,0 +1,1148 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:space/src/core/models/job.dart'; +import 'package:space/src/core/models/jobs.dart'; + +class EditPost extends StatefulWidget { + static const routeName = '/edit-post'; + + @override + _EditPostState createState() => _EditPostState(); +} + +class _EditPostState extends State { + final _locationFocusNode = FocusNode(); + final _descriptionFocusNode = FocusNode(); + final _workingdayFocusNode = FocusNode(); + final _workinghourFocusNode = FocusNode(); + final _skillFocusNode = FocusNode(); + final _salaryFocusNode = FocusNode(); + final _form = GlobalKey(); + var _editJob = Job( + id: null, + title: '', + salary: 0, + description: '', + type: '', + workingday: '', + workinghour: '', + skill: '', + education: '', + industry: '', + location: '', + typeSalary: '', + gender: '', + ); + var _initValues = { + 'title': '', + 'salary': '', + 'description': '', + 'type': '', + 'workingday': '', + 'workinghour': '', + 'skill': '', + 'education': '', + 'industry': '', + 'location': '', + 'typeSalary': '', + 'gender': '', + }; + var _isInit = true; + var _isLoading = false; + + @override + void didChangeDependencies() { + if (_isInit) { + final jobId = ModalRoute.of(context).settings.arguments as String; + if (jobId != null) { + _editJob = Provider.of(context, listen: false).findById(jobId); + _initValues = { + 'title': _editJob.title, + 'location': _editJob.location, + 'description': _editJob.description, + 'workingday': _editJob.workingday, + 'workinghour': _editJob.workinghour, + 'skill': _editJob.skill, + 'salary': _editJob.salary.toString(), + 'type': _editJob.type, + 'education': _editJob.education, + 'industry': _editJob.industry, + 'typeSalary': _editJob.typeSalary, + 'gender': _editJob.gender.toString(), + }; + } + } + _isInit = false; + super.didChangeDependencies(); + } + + @override + void dispose() { + _locationFocusNode.dispose(); + _descriptionFocusNode.dispose(); + _workingdayFocusNode.dispose(); + _workinghourFocusNode.dispose(); + _skillFocusNode.dispose(); + _salaryFocusNode.dispose(); + super.dispose(); + } + + Future _saveForm() async { + final isValid = _form.currentState.validate(); + if (!isValid) { + return; + } + _form.currentState.save(); + setState(() { + _isLoading = true; + }); + if (_editJob.id != null) { + await Provider.of(context, listen: false) + .updateJob(_editJob.id, _editJob); + } else { + try { + await Provider.of(context, listen: false).addJob(_editJob); + } catch (error) { + print(error); + } + { + await showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text('An error occurred!'), + content: Text('Something went wrong.'), + actions: [ + FlatButton( + child: Text('Ok'), + onPressed: () { + Navigator.of(ctx).pop(); + }, + ) + ], + ), + ); + } + // finally { + // setState(() { + // _isLoading = false; + // }); + // Navigator.of(context).pop(); + // } + } + setState(() { + _isLoading = false; + }); + Navigator.of(context).pop(); + // Navigator.of(context).pop(); + } + + String gender; + String industry; + String type; + String typeSalary; + String education; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context, true); + }, + icon: Icon(Icons.chevron_left, color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Text('Post Job', + style: TextStyle( + color: Color(0xff2c4057), + fontSize: 14, + fontWeight: FontWeight.w500, + letterSpacing: 1, + )), + ), + body: _isLoading + ? Center( + child: CircularProgressIndicator(), + ) + : Form( + key: _form, + child: SingleChildScrollView( + padding: EdgeInsets.symmetric(vertical: 30), + child: Column( + children: [ + Column( + children: [ + Column( + children: [ + Text("Job Details", + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Color(0xff2c4057), + fontSize: 22, + fontWeight: FontWeight.w600, + letterSpacing: 2)), + ], + ), + Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only( + left: 130.0, right: 130.0), + child: Divider( + thickness: 2, + color: Color(0xff22c0e8), + height: 30)), + ), + ], + ), + ], + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: TextFormField( + initialValue: _initValues['title'], + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25, + ), + decoration: InputDecoration( + labelText: "Title", + labelStyle: TextStyle( + color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + textInputAction: TextInputAction.next, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(_locationFocusNode); + }, + validator: (value) { + if (value.isEmpty) { + return 'Please provide a value.'; + } + return null; + }, + onSaved: (value) { + _editJob = Job( + title: value, + salary: _editJob.salary, + description: _editJob.description, + gender: _editJob.gender, + industry: _editJob.industry, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + education: _editJob.education, + skill: _editJob.skill, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + id: _editJob.id, + isSave: _editJob.isSave); + }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: TextFormField( + initialValue: _initValues['location'], + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25, + ), + decoration: InputDecoration( + labelText: "Location", + labelStyle: TextStyle( + color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + textInputAction: TextInputAction.next, + focusNode: _locationFocusNode, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(_descriptionFocusNode); + }, + validator: (value) { + if (value.isEmpty) { + return 'Please provide a value.'; + } + return null; + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + salary: _editJob.salary, + description: _editJob.description, + gender: _editJob.gender, + industry: _editJob.industry, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + education: _editJob.education, + skill: _editJob.skill, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: value, + id: _editJob.id, + isSave: _editJob.isSave); + }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: TextFormField( + initialValue: _initValues['description'], + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25, + ), + decoration: InputDecoration( + labelText: "Description", + labelStyle: TextStyle( + color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + maxLines: 3, + keyboardType: TextInputType.multiline, + focusNode: _descriptionFocusNode, + validator: (value) { + if (value.isEmpty) { + return 'Please enter a description.'; + } + if (value.length < 10) { + return 'Should be at least 10 characters long.'; + } + return null; + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + salary: _editJob.salary, + description: value, + gender: _editJob.gender, + industry: _editJob.industry, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + education: _editJob.education, + skill: _editJob.skill, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + id: _editJob.id, + isSave: _editJob.isSave); + }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: FormField( + initialValue: _initValues['gender'], + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + id: _editJob.id, + isSave: _editJob.isSave, + salary: _editJob.salary, + gender: value, + typeSalary: _editJob.typeSalary, + type: _editJob.type, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + industry: _editJob.industry, + education: _editJob.education, + skill: _editJob.skill, + description: _editJob.description, + ); + }, + builder: (FormFieldState state) { + return InputDecorator( + decoration: InputDecoration( + contentPadding: + EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0), + errorStyle: TextStyle( + color: Colors.redAccent, fontSize: 16.0), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + child: DropdownButtonFormField( + decoration: + InputDecoration.collapsed(hintText: ''), + hint: Text('Gender', + style: TextStyle( + color: Color(0xff8997a7), fontSize: 14)), + icon: Icon( + Icons.expand_more, + color: Colors.black45, + size: 22, + ), + value: gender, + onChanged: (String newValue) { + setState(() { + gender = newValue; + }); + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + id: _editJob.id, + isSave: _editJob.isSave, + salary: _editJob.salary, + gender: value, + typeSalary: _editJob.typeSalary, + type: _editJob.type, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + industry: _editJob.industry, + education: _editJob.education, + skill: _editJob.skill, + description: _editJob.description, + ); + }, + items: [ + 'Male', + 'Female' + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value, + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25)), + ); + }).toList(), + ), + ); + }, + // validator: (value) { + // if (value.isEmpty) { + // return 'Gender should filled'; + // } + // return null; + // }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: FormField( + initialValue: _initValues['industry'], + builder: (FormFieldState state) { + return InputDecorator( + decoration: InputDecoration( + contentPadding: + EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0), + errorStyle: TextStyle( + color: Colors.redAccent, fontSize: 16.0), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + child: DropdownButtonHideUnderline( + child: DropdownButtonFormField( + decoration: + InputDecoration.collapsed(hintText: ''), + hint: Text('Industry', + style: TextStyle( + color: Color(0xff8997a7), + fontSize: 14)), + icon: Icon( + Icons.expand_more, + color: Colors.black45, + size: 22, + ), + value: industry, + onChanged: (String newValue) { + setState(() { + industry = newValue; + }); + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + id: _editJob.id, + isSave: _editJob.isSave, + salary: _editJob.salary, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + gender: _editJob.gender, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + industry: value, + education: _editJob.education, + skill: _editJob.skill, + description: _editJob.description, + ); + }, + items: [ + 'Resturants', + 'Hotels' + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value, + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25)), + ); + }).toList(), + ), + ), + ); + }, + // validator: (value) { + // if (value.isEmpty) { + // return 'Industry should filled'; + // } + // return null; + // }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: FormField( + initialValue: _initValues['type'], + builder: (FormFieldState state) { + return InputDecorator( + decoration: InputDecoration( + contentPadding: + EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0), + errorStyle: TextStyle( + color: Colors.redAccent, fontSize: 16.0), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + child: DropdownButtonHideUnderline( + child: DropdownButtonFormField( + decoration: + InputDecoration.collapsed(hintText: ''), + hint: Text('Type', + style: TextStyle( + color: Color(0xff8997a7), + fontSize: 14)), + icon: Icon( + Icons.expand_more, + color: Colors.black45, + size: 22, + ), + value: type, + onChanged: (String newValue) { + setState(() { + type = newValue; + }); + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + id: _editJob.id, + isSave: _editJob.isSave, + salary: _editJob.salary, + type: value, + typeSalary: _editJob.typeSalary, + gender: _editJob.gender, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + industry: _editJob.industry, + education: _editJob.education, + skill: _editJob.skill, + description: _editJob.description); + }, + items: [ + 'Full Time', + 'Part Time', + 'Freelance', + 'Weekend' + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value, + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25)), + ); + }).toList(), + ), + ), + ); + }, + // validator: (value) { + // if (value.isEmpty) { + // return 'Type should filled'; + // } + // return null; + // }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: FormField( + initialValue: _initValues['typeSalary'], + + builder: (FormFieldState state) { + return InputDecorator( + decoration: InputDecoration( + contentPadding: + EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0), + errorStyle: TextStyle( + color: Colors.redAccent, fontSize: 16.0), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + child: DropdownButtonHideUnderline( + child: DropdownButtonFormField( + decoration: + InputDecoration.collapsed(hintText: ''), + hint: Text('Type Salary', + style: TextStyle( + color: Color(0xff8997a7), + fontSize: 14)), + icon: Icon( + Icons.expand_more, + color: Colors.black45, + size: 22, + ), + value: typeSalary, + onChanged: (String newValue) { + setState(() { + typeSalary = newValue; + }); + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + id: _editJob.id, + isSave: _editJob.isSave, + salary: _editJob.salary, + type: _editJob.type, + typeSalary: value, + gender: _editJob.gender, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + industry: _editJob.industry, + education: _editJob.education, + skill: _editJob.skill, + description: _editJob.description); + }, + items: [ + 'Per Hour', + 'Per Day', + 'Per Month' + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value, + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25)), + ); + }).toList(), + ), + ), + ); + }, + // validator: (value) { + // if (value.isEmpty) { + // return 'Type Salary should filled'; + // } + // return null; + // }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: FormField( + initialValue: _initValues['education'], + + builder: (FormFieldState state) { + return InputDecorator( + decoration: InputDecoration( + contentPadding: + EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 5.0), + errorStyle: TextStyle( + color: Colors.redAccent, fontSize: 16.0), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + child: DropdownButtonHideUnderline( + child: DropdownButtonFormField( + decoration: + InputDecoration.collapsed(hintText: ''), + hint: Text('Education Level', + style: TextStyle( + color: Color(0xff8997a7), + fontSize: 14)), + icon: Icon( + Icons.expand_more, + color: Colors.black45, + size: 22, + ), + value: education, + onChanged: (String newValue) { + setState(() { + education = newValue; + }); + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + id: _editJob.id, + isSave: _editJob.isSave, + salary: _editJob.salary, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + gender: _editJob.gender, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + industry: _editJob.industry, + education: value, + skill: _editJob.skill, + description: _editJob.description, + ); + }, + items: [ + 'SD', + 'SMP', + 'SMA', + 'D3', + 'S1', + 'S2', + 'S3' + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value, + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25)), + ); + }).toList(), + ), + ), + ); + }, + // validator: (value) { + // if (value.isEmpty) { + // return 'Education Level should filled'; + // } + // return null; + // }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: TextFormField( + initialValue: _initValues['workingday'], + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25, + ), + decoration: InputDecoration( + labelText: "Working Day", + labelStyle: TextStyle( + color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + textInputAction: TextInputAction.next, + focusNode: _workingdayFocusNode, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(_workinghourFocusNode); + }, + validator: (value) { + if (value.isEmpty) { + return 'Please provide a value.'; + } + return null; + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + salary: _editJob.salary, + description: _editJob.description, + gender: _editJob.gender, + industry: _editJob.industry, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + education: _editJob.education, + skill: _editJob.skill, + workinghour: _editJob.workinghour, + workingday: value, + location: _editJob.location, + id: _editJob.id, + isSave: _editJob.isSave); + }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: TextFormField( + initialValue: _initValues['workinghour'], + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25, + ), + decoration: InputDecoration( + labelText: "Working Hour", + labelStyle: TextStyle( + color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + textInputAction: TextInputAction.next, + focusNode: _workinghourFocusNode, + onFieldSubmitted: (_) { + FocusScope.of(context).requestFocus(_skillFocusNode); + }, + validator: (value) { + if (value.isEmpty) { + return 'Please provide a value.'; + } + return null; + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + salary: _editJob.salary, + description: _editJob.description, + gender: _editJob.gender, + industry: _editJob.industry, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + education: _editJob.education, + skill: _editJob.skill, + workinghour: value, + workingday: _editJob.workingday, + location: _editJob.location, + id: _editJob.id, + isSave: _editJob.isSave); + }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: TextFormField( + initialValue: _initValues['skill'], + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25, + ), + decoration: InputDecoration( + labelText: "Skill", + labelStyle: TextStyle( + color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + textInputAction: TextInputAction.next, + focusNode: _skillFocusNode, + onFieldSubmitted: (_) { + FocusScope.of(context).requestFocus(_salaryFocusNode); + }, + validator: (value) { + if (value.isEmpty) { + return 'Please provide a value.'; + } + return null; + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + salary: _editJob.salary, + description: _editJob.description, + gender: _editJob.gender, + industry: _editJob.industry, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + education: _editJob.education, + skill: value, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + id: _editJob.id, + isSave: _editJob.isSave); + }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: TextFormField( + initialValue: _initValues['salary'], + style: TextStyle( + color: Colors.black45, + fontSize: 14, + letterSpacing: 0.25, + ), + decoration: InputDecoration( + labelText: "Salary", + labelStyle: TextStyle( + color: Color(0xff8997a7), fontSize: 14), + filled: true, + fillColor: Color(0xffdcdfe3), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).errorColor)), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xff22c0e8))), + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Colors.transparent), + borderRadius: + BorderRadius.all(Radius.circular(5)))), + textInputAction: TextInputAction.next, + keyboardType: TextInputType.number, + focusNode: _salaryFocusNode, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(_descriptionFocusNode); + }, + validator: (value) { + if (value.isEmpty) { + return 'Please enter a salary.'; + } + if (double.tryParse(value) == null) { + return 'Please enter a valid number.'; + } + if (double.parse(value) <= 0) { + return 'Please enter a number greater than zero.'; + } + return null; + }, + onSaved: (value) { + _editJob = Job( + title: _editJob.title, + salary: double.parse(value), + description: _editJob.description, + gender: _editJob.gender, + industry: _editJob.industry, + type: _editJob.type, + typeSalary: _editJob.typeSalary, + education: _editJob.education, + skill: _editJob.skill, + workinghour: _editJob.workinghour, + workingday: _editJob.workingday, + location: _editJob.location, + id: _editJob.id, + isSave: _editJob.isSave); + }, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 40, vertical: 8), + child: Material( + elevation: 3.0, + borderRadius: BorderRadius.all(Radius.circular(5)), + color: Color(0xff22c0e8), + child: MaterialButton( + padding: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 15.0), + onPressed: _saveForm, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text('Save Post', + textAlign: TextAlign.center, + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xffffffff), + fontSize: 16, + fontWeight: FontWeight.w500, + )), + Container( + padding: EdgeInsets.only(left: 40, right: 30), + child: Icon( + Icons.arrow_forward, + color: Colors.white, + size: 20, + ), + ), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/src/ui/employer/layout/employer_post.dart b/lib/src/ui/employer/layout/employer_post.dart new file mode 100644 index 0000000..24e40bf --- /dev/null +++ b/lib/src/ui/employer/layout/employer_post.dart @@ -0,0 +1,170 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_money_formatter/flutter_money_formatter.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/ui/employer/layout/employer_edit_post.dart'; +import 'package:space/src/core/models/jobs.dart'; +import 'package:space/src/ui/seeker/layout/job_details.dart'; + +class EmployerPost extends StatelessWidget { + final String id; + final double salary; + final String title; + final String type; + final String location; + + EmployerPost( + this.id, + this.salary, + this.title, + this.type, + this.location, + ); + + @override + Widget build(BuildContext context) { + final scaffold = Scaffold.of(context); + return Container( + child: Stack( + children: [ + ListTile( + title: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text(title, + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 12, + color: Color(0xff3b3b3b))), + Container( + padding: EdgeInsets.only(left: 5), + child: Material( + elevation: 1.0, + borderRadius: BorderRadius.circular(5.0), + color: Color(0xff65be3e), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 4), + child: Text(type, + style: TextStyle( + color: Colors.white, fontSize: 9)), + ), + ), + ), + ], + ), + ], + ), + ), + subtitle: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.location_on, + size: 10, color: Color(0xff8997a7)), + Text(location, + style: TextStyle( + fontSize: 10, color: Color(0xff8997a7))), + ], + ), + Row( + children: [ + Text('Salary: ', + style: TextStyle( + fontSize: 10, color: Color(0xff8997a7))), + Text( + FlutterMoneyFormatter( + amount: salary, + settings: MoneyFormatterSettings( + symbol: 'Rp', + thousandSeparator: '.', + fractionDigits: 0)) + .output + .symbolOnLeft, + style: TextStyle( + fontSize: 10, color: Color(0xff3b3b3b))), + ], + ), + ], + ), + ), + onTap: () { + Navigator.of(context) + .pushNamed(JobDetails.routeName, arguments: id); + }), + Padding( + padding: EdgeInsets.only(right: 15, top: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + IconButton( + onPressed: () { + Navigator.of(context) + .pushNamed(EditPost.routeName, arguments: id); + }, + icon: Icon(Icons.edit), + ), + IconButton( + icon: Icon(Icons.delete), + onPressed: () async { + try { + await Provider.of(context, listen: false) + .deleteJob(id); + } catch (error) { + scaffold.showSnackBar( + SnackBar( + content: Text( + 'Deleting failed!', + textAlign: TextAlign.center, + ), + ), + ); + } + }, + color: Theme.of(context).errorColor, + ), + ], + ), +// PopupMenuButton( +// onSelected: (PostOptions selectedValue) { +// setState(() { +// if (selectedValue == PostOptions.Edit) { +// _showOnlyFavorites = true; +// } else { +// _showOnlyFavorites = false; +// } +// }); +// }, +// icon: Icon( +// Icons.more_vert, +// ), +// itemBuilder: (_) => [ +// PopupMenuItem( +// child: Text('Edit'), +// value: PostOptions.Edit, +// ), +// PopupMenuItem( +// child: Text('Delete'), +// value: PostOptions.Delete, +// ), +// ], +// ), + ), + ], + ), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + width: 0.4, + color: Color(0xffc5cfda), + ), + ), + ), + ); + } +} diff --git a/lib/src/ui/employer/layout/employer_profile_setting.dart b/lib/src/ui/employer/layout/employer_profile_setting.dart new file mode 100644 index 0000000..12b02af --- /dev/null +++ b/lib/src/ui/employer/layout/employer_profile_setting.dart @@ -0,0 +1,137 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +class EmployerProfileSetting extends StatefulWidget { + @override + _EmployerProfileSettingState createState() => _EmployerProfileSettingState(); +} + +class _EmployerProfileSettingState extends State + with SingleTickerProviderStateMixin { + int _selectedIndex = 0; + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + return Container( + child: Scaffold( + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context, true); + }, + icon: Icon(FeatherIcons.chevronLeft, + color: Color(0xff2c4057), size: 16)), + elevation: 0, + backgroundColor: Colors.transparent, + title: Text('Employers Profile', + style: style.copyWith( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500, + letterSpacing: 1, + )), + ), + body: Container( + margin: EdgeInsets.only(top: 20), + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: new BorderRadius.only( + topLeft: const Radius.circular(30.0), + topRight: const Radius.circular(30.0), + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + onTap: () {}, + leading: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Full Name', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + Text('Nakamura Chan', + style: style.copyWith( + color: Color(0xff757575), fontSize: 12)), + Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ], + )), + ], + ), + ), + bottomNavigationBar: BottomNavigationBar( + unselectedItemColor: Color(0xffdcdcdc), + showUnselectedLabels: true, + items: const [ + BottomNavigationBarItem( + icon: Icon(FeatherIcons.home, size: 30), + title: Text('HOME', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.briefcase, size: 30), + title: Text('JOBS', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.search, size: 30), + title: Text('SEARCH', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.messageSquare, size: 30), + title: Text('INBOX', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.user, size: 30), + title: Text('PROFILE', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + ], + currentIndex: _selectedIndex, + selectedItemColor: Color(0xff4d4d4d), + onTap: _onItemTapped, + ), + ), + ); + } +} diff --git a/lib/src/ui/employer/layout/employer_profile_view.dart b/lib/src/ui/employer/layout/employer_profile_view.dart new file mode 100644 index 0000000..05f0bf2 --- /dev/null +++ b/lib/src/ui/employer/layout/employer_profile_view.dart @@ -0,0 +1,241 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +class EmployerProfileView extends StatefulWidget { + @override + _EmployerProfileViewState createState() => _EmployerProfileViewState(); +} + +class _EmployerProfileViewState extends State + with SingleTickerProviderStateMixin { + int _selectedIndex = 0; + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + return new Container( + child: new Stack( + children: [ + new Container( + child: new Image.asset('assets/ketapang.png', fit: BoxFit.cover), + ), + new Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context, true); + }, + icon: Icon(FeatherIcons.chevronLeft, + color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.transparent, + title: Text('Back', + style: style.copyWith( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500, + letterSpacing: 1, + )), + ), + body: LayoutBuilder(builder: + (BuildContext context, BoxConstraints viewportConstraints) { + return Column( + children: [ + Stack( + children: [ + Container( + height: 120, + margin: EdgeInsets.only(top: 120), + padding: EdgeInsets.only(top: 20, left: 30, right: 30), + decoration: BoxDecoration( + color: Color(0xff4d4d4d), + borderRadius: new BorderRadius.only( + topLeft: const Radius.circular(40.0), + topRight: const Radius.circular(40.0))), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + Text('Followers', + style: style.copyWith( + fontSize: 14, color: Colors.white)), + Text('31401', + style: style.copyWith(color: Colors.white)), + ], + ), + RaisedButton( + onPressed: () {}, + color: Color(0xff22c0e8), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30)), + child: Text('Follow', + style: style.copyWith( + color: Colors.white, fontSize: 15))), + ], + )), + Container( + alignment: AlignmentDirectional.center, + margin: EdgeInsets.only(top: 90), + child: CircleAvatar( + backgroundColor: Colors.white, + radius: 45.0, + child: Image.asset('assets/mekuru_2.png'), + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + //Overflow!! + Container( + height: 330, + width: MediaQuery.of(context).size.width, + margin: EdgeInsets.only(top: 200), + padding: + EdgeInsets.only(top: 20, left: 15, right: 15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: new BorderRadius.only( + topLeft: const Radius.circular(40.0), + topRight: const Radius.circular(40.0))), + child: Column( + children: [ + Text('Mekuru Ramen', + style: style.copyWith( + fontSize: 18, + color: Color(0xff222222), + fontWeight: FontWeight.bold)), + Text('The Best Ramen in Town', + style: style.copyWith( + fontSize: 11, + color: Color(0xff1c1c1c), + fontWeight: FontWeight.bold)), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(FeatherIcons.mapPin, + size: 12, color: Color(0xff8997a7)), + Text(' Pontianak, West Borneo', + style: style.copyWith( + fontSize: 12, + color: Color(0xff8997a7))), + ], + ), + SizedBox( + height: 30, + ), + Column( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Text('Company Description', + style: style.copyWith( + fontSize: 14, + color: Color(0xff3b3b3b))), + Text( + 'We have a number of different teams within our agency that specialise in different areas of business so you can be sure that you won’t receive a generic service and although we can’t boast years and years of service we can ensure you that is a good thing in this industry. Our teams are up to date with the latest technologies, media trends and are keen to prove themselves in this industry and that’s what you want from an advertising agency.', + style: style.copyWith( + fontSize: 11, + color: Color(0xff8997a7), + height: 2), + ), + Center( + child: RaisedButton( + onPressed: () {}, + color: Color(0xff8997a7), + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(30)), + child: Text('Apply for a job', + style: style.copyWith( + color: Colors.white, + fontSize: 15))), + ), + ], + ) + ], + ), + ), + ], + ), + ], + ), + ], + ); + }), + bottomNavigationBar: BottomNavigationBar( + unselectedItemColor: Color(0xffdcdcdc), + showUnselectedLabels: true, + items: const [ + BottomNavigationBarItem( + icon: Icon(FeatherIcons.home, size: 30), + title: Text('HOME', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.briefcase, size: 30), + title: Text('JOBS', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.search, size: 30), + title: Text('SEARCH', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.messageSquare, size: 30), + title: Text('INBOX', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + BottomNavigationBarItem( + icon: Icon(FeatherIcons.user, size: 30), + title: Text('PROFILE', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + fontStyle: FontStyle.normal)), + ), + ], + currentIndex: _selectedIndex, + selectedItemColor: Color(0xff4d4d4d), + onTap: _onItemTapped, + ), + ), + ], + )); + } +} diff --git a/lib/src/ui/employer/screens/employer_posted_screen.dart b/lib/src/ui/employer/screens/employer_posted_screen.dart new file mode 100644 index 0000000..56ae60a --- /dev/null +++ b/lib/src/ui/employer/screens/employer_posted_screen.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/jobs.dart'; +import 'package:space/src/ui/employer/layout/employer_post.dart'; + +class EmployerPostScreen extends StatelessWidget { + static const routeName = '/employer-posts'; + + Future _refreshJobs(BuildContext context) async { + await Provider.of(context, listen: false).fetchAndSetJobs(true); + } + + @override + Widget build(BuildContext context) { + // final jobsData = Provider.of(context); + print('rebuilding...'); + return FutureBuilder( + future: _refreshJobs(context), + builder: (ctx, snapshot) => + snapshot.connectionState == ConnectionState.waiting + ? Center( + child: CircularProgressIndicator(), + ) + : RefreshIndicator( + onRefresh: () => _refreshJobs(context), + child: Consumer( + builder: (ctx, jobsData, _) => ListView.builder( + itemCount: jobsData.posts.length, + itemBuilder: (_, i) => EmployerPost( + jobsData.posts[i].id, + jobsData.posts[i].salary, + jobsData.posts[i].title, + jobsData.posts[i].type, + jobsData.posts[i].location, + ), + ), + ), + ), + ); + } +} diff --git a/lib/src/ui/employer/screens/employer_seeker_screen.dart b/lib/src/ui/employer/screens/employer_seeker_screen.dart new file mode 100644 index 0000000..577621e --- /dev/null +++ b/lib/src/ui/employer/screens/employer_seeker_screen.dart @@ -0,0 +1,142 @@ +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:flutter/material.dart'; + +class EmployerSeekerList extends StatefulWidget { + _EmployerSeekerListState createState() => _EmployerSeekerListState(); +} + +final items = List.generate(20, (i) => "Item ${i + 1}"); + +class _EmployerSeekerListState extends State { + @override + @override + Widget build(BuildContext context) { + return ListView.builder( + itemCount: items.length, + itemBuilder: (context, index) { + final item = items[index]; + return Dismissible( + // Specify the direction to swipe and delete + direction: DismissDirection.endToStart, + key: Key(item), + onDismissed: (direction) { + // Removes that item the list on swipwe + setState(() { + items.removeAt(index); + }); + // Shows the information on Snackbar + Scaffold.of(context) + .showSnackBar(SnackBar(content: Text("$item dismissed"))); + }, + background: Container(color: Theme.of(context).errorColor), + child: Container( + padding: EdgeInsets.only(bottom: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(0), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Color(0xff0c0c0c0), + blurRadius: 1.5, + offset: Offset(1.0, 1.0)) + ], + ), + child: Stack( + alignment: Alignment(1.06, -2), + children: [ + ListTile( + leading: Column( + children: [ + Stack( + alignment: Alignment(1, -1), + children: [ + CircleAvatar( + backgroundImage: + AssetImage('assets/img_profil.png'), + backgroundColor: Colors.blue, + radius: 28, + ), + Material( + borderRadius: BorderRadius.circular(20), + color: Color(0xff22c0e8), + child: Icon(FeatherIcons.plus, + color: Colors.white, size: 14), + ), + ], + ), + ], + ), + title: Container( + height: 60, + padding: (EdgeInsets.only(top: 5)), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('James Cahyadi', + style: TextStyle( + fontSize: 11, color: Color(0xff3b3b3b))), + Text('Male, 30 years old', + style: TextStyle( + fontSize: 11, color: Color(0xff3b3b3b))), + Text('Education: High School', + style: TextStyle( + fontSize: 11, color: Color(0xff3b3b3b))), + ], + ), + ), + subtitle: Container( + height: 30, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan(children: [ + TextSpan( + text: "Exp: ", + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff8997a7), + fontSize: 11, + fontWeight: FontWeight.w400, + )), + TextSpan( + text: '2 years as Barista', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 11, + fontWeight: FontWeight.w400, + )), + ])), + Row( + children: [ + Icon(FeatherIcons.mapPin, + size: 10, color: Color(0xff8997a7)), + Text(' Pontianak, West Borneo', + style: TextStyle( + fontSize: 10, color: Color(0xff8997a7))) + ], + ), + ], + ), + ), + trailing: RaisedButton.icon( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0)), + color: Color(0xff22c0e8), + onPressed: () {}, + icon: Icon(FeatherIcons.messageCircle, + color: Colors.white), + label: Text('Chat', + style: + TextStyle(color: Colors.white, fontSize: 14))), + ), + ], + ), + )); + }, + ); + } +} diff --git a/lib/src/ui/employer/screens/employer_tabs.dart b/lib/src/ui/employer/screens/employer_tabs.dart new file mode 100644 index 0000000..5907b0e --- /dev/null +++ b/lib/src/ui/employer/screens/employer_tabs.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +import 'package:space/src/ui/employer/layout/employer_app_bar.dart'; +import 'package:space/src/ui/employer/widgets/employer_app_drawer.dart'; +import 'package:space/src/ui/employer/screens/employer_posted_screen.dart'; +import 'package:space/src/ui/employer/screens/employer_seeker_screen.dart'; +import 'package:space/src/ui/seeker/screens/jobs_list_screen.dart'; + +class EmployerTabs extends StatelessWidget { + static const routeName = 'employer_tabs'; + + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 3, + child: Scaffold( + body: NestedScrollView( + headerSliverBuilder: (context, innerBoxScrolled) => + [EmployerAppBar()], + body: TabBarView( + children: [ + EmployerSeekerList(), + JobsListScreen(), + EmployerPostScreen(), + ], + )), + drawer: EmployerDrawer(), + ), + ); + } +} diff --git a/lib/src/ui/employer/widgets/employer_app_drawer.dart b/lib/src/ui/employer/widgets/employer_app_drawer.dart new file mode 100644 index 0000000..883b0f5 --- /dev/null +++ b/lib/src/ui/employer/widgets/employer_app_drawer.dart @@ -0,0 +1,245 @@ +import 'package:flutter/material.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:space/src/core/models/auth.dart'; +import 'package:space/src/ui/seeker/layout/seeker_profile_setting.dart'; +import 'package:space/src/ui/seeker/layout/seeker_profile_view.dart'; +import 'package:space/src/ui/settings/about_us.dart'; +import 'package:space/src/ui/settings/setting_ui_help.dart'; +import 'package:space/src/ui/settings/setting_ui_payment.dart'; +import 'package:space/src/ui/settings/settings_notification.dart'; +import 'package:space/src/ui/settings/settings_ui_invite_friends.dart'; + +class EmployerDrawer extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Drawer( + child: Container( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.only(top: 20, bottom: 10), + child: ListTile( + onTap: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => SeekerProfileView())); + }, + leading: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Mekuru Ramen', + style: + TextStyle(fontSize: 16, color: Color(0xff3b3b3b))), + Text('View and Edit Profile', + style: + TextStyle(fontSize: 11, color: Color(0xff3b3b3b))), + ], + ), + trailing: CircleAvatar( + backgroundColor: Colors.white, + radius: 40.0, + child: Image.asset( + 'assets/mekuru.png', + height: 75, + ), + ), + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('Notification', + style: TextStyle( + color: Color(0xff757575), fontSize: 12, height: 0.5)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.bellOutline, + color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SettingNotification())); + }, + ), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + Container( + height: 50, + child: ListTile( + title: Text('Profile Setting', + style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.accountEditOutline, + color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SettingSeekerProfile()), + ); + }), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + Container( + height: 50, + child: ListTile( + title: Text('Settings', + style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.settingsOutline, + color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SettingUIPayment()), + ); + }), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + Container( + height: 50, + child: ListTile( + title: Text('Help?', + style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.accountQuestionOutline, + color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => SettingUiHelp()), + ); + }), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + Container( + height: 50, + child: ListTile( + title: Text('Feedback Us', + style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.sendCircleOutline, + color: Color(0xff4d4d4d), size: 20)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + }), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + Container( + height: 50, + child: ListTile( + title: Text('Invite Friends', + style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.accountMultiplePlusOutline, + color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UiInviteFriends()), + ); + }), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + Container( + height: 50, + child: ListTile( + title: Text('FAQ', + style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.helpCircleOutline, + color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + }), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + Container( + height: 50, + child: ListTile( + title: Text('Abous Us', + style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.accountGroupOutline, + color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + }), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + Container( + height: 50, + child: ListTile( + title: Text('Log Out', + style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.logoutVariant, + color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.of(context).pop(); + Provider.of(context, listen: false).logout(); + }), + ), + Container( + height: 0, + child: Divider(color: Color(0xffc9c8c8)), + ), + ], + ), + ), + ); + } +} diff --git a/lib/src/ui/seeker/layout/apply_post.dart b/lib/src/ui/seeker/layout/apply_post.dart new file mode 100644 index 0000000..1501dfe --- /dev/null +++ b/lib/src/ui/seeker/layout/apply_post.dart @@ -0,0 +1,71 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import 'package:space/src/core/models/apply.dart' as ord; + +class ApplyItem extends StatefulWidget { + final ord.ApplyItem apply; + ApplyItem(this.apply); + + @override + _OrderItemState createState() => _OrderItemState(); +} + +class _OrderItemState extends State { + var _expanded = false; + + @override + Widget build(BuildContext context) { + return AnimatedContainer( + duration: Duration(milliseconds: 300), + height: _expanded ? min(widget.apply.jobs.length * 20.0 + 110, 200) : 95, + child: Card( + margin: EdgeInsets.all(10), + child: Column( + children: [ + ListTile( + subtitle: Text( + DateFormat('dd/MM/yyyy hh:mm').format(widget.apply.dateTime), + ), + trailing: IconButton( + icon: Icon(_expanded ? Icons.expand_less : Icons.expand_more), + onPressed: () { + setState(() { + _expanded = !_expanded; + }); + }, + ), + ), + AnimatedContainer( + duration: Duration(milliseconds: 300), + padding: EdgeInsets.symmetric(horizontal: 15, vertical: 4), + height: _expanded + ? min(widget.apply.jobs.length * 20.0 + 10, 100) + : 0, + child: ListView( + children: widget.apply.jobs + .map( + (prod) => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + prod.title, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ) + .toList(), + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/src/ui/seeker/layout/cart_item.dart b/lib/src/ui/seeker/layout/cart_item.dart new file mode 100644 index 0000000..0a67818 --- /dev/null +++ b/lib/src/ui/seeker/layout/cart_item.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/cart.dart'; + +class CartItem extends StatelessWidget { + final String id; + final String productId; + final double salary; + final int quantity; + final String title; + + CartItem( + this.id, + this.productId, + this.salary, + this.quantity, + this.title, + ); + + @override + Widget build(BuildContext context) { + return Dismissible( + key: ValueKey(id), + background: Container( + color: Theme.of(context).errorColor, + child: Icon( + Icons.delete, + color: Colors.white, + size: 40, + ), + alignment: Alignment.centerRight, + padding: EdgeInsets.only(right: 20), + margin: EdgeInsets.symmetric( + horizontal: 15, + vertical: 4, + ), + ), + direction: DismissDirection.endToStart, + confirmDismiss: (direction) { + return showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text('Are you sure?'), + content: Text( + 'Do you want to remove the item from the cart?', + ), + actions: [ + FlatButton( + child: Text('No'), + onPressed: () { + Navigator.of(ctx).pop(false); + }, + ), + FlatButton( + child: Text('Yes'), + onPressed: () { + Navigator.of(ctx).pop(true); + }, + ), + ], + ), + ); + }, + onDismissed: (direction) { + Provider.of(context, listen: false).removeItem(productId); + }, + child: Card( + margin: EdgeInsets.symmetric( + horizontal: 15, + vertical: 4, + ), + child: Padding( + padding: EdgeInsets.all(8), + child: ListTile( + leading: CircleAvatar( + child: Padding( + padding: EdgeInsets.all(5), + child: FittedBox( + child: Text('\$$salary'), + ), + ), + ), + title: Text(title), + subtitle: Text('Total: \$${(salary * quantity)}'), + trailing: Text('$quantity x'), + ), + ), + ), + ); + } +} diff --git a/lib/src/ui/seeker/layout/job_details.dart b/lib/src/ui/seeker/layout/job_details.dart new file mode 100644 index 0000000..29819fd --- /dev/null +++ b/lib/src/ui/seeker/layout/job_details.dart @@ -0,0 +1,315 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter_money_formatter/flutter_money_formatter.dart'; +import 'package:space/src/core/models/apply.dart'; +import 'package:space/src/core/models/job.dart'; + +import 'package:space/src/core/models/jobs.dart'; + +class JobDetails extends StatefulWidget { + static const routeName = '/job-details'; + + _JobDetailsState createState() => _JobDetailsState(); +} + +class _JobDetailsState extends State { + var _isLoading = false; + var _editJob = Job( + id: null, + title: '', + salary: 0, + description: '', + type: '', + workingday: '', + workinghour: '', + skill: '', + education: '', + industry: '', + location: '', + typeSalary: '', + gender: '', + ); +// final bool showSaves; + +// JobDetails(this.showSaves); + + @override + Widget build(BuildContext context) { + // final jobsData = Provider.of(context); + // final job = showSaves ? jobsData.savePosts : jobsData.posts; + final jobId = ModalRoute.of(context).settings.arguments as String; + // final authData = Provider.of(context, listen: false); + // final save = Provider.of(context, listen: false); + final loadedJob = Provider.of( + context, + listen: false, + ).findById(jobId); + return Stack( + children: [ + // Container( + // child: Image.asset('assets/ketapang.png', fit: BoxFit.cover), + // ), + Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context, true); + }, + icon: Icon(FeatherIcons.chevronLeft, + color: Colors.white, size: 16)), + elevation: 1, + backgroundColor: Colors.transparent, + title: Text('loadedJob.employerName', + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500, + letterSpacing: 1, + )), + ), + body: SingleChildScrollView( + child: Container( + height: MediaQuery.of(context).size.height, + child: Stack( + children: [ + Container( + height: 130, + margin: EdgeInsets.only(top: 90), + padding: EdgeInsets.only(top: 10, left: 20, right: 20), + decoration: BoxDecoration( + color: Color(0xff4d4d4d), + borderRadius: BorderRadius.only( + topLeft: const Radius.circular(40.0), + topRight: const Radius.circular(40.0))), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Salary', + style: TextStyle( + fontSize: 10, color: Colors.white)), + Text( + FlutterMoneyFormatter( + amount: loadedJob.salary, + settings: MoneyFormatterSettings( + symbol: 'Rp', + thousandSeparator: '.', + fractionDigits: 0)) + .output + .symbolOnLeft, + style: TextStyle( + fontSize: 10, color: Colors.white)), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text(loadedJob.title, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.white)), + Row( + children: [ + Icon(FeatherIcons.mapPin, + size: 9, color: Color(0xffc4c5c5)), + Text(loadedJob.location, + style: TextStyle( + fontSize: 10, + color: Color(0xffc4c5c5))), + ], + ), + Text('Working Hours', + style: TextStyle( + fontSize: 10, + color: Colors.white, + height: 2.2)), + Text(loadedJob.workingday, + style: TextStyle( + color: Colors.white, fontSize: 10)), + Text(loadedJob.workinghour, + style: TextStyle( + color: Colors.white, fontSize: 10)), + ], + ), + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Type', + style: TextStyle( + fontSize: 10, color: Colors.white)), + Material( + elevation: 1.0, + borderRadius: BorderRadius.circular(5.0), + color: Color(0xff65be3e), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 4), + child: Text(loadedJob.type, + style: TextStyle( + color: Colors.white, fontSize: 9)), + ), + ), + ], + ), + ], + )), + Container( + alignment: AlignmentDirectional.topStart, + padding: EdgeInsets.only( + top: 50, + left: 30, + ), + child: ClipOval( + // child: Image.network(loadedJob.imageUrl, height: 80), + ), + ), + Container( + height: MediaQuery.of(context).size.height, + margin: EdgeInsets.only(top: 190), + padding: EdgeInsets.only(top: 10, left: 20, right: 20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: const Radius.circular(40.0), + topRight: const Radius.circular(40.0))), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'Description: ', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Colors.black), + ), + TextSpan( + text: loadedJob.description, + style: TextStyle( + fontSize: 12, + color: Color(0xff8997a7), + height: 2)), + ], + ), + ), + RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'Industry: ', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Colors.black, + height: 2), + ), + TextSpan( + text: loadedJob.industry, + style: TextStyle( + fontSize: 12, + color: Color(0xff8997a7))), + ], + ), + ), + RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'Education Level: ', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Colors.black), + ), + TextSpan( + text: loadedJob.education, + style: TextStyle( + fontSize: 12, + color: Color(0xff8997a7), + height: 2)), + ], + ), + ), + Text( + 'Skills required: ', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Colors.black, + height: 2), + ), + Text(loadedJob.skill, + style: TextStyle( + fontSize: 12, + color: Color(0xff8997a7), + height: 2)), + SizedBox( + height: 15, + ), + Center( + child: RaisedButton( + child: _isLoading + ? CircularProgressIndicator() + : Text('Apply for a job', + style: TextStyle( + color: Colors.white, fontSize: 15)), + color: Color(0xff22c0e8), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30)), + // onPressed: (_isLoading) + // ? null + // : () async { + // setState(() { + // _isLoading = true; + // }); + // await Provider.of(context, + // listen: false) + // .addApply(_editJob); + // setState(() { + // _isLoading = false; + // }); + // }, + ), + ), + ], + )), + ], + ), + ), + ), + // floatingActionButton: Consumer( + // builder: (ctx, job, _) => + // FloatingActionButton( + // child: Icon( + // job.isSave ? MdiIcons.bookmark : MdiIcons.bookmarkOutline, + // color: Theme.of(context).colorScheme.secondary), + // onPressed: () { + // job.toggleSavePosts( + // authData.token, + // authData.userId, + // ); + // Scaffold.of(context).showSnackBar( + // SnackBar( + // duration: Duration(seconds: 1), + // content: Text('Save', style: TextStyle(color:Colors.white)), + // ), + // ); + // }, + // ), + // ), + ), + ], + ); + } +} diff --git a/lib/src/ui/seeker/layout/job_list.dart b/lib/src/ui/seeker/layout/job_list.dart new file mode 100644 index 0000000..c1a838b --- /dev/null +++ b/lib/src/ui/seeker/layout/job_list.dart @@ -0,0 +1,214 @@ +import 'package:flutter/material.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter_money_formatter/flutter_money_formatter.dart'; +import 'package:space/src/core/models/auth.dart'; +import 'package:space/src/core/models/cart.dart'; + +import 'package:space/src/ui/seeker/layout/job_details.dart'; +import 'package:space/src/core/models/job.dart'; + +class JobsList extends StatelessWidget { + @override + Widget build(BuildContext context) { + final job = Provider.of(context, listen: false); + final authData = Provider.of(context, listen: false); + final cart = Provider.of(context, listen: false); + // final save = Provider.of(context, listen: false); + return Dismissible( + direction: DismissDirection.endToStart, + confirmDismiss: (direction) { + return showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text('Are you sure?'), + content: Text('Do you want to remove the job from the list?'), + actions: [ + FlatButton( + child: Text('No'), + onPressed: () { + Navigator.of(ctx).pop(false); + }, + ), + FlatButton( + child: Text('Yes'), + onPressed: () { + Navigator.of(ctx).pop(true); + }, + ), + ], + )); + }, + onDismissed: (direction) {}, + key: ValueKey(job.id), + background: Container( + color: Theme.of(context).errorColor, + child: Icon( + Icons.delete, + color: Colors.white, + size: 40, + ), + alignment: Alignment.centerRight, + padding: EdgeInsetsDirectional.only(end: 20), + ), + child: Container( + padding: EdgeInsets.only(bottom: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(0), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Color(0xff0c0c0c0), + blurRadius: 1.5, + offset: Offset(1.0, 1.0)) + ], + ), + child: Stack( + alignment: Alignment(1.06, -2), + children: [ + ListTile( + leading: Column( + children: [ + Stack( + alignment: Alignment(1, -1), + children: [ + ClipOval( + // child: Text('Image.network(job.imageUrl, fit: BoxFit.cover, height: 40)') + ), + GestureDetector( + onTap: () { + Navigator.of(context).pushNamed( + JobDetails.routeName, + arguments: job.id); + }, + child: Material( + borderRadius: BorderRadius.circular(20), + color: Color(0xff22c0e8), + child: + Icon(Icons.add, color: Colors.white, size: 14), + ), + ), + ], + ), + ], + ), + title: Container( + height: 50, + padding: (EdgeInsets.only(top: 5)), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('job.employerName', + style: TextStyle( + fontSize: 14, color: Color(0xff3b3b3b))), + Row( + children: [ + Text(job.title, + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 12, + color: Color(0xff3b3b3b))), + Container( + padding: EdgeInsets.only(left: 5), + child: Material( + elevation: 1.0, + borderRadius: BorderRadius.circular(5.0), + color: Color(0xff65be3e), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 4), + child: Text('Full Time', + style: TextStyle( + color: Colors.white, fontSize: 9)), + ), + ), + ), + ], + ), + ], + ), + ), + subtitle: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.location_on, + size: 10, color: Color(0xff8997a7)), + Flexible( + child: Text('job.location', + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 12, color: Color(0xff8997a7)))), + ], + ), + Row( + children: [ + Text('Salary: ', + style: TextStyle( + fontSize: 10, color: Color(0xff8997a7))), + Text( + FlutterMoneyFormatter( + amount: job.salary, + settings: MoneyFormatterSettings( + symbol: 'Rp', + thousandSeparator: '.', + fractionDigits: 0)) + .output + .symbolOnLeft, + style: TextStyle( + fontSize: 10, color: Color(0xff3b3b3b))), + ], + ), + ], + ), + ), + onTap: () { + cart.addItem(job.id, job.salary, job.title); + Scaffold.of(context).hideCurrentSnackBar(); + Scaffold.of(context).showSnackBar( + SnackBar( + content: Text( + 'Added item to cart!', + ), + duration: Duration(seconds: 2), + action: SnackBarAction( + label: 'UNDO', + onPressed: () { + cart.removeSingleItem(job.id); + }, + ), + ), + ); + }), + Padding( + padding: EdgeInsets.only(top: 6), + child: Consumer( + builder: (ctx, job, _) => IconButton( + icon: Icon( + job.isSave ? MdiIcons.bookmark : MdiIcons.bookmarkOutline, + color: Theme.of(context).colorScheme.onPrimary), + onPressed: () { + job.toggleSavePosts( + authData.token, + authData.userId, + ); + Scaffold.of(context).showSnackBar( + SnackBar( + duration: Duration(seconds: 1), + content: + Text('Save', style: TextStyle(color: Colors.white)), + ), + ); + }, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/src/ui/seeker/layout/job_search.dart b/lib/src/ui/seeker/layout/job_search.dart new file mode 100644 index 0000000..edf229a --- /dev/null +++ b/lib/src/ui/seeker/layout/job_search.dart @@ -0,0 +1,303 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:space/src/ui/seeker/layout/job_search_result.dart'; + +class JobSearch extends StatefulWidget { + @override + _JobSearchState createState() => _JobSearchState(); +} + +class _JobSearchState extends State { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + String dropdownValue = 'Rp.0 - Rp.1.000.000'; + double _sliderValue = 20.0; + bool fulltime = false; + bool weekend = false; + bool freelance = false; + bool parttime = false; + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Scaffold( + resizeToAvoidBottomInset: false, + body: SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Container( + padding: EdgeInsets.only(top: 50), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text('SEARCH FOR A JOB', + textAlign: TextAlign.center, + style: style.copyWith( + color: Color(0xff2c4057), + fontSize: 13, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.normal, + letterSpacing: 1, + )), + Container( + margin: EdgeInsets.only(top: 15, bottom: 20), + width: 100, + color: Color(0xff22c0e8), + child: Divider( + height: 2, + ), + ), + Container( + height: 180, + width: 300, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextField( + style: style.copyWith( + fontSize: 16, color: Colors.black54), + decoration: new InputDecoration( + contentPadding: + EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), + hintText: "Keywords (e.g. Job Title...)", + hintStyle: style.copyWith(fontSize: 16), + filled: true, + fillColor: Color(0xffdcdfe3), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide( + color: Colors.transparent, width: 2)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Color(0xff22c0e8), width: 2), + borderRadius: BorderRadius.circular(30.0), + ), + ), + ), + TextField( + style: style.copyWith( + fontSize: 16, color: Colors.black54), + decoration: new InputDecoration( + contentPadding: + EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), + hintText: "Location (e.g. City, Zip...)", + hintStyle: style.copyWith(fontSize: 15), + filled: true, + fillColor: Color(0xffdcdfe3), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide( + color: Colors.transparent, width: 2)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Color(0xff22c0e8), width: 2), + borderRadius: BorderRadius.circular(30.0), + ), + ), + ), + FormField( + builder: (FormFieldState state) { + return InputDecorator( + decoration: InputDecoration( + contentPadding: + EdgeInsets.fromLTRB(30.0, 0.0, 25.0, 0.0), + errorStyle: TextStyle( + color: Colors.redAccent, fontSize: 16.0), + filled: true, + fillColor: Color(0xffdcdfe3), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide( + color: Colors.transparent, width: 2))), + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: dropdownValue, + onChanged: (String newValue) { + setState(() { + dropdownValue = newValue; + }); + }, + icon: Icon( + FeatherIcons.chevronDown, + size: 20, + ), + items: [ + 'Rp.0 - Rp.1.000.000', + 'Rp.1.000.000 - Rp.2.500.000', + 'Rp.2.500.000 - Rp.4.500.000', + 'Rp.4.500.000 -Rp.6.500.000', + 'Rp.6.500.000 - Rp.10.000.000', + 'Rp.10.000.000 - Above' + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: new Text(value, + style: style.copyWith( + color: Colors.black54, + fontSize: 14, + fontStyle: FontStyle.normal, + letterSpacing: 0.25, + )), + ); + }).toList(), + ), + ), + ); + }), + ], + ), + ), + Padding( + padding: EdgeInsets.only(bottom: 10, right: 30), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + Row( + children: [ + Checkbox( + activeColor: Color(0xff22c0e8), + value: fulltime, + onChanged: (bool value) { + setState(() { + fulltime = value; + }); + }, + ), + Text('Fulltime', + style: style.copyWith( + fontSize: 14, + color: Color(0xff8997a7))), + ], + ), + Row( + children: [ + Checkbox( + activeColor: Color(0xff22c0e8), + value: parttime, + onChanged: (bool value) { + setState(() { + parttime = value; + }); + }, + ), + Text('Partime', + style: style.copyWith( + fontSize: 14, + color: Color(0xff8997a7))), + ], + ), + ], + ), + Column( + children: [ + Row( + children: [ + Checkbox( + activeColor: Color(0xff22c0e8), + value: weekend, + onChanged: (bool value) { + setState(() { + weekend = value; + }); + }, + ), + Text('Weekend', + style: style.copyWith( + fontSize: 14, + color: Color(0xff8997a7))), + ], + ), + Row( + children: [ + Checkbox( + activeColor: Color(0xff22c0e8), + value: freelance, + onChanged: (bool value) { + setState(() { + freelance = value; + }); + }, + ), + Text('Freelance', + style: style.copyWith( + fontSize: 14, + color: Color(0xff8997a7))), + ], + ), + ], + ), + ], + ), + ), + Padding( + padding: EdgeInsets.only(left: 70, right: 70), + child: Row( + children: [ + Text('Distance', + style: style.copyWith( + fontSize: 14, color: Color(0xff8997a7))), + Text(' ${_sliderValue.toInt()}', + style: style.copyWith( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xff22c0e8))), + Text(' km', + style: style.copyWith( + fontSize: 14, + fontWeight: FontWeight.w600, + color: Color(0xff22c0e8))), + ], + ), + ), + Padding( + padding: EdgeInsets.only(left: 50, right: 50, bottom: 10), + child: Slider( + activeColor: Color(0xff22c0e8), + min: 0.0, + max: 50.0, + onChanged: (newRating) { + setState(() => _sliderValue = newRating); + }, + value: _sliderValue, + ), + ), + Container( + padding: EdgeInsets.only(left: 30, right: 30), + child: Material( + elevation: 3.0, + borderRadius: BorderRadius.circular(30.0), + color: Color(0xff57b22f), + child: MaterialButton( + padding: EdgeInsets.fromLTRB(60.0, 15.0, 20.0, 15.0), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => new JobSearchResult())); + }, + child: Row( + children: [ + Text('Search for a job', + textAlign: TextAlign.center, + style: style.copyWith(color: Colors.white)), + const Expanded( + child: Icon(Icons.arrow_forward, + color: Colors.white)), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ), + ); + }); + } +} diff --git a/lib/src/ui/seeker/layout/job_search_result.dart b/lib/src/ui/seeker/layout/job_search_result.dart new file mode 100644 index 0000000..9a1a7dd --- /dev/null +++ b/lib/src/ui/seeker/layout/job_search_result.dart @@ -0,0 +1,549 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_slidable/flutter_slidable.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +class JobSearchResult extends StatefulWidget { + @override + _JobSearchResultState createState() => _JobSearchResultState(); +} + +class _JobSearchResultState extends State { + SlidableController slidableController; + final List<_HomeItem> items = List.generate( + 21, + (i) => _HomeItem( + i, + _getJobTitle(i), + _getSubtitle(i), + _getSalary(i), + _getProviderName(i), + '$i', + _getJobTime(i), + ), + ); + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @protected + void initState() { + slidableController = SlidableController( + onSlideAnimationChanged: handleSlideAnimationChanged, + ); + super.initState(); + } + + void handleSlideAnimationChanged(Animation slideAnimation) {} + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context, true); + }, + icon: Icon(FeatherIcons.chevronLeft, + color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Text('Job Search', + style: TextStyle( + color: Color(0xff2c4057), + fontSize: 14, + fontWeight: FontWeight.w500, + letterSpacing: 1, + ))), + body: OrientationBuilder( + builder: (context, orientation) => _buildList( + context, + orientation == Orientation.portrait + ? Axis.vertical + : Axis.horizontal), + ), + ); + } + + Widget _buildList(BuildContext context, Axis direction) { + return ListView.builder( + scrollDirection: direction, + itemBuilder: (context, index) { + final Axis slidableDirection = + direction == Axis.horizontal ? Axis.vertical : Axis.horizontal; + var item = items[index]; + if (item.index < 8) { + return _getSlidableWithLists(context, index, slidableDirection); + } else { + return _getSlidableWithDelegates(context, index, slidableDirection); + } + }, + itemCount: items.length, + ); + } + + Widget _getSlidableWithLists( + BuildContext context, int index, Axis direction) { + final _HomeItem item = items[index]; + //final int t = index; + return Slidable( + key: Key(item.title), + controller: slidableController, + direction: direction, + dismissal: SlidableDismissal( + child: SlidableDrawerDismissal(), + onDismissed: (actionType) { + _showSnackBar(context, + actionType == SlideActionType.primary ? 'Saved' : 'Removed'); + setState(() { + items.removeAt(index); + }); + }, + ), + actionPane: _getActionPane(item.index), + actionExtentRatio: 0.25, + child: direction == Axis.horizontal + ? VerticalListItem(items[index]) + : HorizontalListItem(items[index]), + actions: [ + IconSlideAction( + caption: 'SAVE', + color: Color(0xffcecccc), + icon: FeatherIcons.save, + onTap: () => _showSnackBar(context, 'Archive'), + ), + ], + secondaryActions: [ + IconSlideAction( + caption: 'Remove', + color: Color(0xffcecccc), + icon: FeatherIcons.delete, + onTap: () => _showSnackBar(context, 'Remove'), + ), + ], + ); + } + + Widget _getSlidableWithDelegates( + BuildContext context, int index, Axis direction) { + final _HomeItem item = items[index]; + + return Slidable.builder( + key: Key(item.title), + controller: slidableController, + direction: direction, + dismissal: SlidableDismissal( + child: SlidableDrawerDismissal(), + closeOnCanceled: true, + onWillDismiss: (item.index != 10) + ? null + : (actionType) { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Remove'), + content: Text('Item will be Removed'), + actions: [ + FlatButton( + child: Text('Cancel'), + onPressed: () => Navigator.of(context).pop(false), + ), + FlatButton( + child: Text('Ok'), + onPressed: () => Navigator.of(context).pop(true), + ), + ], + ); + }, + ); + }, + onDismissed: (actionType) { + _showSnackBar(context, + actionType == SlideActionType.primary ? 'Saved' : 'Removed'); + setState(() { + items.removeAt(index); + }); + }, + ), + actionPane: _getActionPane(item.index), + actionExtentRatio: 0.25, + child: direction == Axis.horizontal + ? VerticalListItem(items[index]) + : HorizontalListItem(items[index]), + actionDelegate: SlideActionBuilderDelegate( + actionCount: 2, + builder: (context, index, animation, renderingMode) { + if (index == 0) { + return IconSlideAction( + caption: 'Archive', + color: renderingMode == SlidableRenderingMode.slide + ? Colors.blue.withOpacity(animation.value) + : (renderingMode == SlidableRenderingMode.dismiss + ? Colors.blue + : Colors.green), + icon: Icons.archive, + onTap: () async { + var state = Slidable.of(context); + var dismiss = await showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Remove'), + content: Text('Item will be Removed'), + actions: [ + FlatButton( + child: Text('Cancel'), + onPressed: () => Navigator.of(context).pop(false), + ), + FlatButton( + child: Text('Ok'), + onPressed: () => Navigator.of(context).pop(true), + ), + ], + ); + }, + ); + + if (dismiss) { + state.dismiss(); + } + }, + ); + } else { + return IconSlideAction( + caption: 'Share', + color: renderingMode == SlidableRenderingMode.slide + ? Colors.indigo.withOpacity(animation.value) + : Colors.indigo, + icon: Icons.share, + onTap: () => _showSnackBar(context, 'Share'), + ); + } + }), + secondaryActionDelegate: SlideActionBuilderDelegate( + actionCount: 2, + builder: (context, index, animation, renderingMode) { + if (index == 0) { + return IconSlideAction( + caption: 'More', + color: renderingMode == SlidableRenderingMode.slide + ? Colors.grey.shade200.withOpacity(animation.value) + : Colors.grey.shade200, + icon: Icons.more_horiz, + onTap: () => _showSnackBar(context, 'More'), + closeOnTap: false, + ); + } else { + return IconSlideAction( + caption: 'Remove', + color: renderingMode == SlidableRenderingMode.slide + ? Colors.red.withOpacity(animation.value) + : Colors.red, + icon: FeatherIcons.delete, + onTap: () => _showSnackBar(context, 'Remove'), + ); + } + }), + ); + } + + static Widget _getActionPane(int index) { + switch (index % 4) { + case 0: + return SlidableBehindActionPane(); + case 1: + return SlidableStrechActionPane(); + case 2: + return SlidableScrollActionPane(); + case 3: + return SlidableDrawerActionPane(); + default: + return null; + } + } + + static String _getJobTitle(int index) { + switch (index % 8) { + case 0: + return 'Store Leader'; + case 1: + return 'Cook'; + case 2: + return 'Cleaning Service'; + case 3: + return 'Coffe Shop'; + case 4: + return 'CCTV Installer, Helper'; + case 5: + return 'Job Title'; + case 6: + return 'Job Title'; + case 7: + return 'Job Title'; + default: + return null; + } + } + + static String _getJobTime(int index) { + switch (index % 8) { + case 0: + return 'Full Time'; + case 1: + return 'Part Time'; + case 2: + return 'Weekend'; + case 3: + return 'Freelance'; + default: + return null; + } + } + + static String _getProviderName(int index) { + switch (index % 8) { + case 0: + return 'Mekuru Ramen House'; + case 1: + return 'CV. Borneo Arya Group'; + case 2: + return 'PT. Maju Terus'; + case 3: + return 'PT. Mundur Terus'; + case 4: + return 'PT. Bumi Raya Group'; + case 5: + return 'PT. Bumi Liputan Jaya'; + case 6: + return 'PT. Angkasa Pura II'; + case 7: + return 'Blue Sky Premier Lounge Kota Pontianak'; + default: + return null; + } + } + + static String _getSubtitle(int index) { + switch (index % 8) { + case 0: + return 'Pontianak, West Borneo'; + case 1: + return 'Pontianak, West Borneo'; + case 2: + return 'Pontianak, West Borneo'; + case 3: + return 'Singkawang, West Borneo'; + case 4: + return 'Pontianak, West Borneo'; + case 5: + return 'Pontianak, West Borneo'; + case 6: + return 'Pontianak, West Borneo'; + case 7: + return 'Singkawang, West Borneo'; + default: + return null; + } + } + + static String _getSalary(int index) { + switch (index % 8) { + case 0: + return 'Rp 4.000.000 / m'; + case 1: + return 'Rp 2.000.000 / m'; + case 2: + return 'Rp 40k / h'; + case 3: + return 'Rp 50k / h'; + case 4: + return 'Rp 4.000.000 / m'; + case 5: + return 'Rp 2.000.000 / m'; + case 6: + return 'Rp 40k / h'; + case 7: + return 'Rp 50k / h'; + default: + return null; + } + } + + void _showSnackBar(BuildContext context, String text) { + Scaffold.of(context).showSnackBar(SnackBar(content: Text(text))); + } +} + +class HorizontalListItem extends StatelessWidget { + HorizontalListItem(this.item); + final _HomeItem item; + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + width: 160.0, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Center( + child: Text( + item.subtitle, + ), + ), + ), + ], + ), + ); + } +} + +class VerticalListItem extends StatelessWidget { + VerticalListItem(this.item); + final _HomeItem item; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () => + Slidable.of(context)?.renderingMode == SlidableRenderingMode.none + ? Slidable.of(context)?.open() + : Slidable.of(context)?.close(), + child: Container( + decoration: new BoxDecoration( + borderRadius: new BorderRadius.circular(0), + color: Colors.white, + boxShadow: [ + new BoxShadow( + color: Color(0xff0c0c0c0), + blurRadius: 1.5, + offset: new Offset(1.0, 1.0)) + ], + ), + child: Stack( + alignment: Alignment(1.06, -2), + children: [ + ListTile( + leading: Column( + children: [ + Stack( + alignment: Alignment(1, -1), + children: [ + CircleAvatar( + backgroundColor: Colors.white, + radius: 20.0, + child: Image.asset('assets/mekuru.png', height: 40)), + Material( + borderRadius: BorderRadius.circular(20), + color: Color(0xff22c0e8), + child: Icon(FeatherIcons.plus, + color: Colors.white, size: 14), + ), + ], + ), + ], + ), + title: Container( + height: 50, + padding: (EdgeInsets.only(top: 5)), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('${item.getProviderName}', + style: TextStyle(fontSize: 14)), + Row( + children: [ + Text('${item.getJobTitle}', + style: TextStyle( + fontFamily: 'VarelaRound', fontSize: 12)), + Container( + padding: EdgeInsets.only(left: 5), + child: Material( + elevation: 1.0, + borderRadius: BorderRadius.circular(5.0), + color: Color(0xff65be3e), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 4), + child: Text('${item.getJobTime}', + style: TextStyle( + color: Colors.white, fontSize: 9)), + ), + ), + ), + ], + ), + ], + ), + ), + subtitle: Container( + height: 30, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(FeatherIcons.mapPin, + size: 10, color: Color(0xff8997a7)), + Text('${item.subtitle}', + style: TextStyle( + fontSize: 12, color: Color(0xff8997a7))) + ], + ), + RichText( + text: new TextSpan(children: [ + new TextSpan( + text: "Salary: ", + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff8997a7), + fontSize: 10, + fontWeight: FontWeight.w400, + )), + new TextSpan( + text: '${item.getSalary}', + style: TextStyle( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 10, + fontWeight: FontWeight.w400, + )), + ])), + ], + ), + ), + trailing: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: new BorderRadius.circular(30.0)), + color: Color(0xff22c0e8), + child: Text('Apply', + style: TextStyle(color: Colors.white, fontSize: 14)), + onPressed: () {}), + ), + ], + ), + ), + ); + } +} + +class _HomeItem { + const _HomeItem( + this.index, + this.title, + this.subtitle, + this.getSalary, + this.getProviderName, + this.getJobTitle, + this.getJobTime, + ); + + final int index; + final String title; + final String subtitle; + final String getSalary; + final String getProviderName; + final String getJobTitle; + final String getJobTime; +} diff --git a/lib/src/ui/seeker/layout/order_item.dart b/lib/src/ui/seeker/layout/order_item.dart new file mode 100644 index 0000000..d4e7caa --- /dev/null +++ b/lib/src/ui/seeker/layout/order_item.dart @@ -0,0 +1,79 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import '../../../core/models/apply.dart' as ord; + +class ApplyItem extends StatefulWidget { + final ord.ApplyItem apply; + + ApplyItem(this.apply); + + @override + _ApplyItemState createState() => _ApplyItemState(); +} + +class _ApplyItemState extends State { + var _expanded = false; + + @override + Widget build(BuildContext context) { + return AnimatedContainer( + duration: Duration(milliseconds: 300), + height: + _expanded ? min(widget.apply.jobs.length * 20.0 + 110, 200) : 95, + child: Card( + margin: EdgeInsets.all(10), + child: Column( + children: [ + ListTile( + title: Text('\$${widget.apply.amount}'), + subtitle: Text( + DateFormat('dd/MM/yyyy hh:mm').format(widget.apply.dateTime), + ), + trailing: IconButton( + icon: Icon(_expanded ? Icons.expand_less : Icons.expand_more), + onPressed: () { + setState(() { + _expanded = !_expanded; + }); + }, + ), + ), + AnimatedContainer( + duration: Duration(milliseconds: 300), + padding: EdgeInsets.symmetric(horizontal: 15, vertical: 4), + height: _expanded ? min(widget.apply.jobs.length * 20.0 + 10, 100) : 0, + child: ListView( + children: widget.apply.jobs + .map( + (prod) => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + prod.title, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + Text( + '${prod.quantity}x \$${prod.price}', + style: TextStyle( + fontSize: 18, + color: Colors.grey, + ), + ) + ], + ), + ) + .toList(), + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/src/ui/seeker/layout/saved_lists.dart b/lib/src/ui/seeker/layout/saved_lists.dart new file mode 100644 index 0000000..29eab93 --- /dev/null +++ b/lib/src/ui/seeker/layout/saved_lists.dart @@ -0,0 +1,138 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter_money_formatter/flutter_money_formatter.dart'; +import 'package:space/src/core/models/job.dart'; + +import 'package:space/src/ui/seeker/layout/job_details.dart'; + +class SavePosts extends StatelessWidget { + @override + Widget build(BuildContext context) { + final job = Provider.of(context, listen: false); + return Dismissible( + direction: DismissDirection.endToStart, + onDismissed: (direction) { + // Provider.of(context, listen: false).removeItem(jobId); + }, + key: ValueKey(job.id), + background: Container( + color: Theme.of(context).errorColor, + child: Icon( + Icons.delete, + color: Colors.white, + size: 40, + ), + alignment: Alignment.centerRight, + padding: EdgeInsetsDirectional.only(end: 20), + ), + child: Stack( + alignment: Alignment(1.06, -2), + children: [ + ListTile( + leading: Column( + children: [ + Stack( + alignment: Alignment(1, -1), + children: [ + ClipOval( + // child: Image.network(imageUrl, fit: BoxFit.cover, height: 40) + ), + GestureDetector( + onTap: () { + Navigator.of(context).pushNamed(JobDetails.routeName, + arguments: job.id); + }, + child: Material( + borderRadius: BorderRadius.circular(20), + color: Color(0xff22c0e8), + child: Icon(Icons.add, color: Colors.white, size: 14), + ), + ), + ], + ), + ], + ), + title: Container( + height: 50, + padding: (EdgeInsets.only(top: 5)), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('employerName', + style: + TextStyle(fontSize: 14, color: Color(0xff3b3b3b))), + Row( + children: [ + Text(job.title, + style: TextStyle( + fontFamily: 'VarelaRound', + fontSize: 12, + color: Color(0xff3b3b3b))), + Container( + padding: EdgeInsets.only(left: 5), + child: Material( + elevation: 1.0, + borderRadius: BorderRadius.circular(5.0), + color: Color(0xff65be3e), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 4), + child: Text(job.type, + style: TextStyle( + color: Colors.white, fontSize: 9)), + ), + ), + ), + ], + ), + ], + ), + ), + subtitle: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.location_on, + size: 10, color: Color(0xff8997a7)), + Flexible( + child: Text(job.location, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 12, color: Color(0xff8997a7)))), + ], + ), + Row( + children: [ + Text('Salary: ', + style: TextStyle( + fontSize: 10, color: Color(0xff8997a7))), + Text( + FlutterMoneyFormatter( + amount: job.salary, + settings: MoneyFormatterSettings( + symbol: 'Rp', + thousandSeparator: '.', + fractionDigits: 0)) + .output + .symbolOnLeft, + style: TextStyle( + fontSize: 10, color: Color(0xff3b3b3b))), + ], + ), + ], + ), + ), + onTap: () { + Navigator.of(context).pushNamed( + JobDetails.routeName, + arguments: job.id, + ); + }), + ], + ), + ); + } +} diff --git a/lib/src/ui/seeker/layout/search_by_location.dart b/lib/src/ui/seeker/layout/search_by_location.dart new file mode 100644 index 0000000..7faa584 --- /dev/null +++ b/lib/src/ui/seeker/layout/search_by_location.dart @@ -0,0 +1,170 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:space/src/ui/employer/layout/employer_profile_view.dart'; + +class SearchByLocation extends StatefulWidget { + @override + _SearchByLocationState createState() => _SearchByLocationState(); +} + +class _SearchByLocationState extends State + with SingleTickerProviderStateMixin { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + return new Scaffold( + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context, true); + }, + icon: Icon(FeatherIcons.chevronLeft, + color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Text('Search by location', + style: style.copyWith( + color: Color(0xff2c4057), + fontSize: 14, + letterSpacing: 1, + )), + ), + body: Container( + height: MediaQuery.of(context).size.height, + child: Column( + children: [ + Container( + color: Color(0xffdedede), + height: 350, + ), + Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(20), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 150, + child: Image.asset( + 'assets/ketapang.png', + )), + Container( + height: 25, + child: Row( + children: [ + Icon(FontAwesomeIcons.twitterSquare, + size: 15, color: Color(0xff2ddbf5)), + Text(' Twitter', + style: style.copyWith( + fontSize: 10, color: Color(0xff2ddbf5))), + ], + ), + ), + Container( + height: 25, + child: Row( + children: [ + Icon(FontAwesomeIcons.facebookSquare, + size: 15, color: Color(0xff4267b2)), + Text(' Facebook', + style: style.copyWith( + fontSize: 10, color: Color(0xff4267b2))), + ], + ), + ), + Container( + height: 25, + child: Row( + children: [ + Icon(FontAwesomeIcons.googlePlusSquare, + size: 15, color: Color(0xffdb4a39)), + Text(' Google+', + style: style.copyWith( + fontSize: 10, color: Color(0xffdb4a39))), + ], + ), + ), + Container( + height: 25, + child: Row( + children: [ + Icon(FontAwesomeIcons.externalLinkSquareAlt, + size: 15, color: Color(0xff8997a7)), + Text(' www.mekururamen.com', + style: style.copyWith( + fontSize: 10, color: Color(0xff8997a7))), + ], + ), + ), + ], + ), + Container( + height: MediaQuery.of(context).size.height / 3.8, + padding: EdgeInsets.only(left: 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Mekuru Ramen', + style: style.copyWith(fontSize: 16)), + Text('The Best Ramen in Town', + style: style.copyWith( + fontSize: 10, color: Color(0xff3b3b3b))), + Row( + children: [ + Icon(FontAwesomeIcons.mapMarkerAlt, + size: 10, color: Color(0xff8997a7)), + Text(' Pontianak, West Borneo', + style: style.copyWith( + fontSize: 10, color: Color(0xff8997a7))) + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular(30.0)), + color: Color(0xff8997a7), + child: Text('Apply for a job', + style: style.copyWith( + color: Colors.white, fontSize: 14)), + onPressed: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => + new EmployerProfileView())); + }, + ), + ), + RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular(30.0)), + color: Color(0xff22c0e8), + child: Text('Follow', + style: style.copyWith( + color: Colors.white, fontSize: 14)), + onPressed: () {}, + ), + ], + ), + ], + )), + ], + ), + ), + ], + ), + )); + } +} diff --git a/lib/src/ui/seeker/layout/seeker_profile.dart b/lib/src/ui/seeker/layout/seeker_profile.dart new file mode 100644 index 0000000..fa76baa --- /dev/null +++ b/lib/src/ui/seeker/layout/seeker_profile.dart @@ -0,0 +1,229 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:space/src/ui/settings/setting_ui_payment.dart'; +import 'package:space/src/ui/settings/settings_notification.dart'; +import 'package:space/src/ui/seeker/layout/seeker_profile_setting.dart'; +import 'package:space/src/ui/settings/setting_ui_help.dart'; +import 'package:space/src/ui/settings/settings_ui_invite_friends.dart'; +import 'package:space/src/ui/settings/about_us.dart'; +import 'package:space/src/ui/seeker/layout/seeker_profile_view.dart'; + +void main() { + runApp(MaterialApp( + initialRoute: '/', + routes: { + '/': (context) => SeekerProfile(), + 'space/settings_notification': (context) => SettingNotification(), + 'space/seeker_profile_setting': (context) => SettingSeekerProfile(), + 'space/setting_ui_help': (context) => SettingUiHelp(), + 'space/settings_ui_invite_friends': (context) => UiInviteFriends(), + 'space/about_us': (context) => AboutUs(), + 'space/seeker_profile_view': (context) => SeekerProfileView(), + 'space/setting_payment_method': (context) => SettingUIPayment(), + }, + )); +} + +class SeekerProfile extends StatefulWidget { + const SeekerProfile({Key key, String title}) : super(key: key); + @override + _SeekerProfileState createState() => _SeekerProfileState(); +} + +class _SeekerProfileState extends State + with SingleTickerProviderStateMixin { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Scaffold( + body: SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Container( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + padding: EdgeInsets.only(top: 40, bottom: 15), + child: ListTile( + onTap: () { + Navigator.push( + context, + new MaterialPageRoute( + builder: (context) => new SeekerProfileView())); + }, + leading: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Nakamura Chan', + style: style.copyWith( + fontSize: 20, color: Color(0xff3b3b3b))), + Text('View and Edit Profile', + style: style.copyWith( + fontSize: 12, color: Color(0xff3b3b3b))), + ], + ), + trailing: CircleAvatar( + backgroundColor: Colors.white, + radius: 40.0, + child: Image.asset( + 'assets/img_profile-2.png', + height: 75, + ), + ), + ), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + ListTile( + title: Text('Notification', + style: style.copyWith(color: Color(0xff757575))), + trailing: Icon(FeatherIcons.bell, color: Color(0xff4d4d4d)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SettingNotification())); + }, + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + title: Text('Profile Setting', + style: style.copyWith(color: Color(0xff757575))), + trailing: + Icon(FeatherIcons.user, color: Color(0xff4d4d4d)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SettingSeekerProfile()), + ); + }), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + title: Text('Settings', + style: style.copyWith(color: Color(0xff757575))), + trailing: + Icon(FeatherIcons.settings, color: Color(0xff4d4d4d)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SettingUIPayment()), + ); + }), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + title: Text('Help?', + style: style.copyWith(color: Color(0xff757575))), + trailing: + Icon(FeatherIcons.info, color: Color(0xff4d4d4d)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SettingUiHelp()), + ); + }), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + title: Text('Feedback Us', + style: style.copyWith(color: Color(0xff757575))), + trailing: + Icon(FeatherIcons.send, color: Color(0xff4d4d4d)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + }), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + title: Text('Invite Friends', + style: style.copyWith(color: Color(0xff757575))), + trailing: + Icon(FeatherIcons.users, color: Color(0xff4d4d4d)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UiInviteFriends()), + ); + }), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + title: Text('FAQ', + style: style.copyWith(color: Color(0xff757575))), + trailing: Icon(FeatherIcons.helpCircle, + color: Color(0xff4d4d4d)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + }), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + title: Text('Abous Us', + style: style.copyWith(color: Color(0xff757575))), + trailing: Icon(FontAwesomeIcons.userTie, + color: Color(0xff4d4d4d)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + }), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Color(0xffc9c8c8)), + ), + ], + ), + ), + ), + ), + ); + }); + } +} diff --git a/lib/src/ui/seeker/layout/seeker_profile_setting.dart b/lib/src/ui/seeker/layout/seeker_profile_setting.dart new file mode 100644 index 0000000..21cabd9 --- /dev/null +++ b/lib/src/ui/seeker/layout/seeker_profile_setting.dart @@ -0,0 +1,339 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +class SettingSeekerProfile extends StatefulWidget { + @override + _SettingSeekerProfileState createState() => _SettingSeekerProfileState(); +} + +class _SettingSeekerProfileState extends State + with SingleTickerProviderStateMixin { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Container( + decoration: new BoxDecoration( + image: DecorationImage(image: AssetImage('assets/vector-5.png')), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context, true); + }, + icon: Icon( + FeatherIcons.chevronLeft, + color: Colors.white, + size: 16, + )), + elevation: 0, + backgroundColor: Colors.transparent, + title: Text('Profile Setting', + style: style.copyWith( + color: Colors.white, + fontSize: 14, + letterSpacing: 1, + )), + ), + body: SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Container( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + padding: EdgeInsetsDirectional.only(bottom: 20), + alignment: Alignment.topCenter, + child: CircleAvatar( + backgroundColor: Colors.white, + radius: 40.0, + child: + Image.asset('assets/img_profile-2.png', height: 75), + ), + ), + Container( + padding: EdgeInsets.only(bottom: 20), + child: Column( + children: [ + Text('Nakamura Chan', + style: style.copyWith( + fontSize: 15, color: Colors.white)), + Text('30', + style: style.copyWith( + fontSize: 15, color: Colors.white)), + ], + ), + ), + Container( + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + height: 30, + padding: EdgeInsets.all(5), + child: RaisedButton( + color: Colors.white, + shape: new RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular( + 30.0)), + child: Text('#restaurant', + style: + style.copyWith(fontSize: 12)), + onPressed: () {}, + )), + Container( + height: 30, + padding: EdgeInsets.all(5), + child: RaisedButton( + color: Colors.white, + shape: new RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular( + 30.0)), + child: Text('#ramen', + style: + style.copyWith(fontSize: 12)), + onPressed: () {}, + )), + Container( + height: 30, + padding: EdgeInsets.all(5), + child: RaisedButton( + color: Colors.white, + shape: new RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular( + 30.0)), + child: Text('#chef', + style: + style.copyWith(fontSize: 12)), + onPressed: () {}, + )), + Container( + height: 30, + padding: EdgeInsets.all(5), + child: RaisedButton( + color: Colors.white, + shape: new RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular( + 30.0)), + child: Text('#japanese', + style: + style.copyWith(fontSize: 12)), + onPressed: () {}, + )), + ], + )), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: new BorderRadius.only( + topLeft: const Radius.circular(30.0), + topRight: const Radius.circular(30.0), + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + onTap: () {}, + leading: Container( + width: 120, + alignment: Alignment.centerLeft, + child: Text('Full Name', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + ), + title: Text('Nakamura Chan', + style: style.copyWith( + color: Color(0xff757575), fontSize: 13)), + trailing: Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + onTap: () {}, + leading: Container( + width: 120, + alignment: Alignment.centerLeft, + child: Text('Address', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + ), + title: Text('Jl. Ketapang no 87D, Pontianak', + style: style.copyWith( + color: Color(0xff757575), fontSize: 13)), + trailing: Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + onTap: () {}, + leading: Container( + width: 120, + alignment: Alignment.centerLeft, + child: Text('Gender', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + ), + title: Text('Male', + style: style.copyWith( + color: Color(0xff757575), fontSize: 13)), + trailing: Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + onTap: () {}, + leading: Container( + width: 120, + alignment: Alignment.centerLeft, + child: Text('Date of Birth', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + ), + title: Text('31 December 1989', + style: style.copyWith( + color: Color(0xff757575), fontSize: 13)), + trailing: Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + onTap: () {}, + leading: Container( + width: 120, + alignment: Alignment.centerLeft, + child: Text('Education', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + ), + title: Text('High School', + style: style.copyWith( + color: Color(0xff757575), fontSize: 13)), + trailing: Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + onTap: () {}, + leading: Container( + width: 120, + alignment: Alignment.centerLeft, + child: Text('Experience', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + ), + title: Text('2 Years as Barista', + style: style.copyWith( + color: Color(0xff757575), fontSize: 13)), + trailing: Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + onTap: () {}, + leading: Container( + width: 120, + alignment: Alignment.centerLeft, + child: Text('Current', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + ), + title: Text('1 Years as Head Chef', + style: style.copyWith( + color: Color(0xff757575), fontSize: 13)), + trailing: Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ListTile( + onTap: () {}, + leading: Container( + width: 120, + alignment: Alignment.centerLeft, + child: Text('Upload Resume', + style: style.copyWith( + color: Color(0xff757575), fontSize: 14)), + ), + title: RichText( + text: TextSpan(children: [ + TextSpan( + text: 'CV.PDF - ', + style: style.copyWith( + color: Color(0xff9faab6), fontSize: 13)), + TextSpan( + text: 'successful uploaded', + style: style.copyWith( + color: Color(0xff57b22f), fontSize: 13)), + ])), + trailing: Icon(FeatherIcons.chevronRight, + color: Color(0xff757575), size: 20), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ); + }); + } +} diff --git a/lib/src/ui/seeker/layout/seeker_profile_view.dart b/lib/src/ui/seeker/layout/seeker_profile_view.dart new file mode 100644 index 0000000..f2eeb3e --- /dev/null +++ b/lib/src/ui/seeker/layout/seeker_profile_view.dart @@ -0,0 +1,299 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +class SeekerProfileView extends StatefulWidget { + @override + _SeekerProfileViewState createState() => _SeekerProfileViewState(); +} + +class _SeekerProfileViewState extends State + with SingleTickerProviderStateMixin { + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/vector-5.png'), + alignment: AlignmentDirectional.topEnd, + fit: BoxFit.cover), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context, true); + }, + icon: Icon(FeatherIcons.chevronLeft, + color: Colors.white, size: 16)), + elevation: 0, + backgroundColor: Colors.transparent, + ), + body: SingleChildScrollView( + child: LayoutBuilder(builder: + (BuildContext context, BoxConstraints viewportConstraints) { + return Container( + child: Column( + children: [ + Container( + padding: EdgeInsetsDirectional.only(bottom: 10), + alignment: Alignment.topCenter, + child: CircleAvatar( + backgroundColor: Colors.white, + minRadius: 40, + maxRadius: 45, + child: + Image.asset('assets/img_profile-2.png', scale: 1.4), + ), + ), + Container( + padding: EdgeInsets.only(bottom: 20), + child: Column( + children: [ + Text('Nakamura Chan', + style: style.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.white)), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(FeatherIcons.mapPin, + size: 10, color: Colors.white), + Text(' Pontianak, West Borneo', + style: style.copyWith( + fontSize: 12, + color: Colors.white, + height: 2)) + ], + ), + ], + ), + ), + new Center(), + Container( + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + height: 30, + padding: EdgeInsets.all(5), + child: RaisedButton( + color: Colors.white, + shape: new RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular(30.0)), + child: Text('#restaurant', + style: style.copyWith(fontSize: 12)), + onPressed: () {}, + )), + Container( + height: 30, + padding: EdgeInsets.all(5), + child: RaisedButton( + color: Colors.white, + shape: new RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular(30.0)), + child: Text('#ramen', + style: style.copyWith(fontSize: 12)), + onPressed: () {}, + )), + Container( + height: 30, + padding: EdgeInsets.all(5), + child: RaisedButton( + color: Colors.white, + shape: new RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular(30.0)), + child: Text('#chef', + style: style.copyWith(fontSize: 12)), + onPressed: () {}, + )), + Container( + height: 30, + padding: EdgeInsets.all(5), + child: RaisedButton( + color: Colors.white, + shape: new RoundedRectangleBorder( + borderRadius: + new BorderRadius.circular(30.0)), + child: Text('#japanese', + style: style.copyWith(fontSize: 12)), + onPressed: () {}, + )), + ], + )), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10), + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: new BorderRadius.only( + topLeft: const Radius.circular(30.0), + topRight: const Radius.circular(30.0), + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: + EdgeInsets.only(left: 20, right: 20, top: 10), + child: ListTile( + leading: Padding( + padding: EdgeInsets.only(top: 3), + child: Image.asset('assets/icon6.png', + scale: 3.5)), + title: Text('Address', + style: style.copyWith( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold)), + subtitle: Text('Pontianak, West Borneo', + style: style.copyWith( + color: Color(0xff757575), fontSize: 16)), + ), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: ListTile( + leading: Padding( + padding: EdgeInsets.only(top: 3), + child: Image.asset('assets/icon3.png', + scale: 3.5)), + title: Text('Age', + style: style.copyWith( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold)), + subtitle: Text('30 Years Old', + style: style.copyWith( + color: Color(0xff757575), fontSize: 16)), + ), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: ListTile( + leading: Padding( + padding: EdgeInsets.only(top: 3), + child: Image.asset('assets/icon5.png', + scale: 3.5)), + title: Text('Gender', + style: style.copyWith( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold)), + subtitle: Text('Male', + style: style.copyWith( + color: Color(0xff757575), fontSize: 16)), + ), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: ListTile( + leading: Padding( + padding: EdgeInsets.only(top: 3), + child: Image.asset('assets/icon4.png', + scale: 3.5)), + title: Text('Experience', + style: style.copyWith( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold)), + subtitle: Text('10 Years as Chef', + style: style.copyWith( + color: Color(0xff757575), fontSize: 16)), + ), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: ListTile( + leading: Padding( + padding: EdgeInsets.only(top: 3), + child: Image.asset('assets/icon8.png', + scale: 3.5)), + title: Text('Education', + style: style.copyWith( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold)), + subtitle: Text('High School', + style: style.copyWith( + color: Color(0xff757575), fontSize: 16)), + ), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: ListTile( + leading: Padding( + padding: EdgeInsets.only(top: 3), + child: Image.asset('assets/icon7.png', + scale: 3.5)), + title: Text('Current Job', + style: style.copyWith( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold)), + subtitle: Text('Full Time Chef', + style: style.copyWith( + color: Color(0xff757575), fontSize: 16)), + ), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider(color: Color(0xffc9c8c8)), + ), + ], + ), + ), + ], + ), + ); + }), + ), + ), + ); + } +} diff --git a/lib/src/ui/seeker/screens/applys_screen.dart b/lib/src/ui/seeker/screens/applys_screen.dart new file mode 100644 index 0000000..c8f5589 --- /dev/null +++ b/lib/src/ui/seeker/screens/applys_screen.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/apply.dart' show Applys; +import 'package:space/src/ui/seeker/layout/apply_post.dart'; + +class ApplysScreen extends StatelessWidget { + static const routeName = '/orders'; + + @override + Widget build(BuildContext context) { + print('building orders'); + // final applyData = Provider.of(context); + return Scaffold( + body: FutureBuilder( + future: Provider.of(context, listen: false).fetchAndSetApplys(), + builder: (ctx, dataSnapshot) { + if (dataSnapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator()); + } else { + if (dataSnapshot.error != null) { + // ... + // Do error handling stuff + return Center( + child: Text('An error occurred!'), + ); + } else { + return Consumer( + builder: (ctx, applyData, child) => ListView.builder( + itemCount: applyData.applys.length, + itemBuilder: (ctx, i) => ApplyItem(applyData.applys[i]), + ), + ); + } + } + }, + ), + ); + } +} diff --git a/lib/src/ui/seeker/screens/cart_screen.dart b/lib/src/ui/seeker/screens/cart_screen.dart new file mode 100644 index 0000000..46dfc02 --- /dev/null +++ b/lib/src/ui/seeker/screens/cart_screen.dart @@ -0,0 +1,102 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:space/src/core/models/apply.dart'; + +import 'package:space/src/core/models/cart.dart' show Cart; +import 'package:space/src/ui/seeker/layout/cart_item.dart'; + +class CartScreen extends StatelessWidget { + static const routeName = '/cart'; + + @override + Widget build(BuildContext context) { + final cart = Provider.of(context); + return Scaffold( + appBar: AppBar( + title: Text('Your Cart'), + ), + body: Column( + children: [ + Card( + margin: EdgeInsets.all(15), + child: Padding( + padding: EdgeInsets.all(8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Total', + style: TextStyle(fontSize: 20), + ), + Spacer(), + Chip( + label: Text( + '\$${cart.totalAmount.toStringAsFixed(2)}', + style: TextStyle( + color: Theme.of(context).primaryTextTheme.title.color, + ), + ), + backgroundColor: Theme.of(context).primaryColor, + ), + OrderButton(cart: cart) + ], + ), + ), + ), + SizedBox(height: 10), + Expanded( + child: ListView.builder( + itemCount: cart.items.length, + itemBuilder: (ctx, i) => CartItem( + cart.items.values.toList()[i].id, + cart.items.keys.toList()[i], + cart.items.values.toList()[i].price, + cart.items.values.toList()[i].quantity, + cart.items.values.toList()[i].title, + ), + ), + ) + ], + ), + ); + } +} + +class OrderButton extends StatefulWidget { + const OrderButton({ + Key key, + @required this.cart, + }) : super(key: key); + + final Cart cart; + + @override + _OrderButtonState createState() => _OrderButtonState(); +} + +class _OrderButtonState extends State { + var _isLoading = false; + + @override + Widget build(BuildContext context) { + return FlatButton( + child: _isLoading ? CircularProgressIndicator() : Text('ORDER NOW'), + onPressed: (widget.cart.totalAmount <= 0 || _isLoading) + ? null + : () async { + setState(() { + _isLoading = true; + }); + await Provider.of(context, listen: false).addApply( + widget.cart.items.values.toList(), + widget.cart.totalAmount, + ); + setState(() { + _isLoading = false; + }); + widget.cart.clear(); + }, + textColor: Theme.of(context).colorScheme.onSecondary, + ); + } +} diff --git a/lib/src/ui/seeker/screens/jobs_list_screen.dart b/lib/src/ui/seeker/screens/jobs_list_screen.dart new file mode 100644 index 0000000..304f624 --- /dev/null +++ b/lib/src/ui/seeker/screens/jobs_list_screen.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/jobs.dart'; +import 'package:space/src/ui/seeker/layout/job_list.dart'; + +class JobsListScreen extends StatefulWidget { + _JobsListScreenState createState() => _JobsListScreenState(); +} + +class _JobsListScreenState extends State { + var _isInit = true; + var _isLoading = false; + + @override + void didChangeDependencies() { + if (_isInit) { + setState(() { + _isLoading = true; + }); + Provider.of(context).fetchAndSetJobs().then((_) { + setState(() { + _isLoading = false; + }); + }); + } + _isInit = false; + super.didChangeDependencies(); + } + + @override + Widget build(BuildContext context) { + final jobData = Provider.of(context); + final jobs = jobData.posts; + return Scaffold( + backgroundColor: Colors.transparent, + body: _isLoading + ? Center( + child: CircularProgressIndicator(), + ) + : ListView.builder( + itemCount: jobs.length, + itemBuilder: (ctx, i) => ChangeNotifierProvider.value( + // builder: (c) => jobs[i], + value: jobs[i], + child: JobsList( + // jobs[i].id, + // jobs[i].title, + // jobs[i].imageUrl, + ), + ), + ), + ); + } +} diff --git a/lib/src/ui/seeker/screens/save_screen.dart b/lib/src/ui/seeker/screens/save_screen.dart new file mode 100644 index 0000000..a4a867e --- /dev/null +++ b/lib/src/ui/seeker/screens/save_screen.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:space/src/core/models/jobs.dart'; +import 'package:space/src/ui/seeker/layout/saved_lists.dart'; + +class SaveListScreen extends StatelessWidget { + final bool showSave; + + SaveListScreen(this.showSave); + + @override + Widget build(BuildContext context) { + final jobData = Provider.of(context); + final jobs = showSave ? jobData.savePosts : jobData.posts; + return ListView.builder( + padding: const EdgeInsets.all(10.0), + itemCount: jobs.length, + itemBuilder: (ctx, i) => ChangeNotifierProvider.value( + value: jobs[i], + child: SavePosts(), + ), + ); + } +} diff --git a/lib/src/ui/seeker/screens/seeker_tabs.dart b/lib/src/ui/seeker/screens/seeker_tabs.dart new file mode 100644 index 0000000..2ada651 --- /dev/null +++ b/lib/src/ui/seeker/screens/seeker_tabs.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; + +import 'package:space/src/ui/seeker/widgets/seeker_app_drawer.dart'; +import 'package:space/src/ui/components/seeker_app_bar.dart'; +import 'package:space/src/ui/seeker/screens/applys_screen.dart'; +import 'package:space/src/ui/seeker/screens/jobs_list_screen.dart'; +import 'package:space/src/ui/seeker/screens/save_screen.dart'; + +var _showSaves = false; + +class SeekerTabs extends StatelessWidget { + static const routeName = 'seeker-tabs'; + + @override + Widget build(BuildContext context) { + return DefaultTabController( + length: 3, + child: Scaffold( + drawer: AppDrawer(), + body: NestedScrollView( + headerSliverBuilder: (context, innerBoxScrolled) => [SeekerAppBar()], + body: TabBarView( + children: [ + // RefreshIndicator( + // onRefresh: () async { + // return true; + // }, + // child: + JobsListScreen(), + ApplysScreen(), + SaveListScreen(_showSaves), + ], + ), + ), + ), + ); + } +} diff --git a/lib/src/ui/seeker/widgets/seeker_app_drawer.dart b/lib/src/ui/seeker/widgets/seeker_app_drawer.dart new file mode 100644 index 0000000..a31c640 --- /dev/null +++ b/lib/src/ui/seeker/widgets/seeker_app_drawer.dart @@ -0,0 +1,236 @@ +import 'package:flutter/material.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:space/src/core/models/auth.dart'; +import 'package:space/src/ui/seeker/layout/seeker_profile_setting.dart'; +import 'package:space/src/ui/seeker/layout/seeker_profile_view.dart'; +import 'package:space/src/ui/settings/about_us.dart'; +import 'package:space/src/ui/settings/setting_ui_help.dart'; +import 'package:space/src/ui/settings/setting_ui_payment.dart'; +import 'package:space/src/ui/settings/settings_notification.dart'; +import 'package:space/src/ui/settings/settings_ui_invite_friends.dart'; + +class AppDrawer extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Drawer( + child: Container( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.only(top: 20, bottom: 10), + child: ListTile( + onTap: () { Navigator.push(context, new MaterialPageRoute( + builder: (context) => + new SeekerProfileView()) + ); }, + leading: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children:[ + Text('Nakamura Chan', style: TextStyle(fontSize: 16, color: Color(0xff3b3b3b))), + Text('View and Edit Profile', style: TextStyle(fontSize: 11, color: Color(0xff3b3b3b))), + ],), + trailing: CircleAvatar( + backgroundColor: Colors.white, + radius: 40.0, + child: Image.asset('assets/img_profile-2.png', height: 75,), + ), + ), + ), + + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('Notification', style: TextStyle(color: Color(0xff757575), fontSize: 12, height: 0.5)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.bellOutline, color: Color(0xff4d4d4d), size: 18)), + onTap: () { Navigator.push(context, MaterialPageRoute(builder: (context) =>SettingNotification())); }, + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('Profile Setting', style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.accountEditOutline, color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => SettingSeekerProfile()), + ); + } + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('Settings', style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.settingsOutline, color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => SettingUIPayment()), + ); + } + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('Help?', style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.accountQuestionOutline, color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => SettingUiHelp()), + ); + } + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + Container( + height: 50, + child: ListTile( + title:Text('Feedback Us', style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.sendCircleOutline, color: Color(0xff4d4d4d), size: 20)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + } + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('Invite Friends', style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.accountMultiplePlusOutline, color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => UiInviteFriends()), + ); + } + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('FAQ', style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.helpCircleOutline, color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + } + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('Abous Us', style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.accountGroupOutline, color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => AboutUs()), + ); + } + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + Container( + height: 50, + child: ListTile( + title: Text('Log Out', style: TextStyle(color: Color(0xff757575), fontSize: 12)), + trailing: Padding( + padding: EdgeInsets.only(bottom: 5), + child: Icon(MdiIcons.logoutVariant, color: Color(0xff4d4d4d), size: 18)), + onTap: () { + Navigator.of(context).pop(); + Provider.of(context, listen: false).logout(); + } + ), + ), + Container( + height: 0, + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + + ],), + + ), + ); + } +} diff --git a/lib/src/ui/settings/about_us.dart b/lib/src/ui/settings/about_us.dart new file mode 100644 index 0000000..b14241d --- /dev/null +++ b/lib/src/ui/settings/about_us.dart @@ -0,0 +1,110 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +class AboutUs extends StatefulWidget { + const AboutUs({ Key key, String title }) : super(key: key); + @override + _AboutUsState createState() => _AboutUsState(); +} + +class _AboutUsState extends State with SingleTickerProviderStateMixin { + + + TextStyle style2 = TextStyle(fontFamily: 'Cocogoose', fontSize: 20.0); + TextStyle style = TextStyle(fontFamily: 'TitilliumWeb', fontSize: 20.0); + TextStyle style3 = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/vector-5.png'), + alignment: AlignmentDirectional.topEnd, + fit: BoxFit.cover + ), + ), + child: new Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context,true); + }, + icon: Icon(FeatherIcons.chevronLeft, color: Colors.white, size: 16)), + elevation: 10, + backgroundColor: Colors.transparent, + title: Text('Abous Us', style: style3.copyWith(color: Color(0xffffffff), + fontSize: 14, fontWeight: FontWeight.w500,letterSpacing: 1,)), + ), + body: Column(children: [ + Container( + child: Stack( + alignment: AlignmentDirectional.center, + children: [ + CircleAvatar( + backgroundImage: AssetImage('assets/grunge.png'), + radius: 120, + backgroundColor: Colors.white, + ), + Container( + margin: EdgeInsets.only(right: 80), + child: Image.asset('assets/vector-7.png', height: 90), + ), + Container( + margin: EdgeInsets.only(top: 90, right: 20), + child: Image.asset('assets/vector-7.png', height: 90), + ), + Container( + margin: EdgeInsets.only(left: 70, top: 60), + child: Image.asset('assets/vector-7.png', height: 90), + ), + ], + ), + ) , + Container( + padding: EdgeInsets.symmetric(horizontal: 30), + margin: EdgeInsets.only(top: 5), + child: Column( + children: [ + Text('About Us', + style: style2.copyWith(fontSize: 30, color: Colors.white, fontWeight: FontWeight.bold)), + Text('Dreamjob adalah tempat untuk mewujudkan mimpi kalian semua dimulai dari bekerja. Pekerjaan impian anda bisa saja ada disini. Bisa juga kerjaan biasa yang akan membawa kalian melangkah lebih jauh untuk menggapai mimpi.', + textAlign: TextAlign.center, + style: style.copyWith(fontSize: 12, color: Colors.white)), + Text('Logo astronot melambangkan cita-cita yang terucapkan oleh mayoritas individu semasa kecil. Tidak ada jalan pintas untuk menjadi astronot selain belajar dan kerja keras. Dua simbol bintang dengan ukuran kecil dan besar di logo melambangkan simbol pencapaian dan reward yang melalui progress dari kecil menjadi besar.', + textAlign: TextAlign.center, + style: style.copyWith(fontSize: 12, color: Colors.white)), + Column( + children: [ + Text('So, Dreamers,', + style: style.copyWith(fontSize: 12, color: Colors.white) + ), + Text('"Never stop working and never stop dreaming"', + style: style.copyWith(fontSize: 12, color: Colors.white) + ), + SizedBox( + height: 15, + ), + Text('In DREAMJOB, We Make It Happen!', + style: style.copyWith(fontSize: 12, color: Colors.white) + ), + + + ], + ) + ], + ), + ), + ],), + + ), + + + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/settings/setting_payment_method.dart b/lib/src/ui/settings/setting_payment_method.dart new file mode 100644 index 0000000..db35924 --- /dev/null +++ b/lib/src/ui/settings/setting_payment_method.dart @@ -0,0 +1,402 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Slidable Demo', + home: PaymentMethod(title: 'Flutter Slidable Demo'), + ); + } +} + + +class PaymentMethod extends StatefulWidget { + const PaymentMethod({ Key key, String title }) : super(key: key); + @override + _PaymentMethodState createState() => _PaymentMethodState(); +} + +class _PaymentMethodState extends State with SingleTickerProviderStateMixin { + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + bool save = false; + + final _formKey = GlobalKey(); + @override + Widget build(BuildContext context) { + return new Scaffold( + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context,true); + }, + icon: Icon(FeatherIcons.chevronLeft, color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Text('Settings', style: style.copyWith(color: Color(0xff2c4057), + fontSize: 14, fontWeight: FontWeight.w500,letterSpacing: 1,)), + ), + + body: Container( + padding: EdgeInsets.only(top: 20, left: 5, right: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + leading: Text('Telkomsel', style: style.copyWith(fontSize: 17, color: Color(0xff3b3b3b))), + trailing: Image.asset('assets/icon12.png', scale: 1.6), + onTap: (){}, + ), + Container( + padding: EdgeInsets.only(left: 16, right: 20), + margin: EdgeInsets.only(bottom: 15), + height: 0, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + Text('Payment Method', style: style.copyWith(fontWeight: FontWeight.bold, color: Color(0xff3b3b3b))), + Text('Choose your payments', style: style.copyWith(fontSize: 12, fontWeight: FontWeight.bold, color: Color(0xff3b3b3b), height: 2)), + ListTile( + leading: Text('Add Card', style: style.copyWith(fontSize: 17, color: Color(0xff3b3b3b), height: 2)), + trailing: Image.asset('assets/icon11.png', scale: 1.6), + onTap: () { showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + content: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text('Add Card', style: style.copyWith(fontSize: 14, fontWeight: FontWeight.bold)), + Text('Card Number', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, height: 2)), + Container( + margin: EdgeInsets.only(top: 5, bottom: 20), + child: TextField( + style: style.copyWith(fontSize: 16, color: Color(0xff8997a7)), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(10), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(10.0), + ), + fillColor: Color(0xffdcdfe3), + filled: true, + ), + ), + ), + Row(children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Exp Dates', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, height: 2)), + Container( + margin: EdgeInsets.only(right: 30, top: 5, bottom: 10), + child: TextField( + style: style.copyWith(fontSize: 16, color: Color(0xff8997a7)), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(10), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(10.0), + ), + fillColor: Color(0xffdcdfe3), + filled: true, + ), + ), + ), + ],), + ), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Security Code', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, height: 2)), + Container( + margin: EdgeInsets.only(right: 30, top: 5, bottom: 10), + child: TextField( + style: style.copyWith(fontSize: 16, color: Color(0xff8997a7)), + decoration: InputDecoration( + focusColor: Colors.yellow, + contentPadding: EdgeInsets.all(10), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(10.0), + ), + fillColor: Color(0xffdcdfe3), + filled: true, + ), + ), + ), + ],), + ), + ],), + Row(children: [ + Checkbox( + checkColor: Color(0xff22c0e8), + activeColor: Colors.white, + value: save, + onChanged: (bool value) { + setState(() { + save = value; + }); + }, + ), + Text('SAVE CARD', style: style.copyWith(fontSize: 12, fontWeight: FontWeight.bold)), + ],), + + Padding( + padding: const EdgeInsets.only(right: 155), + child: RaisedButton( + shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(10.0)), + color: Color(0xff22c0e8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('ADD CARD', style: style.copyWith(fontSize: 12, color: Colors.white)), + Icon(Icons.arrow_forward, size: 18, color: Colors.white) + ],), + onPressed: () { + if (_formKey.currentState.validate()) { + _formKey.currentState.save(); + } + }, + ), + ) + ], + ), + ), + + ); + }); + } + ), + Container( + padding: EdgeInsets.only(left: 16, right: 20), + margin: EdgeInsets.only(top: 5), + height: 5, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + ListTile( + leading: Text('Visa **** **** **** 5967', style: style.copyWith(fontSize: 17, color: Color(0xff3b3b3b), height: 2)), + trailing: Image.asset('assets/icon14.png', scale: 1.6) + ), + Container( + padding: EdgeInsets.only(left: 16, right: 20), + margin: EdgeInsets.only(top: 5), + height: 5, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + ListTile( + leading: Text('Master **** **** **** 3461', style: style.copyWith(fontSize: 17, color: Color(0xff3b3b3b), height: 2)), + trailing: Image.asset('assets/icon13.png', scale: 1.6) + ), + Container( + padding: EdgeInsets.only(left: 16, right: 20), + margin: EdgeInsets.only(top: 5), + height: 5, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + ListTile( + leading: Text('Add GoPay', style: style.copyWith(fontSize: 17, color: Color(0xff3b3b3b), height: 2)), + trailing: Image.asset('assets/icon15.png', scale: 1.6), + onTap: () { showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + content: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text('Add GoPay', style: style.copyWith(fontSize: 14, fontWeight: FontWeight.bold)), + Text('Phone Number', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, height: 2)), + Row( + children: [ + Flexible( + child: Container( + width: 40, + margin: EdgeInsets.only(top: 5, right: 10), + child: TextField( + style: style.copyWith(fontSize: 16, color: Color(0xff8997a7)), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(10), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(10.0), + ), + fillColor: Color(0xffdcdfe3), + filled: true, + ), + ), + ), + ), + + Flexible( + child: Container( + margin: EdgeInsets.only(top: 5), + child: TextField( + style: style.copyWith(fontSize: 16, color: Color(0xff8997a7)), + decoration: InputDecoration( + focusColor: Colors.yellow, + contentPadding: EdgeInsets.all(10), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(10.0), + ), + fillColor: Color(0xffdcdfe3), + filled: true, + ), + ), + ), + ), + ],), + + + + Row(children: [ + Flexible( + child: Container( + padding: EdgeInsets.only(top: 30, bottom: 10, right: 10), + child: RaisedButton( + shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(10.0)), + color: Color(0xff22c0e8), + onPressed: () { + if (_formKey.currentState.validate()) { + _formKey.currentState.save(); + } + }, + child: Text('SEND OTP', style: style.copyWith(fontSize: 10, color: Colors.white)), + ), + ) + ), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('OTP', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, height: 2)), + Container( + margin: EdgeInsets.only(right: 30), + child: TextField( + style: style.copyWith(fontSize: 16, color: Color(0xff8997a7)), + decoration: InputDecoration( + focusColor: Colors.yellow, + contentPadding: EdgeInsets.all(10), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + borderSide: BorderSide(color: Colors.transparent, width: 1), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xff22c0e8), width: 1), + borderRadius: BorderRadius.circular(10.0), + ), + fillColor: Color(0xffdcdfe3), + filled: true, + ), + ), + ), + ],), + ), + ],), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('By continuing, you agree to :', style: style.copyWith(fontSize: 14, fontWeight: FontWeight.bold)), + Text('- Dreamjob Terms of Service', style: style.copyWith(fontSize: 14, fontWeight: FontWeight.bold)), + Text('- GoPay Terms of Service', style: style.copyWith(fontSize: 14, fontWeight: FontWeight.bold, height: 2)), + ],), + + Container( + width: 400, + padding: EdgeInsets.symmetric(horizontal: 10), + child: RaisedButton( + shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(10.0)), + color: Color(0xff22c0e8), + onPressed: () { + if (_formKey.currentState.validate()) { + _formKey.currentState.save(); + } + }, + child: Text('Continue', style: style.copyWith(fontSize: 12, color: Colors.white)), + ), + ) + ], + ), + ), + + ); + }); + } + ), + Container( + padding: EdgeInsets.only(left: 16, right: 20), + margin: EdgeInsets.only(top: 5), + height: 5, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + ListTile( + leading: Text('Add OVO', style: style.copyWith(fontSize: 17, color: Color(0xff3b3b3b), height: 2)), + trailing: CircleAvatar( + backgroundColor: Colors.black, + radius: 11, + child: Image.asset('assets/icon16.png', scale: 1.6,) + ), + ), + Container( + padding: EdgeInsets.only(left: 16, right: 20), + margin: EdgeInsets.only(top: 5), + height: 5, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + ], + ), + ) + + + ); + + + } + + +} \ No newline at end of file diff --git a/lib/src/ui/settings/setting_ui_help.dart b/lib/src/ui/settings/setting_ui_help.dart new file mode 100644 index 0000000..295bb52 --- /dev/null +++ b/lib/src/ui/settings/setting_ui_help.dart @@ -0,0 +1,112 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Slidable Demo', + home: SettingUiHelp(title: 'Flutter Slidable Demo'), + ); + } +} + + +class SettingUiHelp extends StatefulWidget { + const SettingUiHelp({ Key key, String title }) : super(key: key); + @override + _SettingUiHelpState createState() => _SettingUiHelpState(); +} + +class _SettingUiHelpState extends State with SingleTickerProviderStateMixin { + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + return new Scaffold( + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context,true); + }, + icon: Icon(FeatherIcons.chevronLeft, color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Text('Help', style: style.copyWith(color: Color(0xff2c4057), + fontSize: 14, fontWeight: FontWeight.w500,letterSpacing: 1,)), + ), + + body: Container( + height: MediaQuery.of(context).size.height, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Help', style: style.copyWith(fontWeight: FontWeight.bold, color: Color(0xff3b3b3b))), + Text('Get in touch', style: style.copyWith(fontSize: 14, color: Color(0xff3b3b3b))), + ],), + ), + Container( + color: Color(0xffdedede), + height: 250, + ), + + Container( + width: MediaQuery.of(context).size.width, + margin: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 120, + child: Image.asset('assets/logo_vertical.png',) + ), + + Container( + margin: EdgeInsets.only(top: 15), + height: 120, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row(children: [ + Icon(FeatherIcons.mapPin, size: 12, color: Color(0xff010101)), + Text(' PELNI Tower, 2nd Floor, Jl. Sultan Abdurahman no 123,', + style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, color: Color(0xff010101))), + ],), + Padding( + padding: EdgeInsets.only(left: 18), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Pontianak West Borneo, Indonesia', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, color: Color(0xff010101))), + Text('Dreamjob.id@gmail.com', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, color: Color(0xff010101), height: 2)), + Text('Dreamjob Indonesia', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, color: Color(0xff010101), height: 2)), + Text('Dreamjob.id', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, color: Color(0xff010101), height: 2)), + Text('+62 812 3456 7890', style: style.copyWith(fontSize: 11, fontWeight: FontWeight.bold, color: Color(0xff010101), height: 2)), + ],), + ), + ],) + ), + + + + ],), + + + ), + ], + ), + ) +); + + } +} \ No newline at end of file diff --git a/lib/src/ui/settings/setting_ui_payment.dart b/lib/src/ui/settings/setting_ui_payment.dart new file mode 100644 index 0000000..5aae15d --- /dev/null +++ b/lib/src/ui/settings/setting_ui_payment.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:space/src/ui/settings/setting_payment_method.dart'; + +void main() { + runApp(MaterialApp( + title: 'Named Routes Demo', + initialRoute: '/', + routes: { + '/': (context) => SettingUIPayment(), + 'space/setting_payment_method': (context) => PaymentMethod(), + }, + )); +} + + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Slidable Demo', + home: SettingUIPayment(title: 'Flutter Slidable Demo'), + ); + } +} + + +class SettingUIPayment extends StatefulWidget { + const SettingUIPayment({ Key key, String title }) : super(key: key); + @override + _SettingUIPaymentState createState() => _SettingUIPaymentState(); +} + +class _SettingUIPaymentState extends State with SingleTickerProviderStateMixin { + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0); + + @override + Widget build(BuildContext context) { + return new Scaffold( + appBar: AppBar( + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context,true); + }, + icon: Icon(FeatherIcons.chevronLeft, color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Text('Settings', style: style.copyWith(color: Color(0xff2c4057), + fontSize: 14, fontWeight: FontWeight.w500,letterSpacing: 1,)), + ), + + body: Container( + padding: EdgeInsets.only(top: 20, left: 20, right: 30), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Settings', style: style.copyWith(fontWeight: FontWeight.bold, color: Color(0xff3b3b3b))), + Text('Set your payment options', style: style.copyWith(fontSize: 12, fontWeight: FontWeight.bold, color: Color(0xff3b3b3b), height: 2)), + MaterialButton( + onPressed: () { Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => new PaymentMethod())); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Payment method', style: style.copyWith(fontSize: 17, color: Color(0xff3b3b3b), height: 3)), + Image.asset('assets/icon10.png', scale: 1.6) + ],)), + Container( + height: 20, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + MaterialButton( + onPressed: (){}, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('Subscribes', style: style.copyWith(fontSize: 17, color: Color(0xff3b3b3b), height: 2)), + Image.asset('assets/icon9.png', scale: 1.6) + ],)), + Container( + height: 20, + child: Divider( + color: Color(0xffc9c8c8), + ), + ), + ], + ), + ) + + + ); + + + } + + +} \ No newline at end of file diff --git a/lib/src/ui/settings/settings_notification.dart b/lib/src/ui/settings/settings_notification.dart new file mode 100644 index 0000000..1b2e31c --- /dev/null +++ b/lib/src/ui/settings/settings_notification.dart @@ -0,0 +1,268 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; + +void main() { + runApp(MaterialApp( + initialRoute: '/', + routes: { + '/': (context) => SettingNotification(), + }, + )); +} + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + brightness: Brightness.light, + primaryColor: Colors.black, + scaffoldBackgroundColor: Colors.white, + ), + home: const SettingNotification(), +); + } +} + + +class SettingNotification extends StatefulWidget { + const SettingNotification({ Key key, String title }) : super(key: key); + @override + _SettingNotificationState createState() => _SettingNotificationState(); +} + +class _SettingNotificationState extends State with SingleTickerProviderStateMixin { + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0, color: Color(0xff3b3b3b)); + bool _value1 = false; + bool _value2 = false; + + void _onChanged1(bool value) => setState(() => _value1 = value); + void _onChanged2(bool value) => setState(() => _value2 = value); + + @override + Widget build(BuildContext context) { + + return new Scaffold( + appBar: AppBar( + leading: IconButton( + onPressed: () { + Navigator.pop(context,true); + }, + icon: Icon(FeatherIcons.chevronLeft, color: Color(0xff2c4057), size: 16)), + elevation: 1, + backgroundColor: Colors.white, + title: Text('Notification', style: style.copyWith(color: Color(0xff2c4057), + fontSize: 14, fontWeight: FontWeight.w500,letterSpacing: 1,)), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.fromLTRB(15, 25, 15, 25), + child: Column(children: [ + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.symmetric(horizontal: 15), + height: 50, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Messages', style: style.copyWith(fontSize: 22, fontWeight: FontWeight.w600)), + Text('Receive messages from job provider', style: style.copyWith(fontSize: 14, fontWeight: FontWeight.w600)), + ],), + ), + Container( + child: Column(children: [ + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Push Notification', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Email', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Text Messages', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + ],), + ), + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.symmetric(horizontal: 15), + margin: EdgeInsets.only(top:25), + height: 70, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Reminders', style: style.copyWith(fontSize: 22, fontWeight: FontWeight.w600)), + Text('Receive schedule reminders, for interview or live interview', + style: style.copyWith(fontSize: 14, fontWeight: FontWeight.w600)), + ],), + ), + Container( + child: Column(children: [ + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Push Notification', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Email', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Text Messages', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + ],), + ), + + Container( + alignment: Alignment.centerLeft, + padding: EdgeInsets.symmetric(horizontal: 15), + margin: EdgeInsets.only(top:25), + height: 70, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Promotions', style: style.copyWith(fontSize: 22, fontWeight: FontWeight.w600)), + Text('Receive coupons, promotion, surveys, updates, and inspiration from Dreamjob.', + style: style.copyWith(fontSize: 14, fontWeight: FontWeight.w600)), + ],), + ), + Container( + child: Column(children: [ + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Push Notification', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Email', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + new SwitchListTile( + activeColor: Color(0xff22c0e8), + activeTrackColor: Colors.lightBlue[100], + inactiveThumbColor: Color(0xff757575), + inactiveTrackColor: Colors.black12, + value: _value2, + onChanged: _onChanged2, + title: new Text('Text Messages', style: style.copyWith(fontSize: 18)), + ), + Container( + height: 0, + padding: EdgeInsets.symmetric(horizontal: 17), + child: Divider( + color: Color(0xffc9c8c8) + ), + ), + ],), + ), + + ],), + ), + ) + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/settings/settings_ui_invite_friends.dart b/lib/src/ui/settings/settings_ui_invite_friends.dart new file mode 100644 index 0000000..e2f0480 --- /dev/null +++ b/lib/src/ui/settings/settings_ui_invite_friends.dart @@ -0,0 +1,169 @@ +import 'package:flutter/material.dart'; +import 'package:feather_icons_flutter/feather_icons_flutter.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:flutter/services.dart'; + +void main() { + runApp(MyApp()); + + SystemChrome.setSystemUIOverlayStyle( + const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + systemNavigationBarColor: Colors.white, + systemNavigationBarDividerColor: Colors.black, + systemNavigationBarIconBrightness: Brightness.dark, + ), + ); +} + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + brightness: Brightness.light, + primaryColor: Colors.black, + scaffoldBackgroundColor: Colors.black, + ), + home: const UiInviteFriends(), +); + } +} + + +class UiInviteFriends extends StatefulWidget { + const UiInviteFriends({ Key key, String title }) : super(key: key); + @override + _UiInviteFriendsState createState() => _UiInviteFriendsState(); +} + +class _UiInviteFriendsState extends State with SingleTickerProviderStateMixin { + + TextStyle style = TextStyle(fontFamily: 'VarelaRound', fontSize: 20.0, color: Colors.white); + + @override + Widget build(BuildContext context) { + +return Container( + decoration: new BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/vector-5.png'), + fit: BoxFit.cover + ) + ), + + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + title: Text('Invite Friends', style: style.copyWith(color: Colors.white, fontSize: 14, letterSpacing: 1)), + automaticallyImplyLeading: true, + leading: IconButton( + onPressed: () { + Navigator.pop(context,true); + }, + icon: Icon(FeatherIcons.chevronLeft, color: Colors.white, size: 16)), + elevation: 0, + backgroundColor: Colors.transparent, + ), + body: LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Container( + height: MediaQuery.of(context).size.height, + child: Stack( + alignment: AlignmentDirectional.bottomEnd, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 20, left: 30, right: 30), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Invite Friends', style: style.copyWith(fontSize: 25, fontWeight: FontWeight.bold)), + Text('Invite your friends to join Dreamjob', style: style.copyWith(fontSize: 16, height: 2)), + ],), + ), + + Container( + margin: EdgeInsets.only(top: 60), + padding: EdgeInsets.symmetric(horizontal: 50), + child: Column( + children: [ + Text('Invite your friends to make dreams come true', textAlign: TextAlign.center, style: style.copyWith(fontSize: 22, fontWeight: FontWeight.bold)), + ],), + ), + + Center( + child: Container( + width: 300, + padding: EdgeInsets.only(top: 50), + + child: RaisedButton( + padding: EdgeInsets.only(top: 15, bottom: 15, right: 40, left: 50), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), + onPressed: (){}, + color: Color(0xff2d67a5), + child: Row(children: [ Icon(FontAwesomeIcons.facebookF, color: Colors.white, size: 30), + Text(' Share on Facebook', style: style.copyWith(color: Colors.white, fontSize: 16)), + ],), + + ), + ), + ), + SizedBox( + height: 20 + ), + Center( + child: Container( + width: 300, + child: RaisedButton( + padding: EdgeInsets.only(top: 18, bottom: 18, right: 40, left: 50), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), + onPressed: (){}, + color: Colors.white, + child: Row(children: [ + Icon(FeatherIcons.link, color: Color(0xff22c0e8), size: 25), + Text(' Share Invitation Link', style: style.copyWith(color: Color(0xff22c0e8), fontSize: 16)), + ],), + + ), + ), + ), + ],), + Container( + height: 150, + width: MediaQuery.of(context).size.width, + child: Stack( + alignment: Alignment(-0.7, 0.3), + children: [ + Image.asset('assets/vector-8.png', scale: 5,) + ], + ), + ), + Image.asset('assets/vector-10.png'), + Container( + height: 300, + width: MediaQuery.of(context).size.width, + child: Stack( + alignment: Alignment(0.9, 0.8), + children: [ + Image.asset('assets/vector-9.png', scale: 5) + ], + ), + ), + ], + ), + + + + ); + } + ), + ), + + ); + } +} \ No newline at end of file diff --git a/lib/src/ui/theme/colors.dart b/lib/src/ui/theme/colors.dart new file mode 100644 index 0000000..ce893cb --- /dev/null +++ b/lib/src/ui/theme/colors.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + +class BrandColors { + static Color get yellow => const Color(0xffffb732); + + static Color get white => const Color(0xffffffff); + + static Color get blue => const Color(0xff22c0e8); + + static Color get green => const Color(0xff65be3e); + + static Color get black => const Color(0xff3b3b3b); +} + +final colorScheme = ColorScheme( + brightness: Brightness.dark, + + primary: BrandColors.white, + primaryVariant: BrandColors.blue, + onPrimary: Colors.yellow[700], + + secondary: BrandColors.black, + secondaryVariant: BrandColors.green, + onSecondary: Colors.black87, + + background: BrandColors.white, + onBackground: Colors.black, + + surface: BrandColors.white, + onSurface: Colors.black, + + error: Colors.redAccent, + onError: Colors.black87, +); + +/*class BrandedColorScheme extends ColorScheme { + @override + Color get primary => BrandColors.yellow; + + @override + Color get onPrimary => Colors.white; + + @override + Color get secondary => BrandColors.bitterSweet; + + @override + Color get onSecondary => Colors.black87; + + @override + Color get background => BrandColors.yellow; + + @override + Color get onBackground => Colors.white; + + @override + Color get surface => BrandColors.yellow; + + @override + Color get onSurface => Colors.white; + + @override + Color get error => Colors.redAccent; + + @override + Color get onError => Colors.black87; +}*/ diff --git a/lib/src/ui/theme/theme.dart b/lib/src/ui/theme/theme.dart new file mode 100644 index 0000000..b4173b3 --- /dev/null +++ b/lib/src/ui/theme/theme.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; + +import 'package:space/src/ui/theme/colors.dart'; + +ThemeData buildTheme() { + final base = ThemeData.light(); + + return base.copyWith( + colorScheme: colorScheme, + primaryColor: colorScheme.primary, + primaryColorDark: colorScheme.primaryVariant, + accentColor: colorScheme.secondary, + scaffoldBackgroundColor: colorScheme.background, + cardColor: colorScheme.surface, + canvasColor: colorScheme.surface, + primaryIconTheme: _buildIconTheme( + base.accentIconTheme, + color: colorScheme.secondary, + ), + textTheme: _buildTextTheme(base.textTheme), + primaryTextTheme: _buildTextTheme(base.primaryTextTheme), + accentTextTheme: _buildTextTheme(base.accentTextTheme), + snackBarTheme: base.snackBarTheme.copyWith( + behavior: SnackBarBehavior.floating, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + ); +} + +IconThemeData _buildIconTheme( + IconThemeData base, { + Color color, + double opacity, + double size, +}) => + base.copyWith( + color: color, + opacity: opacity, + size: size, + ); + +TextTheme _buildTextTheme(TextTheme base) { + return base.copyWith( + headline: base.headline.copyWith( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 14, + ), + title: base.title.copyWith( + fontFamily: 'VarelaRound', + color: Color(0xff3b3b3b), + fontSize: 11, + ), + button: base.button.copyWith( + fontFamily: 'VarelaRound', + fontSize: 12, + ), + ); +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..29db568 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,476 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.10" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.2" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + bloc: + dependency: transitive + description: + name: bloc + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.4" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + carousel_slider: + dependency: "direct main" + description: + name: carousel_slider + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + cookie_jar: + dependency: transitive + description: + name: cookie_jar + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + devicelocale: + dependency: transitive + description: + name: devicelocale + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1" + dio: + dependency: "direct main" + description: + name: dio + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" + dropdown_formfield: + dependency: "direct main" + description: + name: dropdown_formfield + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1" + equatable: + dependency: "direct main" + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.0" + feather_icons_flutter: + dependency: "direct main" + description: + name: feather_icons_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "4.7.4" + flare_dart: + dependency: transitive + description: + name: flare_dart + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" + flare_flutter: + dependency: "direct main" + description: + name: flare_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + url: "https://pub.dartlang.org" + source: hosted + version: "0.20.1" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + flutter_money_formatter: + dependency: "direct main" + description: + name: flutter_money_formatter + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.3" + flutter_screenutil: + dependency: "direct main" + description: + name: flutter_screenutil + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.0" + flutter_slidable: + dependency: "direct main" + description: + name: flutter_slidable + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.4" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + font_awesome_flutter: + dependency: "direct main" + description: + name: font_awesome_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "8.5.0" + giffy_dialog: + dependency: "direct main" + description: + name: giffy_dialog + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.0+2" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.15.8" + line_icons: + dependency: "direct main" + description: + name: line_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + location: + dependency: "direct main" + description: + name: location + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.5" + markdown: + dependency: transitive + description: + name: markdown + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + mask_shifter: + dependency: "direct main" + description: + name: mask_shifter + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.5" + material_design_icons_flutter: + dependency: "direct main" + description: + name: material_design_icons_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.4495" + meta: + dependency: "direct main" + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.7" + morpheus: + dependency: "direct main" + description: + name: morpheus + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.2+1" + outline_material_icons: + dependency: "direct main" + description: + name: outline_material_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" + package_info: + dependency: transitive + description: + name: package_info + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.0+6" + parse_server_sdk: + dependency: "direct main" + description: + name: parse_server_sdk + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.24" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.4" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0+1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.22.3" + sembast: + dependency: transitive + description: + name: sembast + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.3+4" + 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.5.5" + sqflite: + dependency: "direct main" + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.7+1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0+1" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.5" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "3.5.0" + xxtea: + dependency: transitive + description: + name: xxtea + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" +sdks: + dart: ">=2.5.0 <3.0.0" + flutter: ">=1.9.1 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..75d9024 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,162 @@ +name: space +description: A new Flutter application. +version: 1.0.0+1 + +environment: + sdk: ">=2.2.2 <3.0.0" + +dependencies: + + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + flare_flutter: ^1.3.3 + giffy_dialog: ^1.3.0 + dropdown_formfield: ^0.1.0 + flutter_screenutil: ^0.6.0 + carousel_slider: ^1.3.0 + feather_icons_flutter: ^4.7.4 + flutter_slidable: ^0.5.3 + font_awesome_flutter: ^8.5.0 + line_icons: ^0.2.0 + http: ^0.12.0+2 + provider: ^3.0.0 + intl: ^0.15.8 + material_design_icons_flutter: ^3.2.4096 + outline_material_icons: ^0.1.0 + flutter_money_formatter: ^0.8.3 + morpheus: ^1.2.2+1 + location: ^2.3.5 + shared_preferences: ^0.5.3 + flutter_markdown: ^0.2.0 + parse_server_sdk: ^1.0.24 + sqflite: ^1.1.6+3 + flutter_bloc: ^0.20.1 + equatable: ^0.4.0 + meta: ^1.1.6 + dio: ^2.1.0 + mask_shifter: ^0.1.0 + +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 + + assets: + - assets/logo.png + - assets/space_demo.flr + - assets/job.png + - assets/job2.png + - assets/mekuru.png + - assets/blog.png + - assets/home.png + - assets/img_profil.png + - assets/img_profil_2.png + - assets/img_profil_3.png + - assets/img_profil_4.png + - assets/recent_job.png + - assets/nav_astro.png + - assets/mekuru_2.png + - assets/ketapang.png + - assets/background-1.png + - assets/vector-1.png + - assets/vector-2.png + - assets/img_profile-1.png + - assets/img_profile-2.png + - assets/logo_vertical.png + - assets/vector-3.png + - assets/ellipse_1.png + - assets/ellipse_2.png + - assets/icon1.png + - assets/icon2.png + - assets/icon3.png + - assets/icon4.png + - assets/icon5.png + - assets/icon6.png + - assets/icon7.png + - assets/icon8.png + - assets/icon9.png + - assets/icon10.png + - assets/icon11.png + - assets/icon12.png + - assets/icon13.png + - assets/icon14.png + - assets/icon15.png + - assets/icon16.png + - assets/vector-4.png + - assets/vector-5.png + - assets/vector-6.png + - assets/vector-7.png + - assets/vector-8.png + - assets/vector-9.png + - assets/vector-10.png + - assets/vector-11.png + - assets/vector-12.png + - assets/vector-13.png + - assets/vector-14.png + - assets/vector-15.png + - assets/vector-16.png + - assets/grunge.png + - assets/background-2.png + - assets/up2u.png + - assets/logo-hitam.png + - assets/gmail.png + # 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: VarelaRound + fonts: + - asset: fonts/VarelaRound.ttf + - family: Quicksand-Regular + fonts: + - asset: fonts/Quicksand-Regular.ttf + - asset: fonts/Quicksand-Bold.ttf + - asset: fonts/Quicksand-SemiBold.ttf + - family: Cocogoose + fonts: + - asset: fonts/Cocogoose.ttf + - family: TitilliumWeb + fonts: + - asset: fonts/TitilliumWeb-Regular.ttf + # 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