├── .gitignore ├── .metadata ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── flutter_web_portfolio │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── config │ ├── colors.dart │ ├── constants.dart │ ├── styles.dart │ └── themes.dart ├── data │ ├── projects.dart │ └── skills.dart ├── main.dart ├── ui │ ├── about.dart │ ├── contact_us.dart │ ├── footer.dart │ ├── header.dart │ ├── home.dart │ ├── icon.dart │ ├── my_projects.dart │ ├── responsive_widget.dart │ ├── statistics.dart │ └── working_process.dart └── utils │ └── extensions.dart ├── pubspec.yaml ├── screenshots ├── desktop-screenshot.png ├── mobile-screenshot.png └── screenshot.png ├── test └── widget_test.dart └── web ├── assets ├── FontManifest.json ├── fonts │ └── MaterialIcons-Regular.ttf ├── icons │ ├── briefcase.png │ ├── call.png │ ├── coding.png │ ├── coffee.png │ ├── design.png │ ├── double-up-arrow.png │ ├── email.png │ ├── facebook.png │ ├── github.png │ ├── happy.png │ ├── linkedin.png │ ├── list.png │ ├── menu.png │ ├── pencil.png │ ├── pin.png │ └── twitter.png └── images │ ├── background.jpg │ ├── cover.jpg │ ├── icon.jpg │ ├── ouahid.png │ └── projects │ ├── juda.png │ ├── nataloe.png │ ├── omran.png │ ├── topfood.png │ └── toptaxi.png ├── favicon.png ├── icons ├── Icon-192.png └── Icon-512.png ├── index.html └── manifest.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | pubspec.lock 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | 45 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: d408d302e22179d598f467e11da5dd968dbdc9ec 8 | channel: beta 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flutter Web Portfolio 2 | 3 | My responsive portfolio using Flutter web. 4 | 5 | 6 | 7 | # Desktop 8 | 9 | 10 | # Mobile 11 | 12 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 29 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.flutter_web_portfolio" 42 | minSdkVersion 16 43 | targetSdkVersion 29 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/flutter_web_portfolio/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.flutter_web_portfolio 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | android.enableR8=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | FRAMEWORK_SEARCH_PATHS = ( 293 | "$(inherited)", 294 | "$(PROJECT_DIR)/Flutter", 295 | ); 296 | INFOPLIST_FILE = Runner/Info.plist; 297 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 298 | LIBRARY_SEARCH_PATHS = ( 299 | "$(inherited)", 300 | "$(PROJECT_DIR)/Flutter", 301 | ); 302 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebPortfolio; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 305 | SWIFT_VERSION = 5.0; 306 | VERSIONING_SYSTEM = "apple-generic"; 307 | }; 308 | name = Profile; 309 | }; 310 | 97C147031CF9000F007C117D /* Debug */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 316 | CLANG_CXX_LIBRARY = "libc++"; 317 | CLANG_ENABLE_MODULES = YES; 318 | CLANG_ENABLE_OBJC_ARC = YES; 319 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 320 | CLANG_WARN_BOOL_CONVERSION = YES; 321 | CLANG_WARN_COMMA = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INFINITE_RECURSION = YES; 328 | CLANG_WARN_INT_CONVERSION = YES; 329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_STRICT_PROTOTYPES = YES; 335 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 336 | CLANG_WARN_UNREACHABLE_CODE = YES; 337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 339 | COPY_PHASE_STRIP = NO; 340 | DEBUG_INFORMATION_FORMAT = dwarf; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | ENABLE_TESTABILITY = YES; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_DYNAMIC_NO_PIC = NO; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_OPTIMIZATION_LEVEL = 0; 347 | GCC_PREPROCESSOR_DEFINITIONS = ( 348 | "DEBUG=1", 349 | "$(inherited)", 350 | ); 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 358 | MTL_ENABLE_DEBUG_INFO = YES; 359 | ONLY_ACTIVE_ARCH = YES; 360 | SDKROOT = iphoneos; 361 | TARGETED_DEVICE_FAMILY = "1,2"; 362 | }; 363 | name = Debug; 364 | }; 365 | 97C147041CF9000F007C117D /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | ALWAYS_SEARCH_USER_PATHS = NO; 369 | CLANG_ANALYZER_NONNULL = YES; 370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 371 | CLANG_CXX_LIBRARY = "libc++"; 372 | CLANG_ENABLE_MODULES = YES; 373 | CLANG_ENABLE_OBJC_ARC = YES; 374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_COMMA = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_EMPTY_BODY = YES; 381 | CLANG_WARN_ENUM_CONVERSION = YES; 382 | CLANG_WARN_INFINITE_RECURSION = YES; 383 | CLANG_WARN_INT_CONVERSION = YES; 384 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 385 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 386 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 389 | CLANG_WARN_STRICT_PROTOTYPES = YES; 390 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 391 | CLANG_WARN_UNREACHABLE_CODE = YES; 392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 393 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 394 | COPY_PHASE_STRIP = NO; 395 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 396 | ENABLE_NS_ASSERTIONS = NO; 397 | ENABLE_STRICT_OBJC_MSGSEND = YES; 398 | GCC_C_LANGUAGE_STANDARD = gnu99; 399 | GCC_NO_COMMON_BLOCKS = YES; 400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 402 | GCC_WARN_UNDECLARED_SELECTOR = YES; 403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 404 | GCC_WARN_UNUSED_FUNCTION = YES; 405 | GCC_WARN_UNUSED_VARIABLE = YES; 406 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 407 | MTL_ENABLE_DEBUG_INFO = NO; 408 | SDKROOT = iphoneos; 409 | SUPPORTED_PLATFORMS = iphoneos; 410 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 411 | TARGETED_DEVICE_FAMILY = "1,2"; 412 | VALIDATE_PRODUCT = YES; 413 | }; 414 | name = Release; 415 | }; 416 | 97C147061CF9000F007C117D /* Debug */ = { 417 | isa = XCBuildConfiguration; 418 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 419 | buildSettings = { 420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 421 | CLANG_ENABLE_MODULES = YES; 422 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 423 | ENABLE_BITCODE = NO; 424 | FRAMEWORK_SEARCH_PATHS = ( 425 | "$(inherited)", 426 | "$(PROJECT_DIR)/Flutter", 427 | ); 428 | INFOPLIST_FILE = Runner/Info.plist; 429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 430 | LIBRARY_SEARCH_PATHS = ( 431 | "$(inherited)", 432 | "$(PROJECT_DIR)/Flutter", 433 | ); 434 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebPortfolio; 435 | PRODUCT_NAME = "$(TARGET_NAME)"; 436 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 437 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 438 | SWIFT_VERSION = 5.0; 439 | VERSIONING_SYSTEM = "apple-generic"; 440 | }; 441 | name = Debug; 442 | }; 443 | 97C147071CF9000F007C117D /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | CLANG_ENABLE_MODULES = YES; 449 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 450 | ENABLE_BITCODE = NO; 451 | FRAMEWORK_SEARCH_PATHS = ( 452 | "$(inherited)", 453 | "$(PROJECT_DIR)/Flutter", 454 | ); 455 | INFOPLIST_FILE = Runner/Info.plist; 456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 457 | LIBRARY_SEARCH_PATHS = ( 458 | "$(inherited)", 459 | "$(PROJECT_DIR)/Flutter", 460 | ); 461 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebPortfolio; 462 | PRODUCT_NAME = "$(TARGET_NAME)"; 463 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 464 | SWIFT_VERSION = 5.0; 465 | VERSIONING_SYSTEM = "apple-generic"; 466 | }; 467 | name = Release; 468 | }; 469 | /* End XCBuildConfiguration section */ 470 | 471 | /* Begin XCConfigurationList section */ 472 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | 97C147031CF9000F007C117D /* Debug */, 476 | 97C147041CF9000F007C117D /* Release */, 477 | 249021D3217E4FDB00AE95B9 /* Profile */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 483 | isa = XCConfigurationList; 484 | buildConfigurations = ( 485 | 97C147061CF9000F007C117D /* Debug */, 486 | 97C147071CF9000F007C117D /* Release */, 487 | 249021D4217E4FDB00AE95B9 /* Profile */, 488 | ); 489 | defaultConfigurationIsVisible = 0; 490 | defaultConfigurationName = Release; 491 | }; 492 | /* End XCConfigurationList section */ 493 | }; 494 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 495 | } 496 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_web_portfolio 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/config/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | mixin AppColors { 4 | static final yellow = Colors.yellow[800]; 5 | 6 | static final black = Colors.black87; 7 | 8 | static final greyLight = Colors.grey[100]; 9 | } 10 | -------------------------------------------------------------------------------- /lib/config/constants.dart: -------------------------------------------------------------------------------- 1 | mixin AppConstants { 2 | static final String mail = 'abdeluached@gmail.com'; 3 | 4 | static final String phone = '(+213) 06 xx xx xx xx'; 5 | 6 | static final String location = 'Touggourt, Ouargla, Algeria'; 7 | 8 | static final String github = 'https://github.com/GeekAbdelouahed'; 9 | 10 | static final String linkedin = 11 | 'https://www.linkedin.com/in/abdelouahed-medjoudja'; 12 | 13 | static final String twitter = 'https://twitter.com/MedAbdelouahed'; 14 | 15 | static final String facebook = 16 | 'https://www.facebook.com/AbdelouahedMedjoudja'; 17 | 18 | static final String cv = 'YOUR-CV-URL'; // TODO 19 | } 20 | -------------------------------------------------------------------------------- /lib/config/styles.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'colors.dart'; 4 | 5 | mixin AppStyles { 6 | static final TextStyle title = TextStyle( 7 | color: AppColors.black.withOpacity(.8), 8 | fontSize: 35, 9 | fontWeight: FontWeight.w700, 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /lib/config/themes.dart: -------------------------------------------------------------------------------- 1 | mixin AppThemes {} 2 | -------------------------------------------------------------------------------- /lib/data/projects.dart: -------------------------------------------------------------------------------- 1 | class Project { 2 | final String? name; 3 | final String? description; 4 | final String? image; 5 | final String? url; 6 | final List? skills; 7 | 8 | Project({this.name, this.description, this.image, this.url, this.skills}); 9 | } 10 | 11 | // ignore: non_constant_identifier_names 12 | List PROJECTS = [ 13 | Project( 14 | name: 'Omran', 15 | description: 16 | 'Developing a strategic plan that can lead the Muslim Ummah towards global competitiveness and can direct the efforts of qualified and skilled youth towards optimal utilization of planning and institutional tools to contribute to the renaissance of their communities and homeland countries.', 17 | image: 'images/projects/omran.png', 18 | url: 'https://play.google.com/store/apps/details?id=org.omran.android', 19 | skills: [ 20 | 'Dart', 21 | 'Java', 22 | 'Php', 23 | 'Sql', 24 | 'Flutter', 25 | 'OneSignal', 26 | 'Git', 27 | ], 28 | ), 29 | Project( 30 | name: 'Topfood', 31 | description: 'Food delivery app', 32 | image: 'images/projects/topfood.png', 33 | url: 34 | 'https://play.google.com/store/apps/details?id=dz.topfood.top_food_client', 35 | skills: [ 36 | 'Dart', 37 | 'Flutter', 38 | 'Git', 39 | ], 40 | ), 41 | Project( 42 | name: 'Toptaxi', 43 | description: 44 | 'Toptaxi is a third party transportation service, which is intended to provide cars to its customers through a smart application whenever they request. The use of this application is free', 45 | image: 'images/projects/toptaxi.png', 46 | url: 'https://play.google.com/store/apps/details?id=toptaxi.dz', 47 | skills: [ 48 | 'Java', 49 | 'Php', 50 | 'JavaScript', 51 | 'Html', 52 | 'Css', 53 | 'Sql', 54 | 'Firebase', 55 | 'Laravel', 56 | 'OneSignal', 57 | 'Git', 58 | ], 59 | ), 60 | Project( 61 | name: 'Nataloe', 62 | description: 63 | 'nataloe شركة جزائرية - إسبانية متخصصة بانتاج مستحضرات شبه صيدلانية للعناية اليومية بالبشرة اعتمادا على خلاصتي الألوفيرا والحلزون والزيوت الأساسية', 64 | image: 'images/projects/nataloe.png', 65 | url: 'https://play.google.com/store/apps/details?id=com.nataloe', 66 | skills: [ 67 | 'Kotlin', 68 | 'Php', 69 | 'JavaScript', 70 | 'Html', 71 | 'Css', 72 | 'Sql', 73 | 'Firebase', 74 | 'Laravel', 75 | 'Git', 76 | ], 77 | ), 78 | Project( 79 | name: 'جداء', 80 | description: 81 | 'يعتبر تعليم الطفل جدول الضرب من أصعب الأمور بالنسبة للأولياء وممل بالنسبة لطفل، لكن مع التطور التكنولوجي وحب الاطفال للتكنولوجيا أصبح ذلك من أيسر المهام على الأولياء والطفل على حد سواء ؛ تطبيق جداء يعتبر الحل الامثل لتعلم جدول الضرب خطوة بخطوة بطريقة سهلة وممتعة مع أصوات خاصة بالإجابة الصحيحة أوالخاطئة، أيضا التطبيق يعطيك تقييما لمستواك خلال التعلم تقييم لكل الجداول معا وتقييم خاص لكل جدول كما يمكنك التطبيق من إجراء إمتحان مباشر لتحديد المستوى ويقوم بحفظ كل نتائجك مع التقييم والتاريخ وبالتالي يمكنك الرجوع لها في أي وقت للإطلاع عليها وملاحظة مراحل تطورك مع الوقت.', 82 | image: 'images/projects/juda.png', 83 | url: 'https://play.google.com/store/apps/details?id=com.ouahiddev.juda', 84 | skills: [ 85 | 'Java', 86 | 'Sql', 87 | 'Git', 88 | ], 89 | ), 90 | ]; 91 | -------------------------------------------------------------------------------- /lib/data/skills.dart: -------------------------------------------------------------------------------- 1 | class Skill { 2 | final String? name; 3 | 4 | Skill({this.name}); 5 | } 6 | 7 | // ignore: non_constant_identifier_names 8 | List SKILLS = [ 9 | Skill(name: 'Java'), 10 | Skill(name: 'Kotlin'), 11 | Skill(name: 'Dart'), 12 | Skill(name: 'Php'), 13 | Skill(name: 'Java Script'), 14 | Skill(name: 'Flutter'), 15 | Skill(name: 'NodeJs'), 16 | Skill(name: 'Laravel'), 17 | Skill(name: 'Git'), 18 | ]; 19 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'ui/home.dart'; 4 | import 'config/colors.dart'; 5 | 6 | void main() { 7 | runApp(MyApp()); 8 | } 9 | 10 | class MyApp extends StatelessWidget { 11 | @override 12 | Widget build(BuildContext context) { 13 | return MaterialApp( 14 | title: 'OuahidDev', 15 | debugShowCheckedModeBanner: false, 16 | theme: ThemeData( 17 | accentColor: AppColors.yellow, 18 | visualDensity: VisualDensity.adaptivePlatformDensity, 19 | ), 20 | home: Home(), 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/ui/about.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:url_launcher/url_launcher.dart'; 3 | 4 | import 'responsive_widget.dart'; 5 | import '../data/skills.dart'; 6 | import '../config/constants.dart'; 7 | import '../config/styles.dart'; 8 | import '../config/colors.dart'; 9 | 10 | class About extends StatelessWidget { 11 | final String _avatar = 'images/ouahid.png'; 12 | final String _description = 13 | "I am developer has around 4 years experience developing mobile and web applications, using different languages and techniques."; 14 | 15 | @override 16 | Widget build(BuildContext context) => ResponsiveWidget( 17 | desktopScreen: Container( 18 | color: Colors.white, 19 | padding: EdgeInsets.symmetric( 20 | horizontal: MediaQuery.of(context).size.width * .15, 21 | vertical: 100, 22 | ), 23 | child: Column( 24 | children: [ 25 | Row( 26 | children: [ 27 | ClipRRect( 28 | borderRadius: BorderRadius.circular(1000), 29 | child: Container( 30 | color: AppColors.greyLight, 31 | child: Image.asset( 32 | _avatar, 33 | width: 300, 34 | height: 300, 35 | fit: BoxFit.cover, 36 | ), 37 | ), 38 | ), 39 | const SizedBox(width: 20), 40 | Expanded( 41 | child: Column( 42 | crossAxisAlignment: CrossAxisAlignment.start, 43 | children: [ 44 | Text( 45 | 'ABOUT ME', 46 | style: TextStyle( 47 | color: AppColors.yellow, 48 | fontSize: 40, 49 | fontWeight: FontWeight.bold, 50 | ), 51 | ), 52 | Text( 53 | _description, 54 | style: Theme.of(context).textTheme.bodyText2!.copyWith( 55 | color: Colors.black.withOpacity(.7), 56 | fontSize: 17, 57 | ), 58 | ), 59 | const SizedBox(height: 30), 60 | Row( 61 | children: [ 62 | RaisedButton( 63 | onPressed: () {}, 64 | color: AppColors.yellow, 65 | textColor: Colors.white, 66 | padding: const EdgeInsets.symmetric( 67 | horizontal: 30, vertical: 20), 68 | child: Text('HIRE ME NOW'), 69 | ), 70 | const SizedBox(width: 20), 71 | RaisedButton( 72 | onPressed: _downloadCV, 73 | color: AppColors.black, 74 | textColor: Colors.white, 75 | padding: const EdgeInsets.symmetric( 76 | horizontal: 30, vertical: 20), 77 | child: Text('VIEW RESUME'), 78 | ), 79 | ], 80 | ), 81 | ], 82 | ), 83 | ), 84 | ], 85 | ), 86 | const SizedBox(height: 100), 87 | Text('MY SKILLS', style: AppStyles.title), 88 | Container(width: 100, height: 2, color: AppColors.yellow), 89 | const SizedBox(height: 3), 90 | Container(width: 75, height: 2, color: AppColors.yellow), 91 | const SizedBox(height: 50), 92 | Wrap( 93 | spacing: 25, 94 | runSpacing: 25, 95 | runAlignment: WrapAlignment.spaceBetween, 96 | children: SKILLS.map(_buildSkill).toList(), 97 | ), 98 | ], 99 | ), 100 | ), 101 | mobileScreen: Container( 102 | color: Colors.white, 103 | padding: EdgeInsets.symmetric( 104 | horizontal: MediaQuery.of(context).size.width * .15, 105 | vertical: 50, 106 | ), 107 | child: Column( 108 | children: [ 109 | ClipRRect( 110 | borderRadius: BorderRadius.circular(1000), 111 | child: Container( 112 | color: AppColors.greyLight, 113 | child: Image.asset( 114 | _avatar, 115 | width: 150, 116 | height: 150, 117 | fit: BoxFit.cover, 118 | ), 119 | ), 120 | ), 121 | const SizedBox(height: 20), 122 | Text( 123 | 'ABOUT ME', 124 | style: TextStyle( 125 | color: AppColors.yellow, 126 | fontSize: 20, 127 | fontWeight: FontWeight.bold, 128 | ), 129 | ), 130 | Text( 131 | _description, 132 | style: Theme.of(context).textTheme.bodyText2!.copyWith( 133 | color: Colors.black.withOpacity(.7), 134 | fontSize: 13, 135 | ), 136 | textAlign: TextAlign.center, 137 | ), 138 | const SizedBox(height: 30), 139 | RaisedButton( 140 | onPressed: () {}, 141 | color: AppColors.yellow, 142 | textColor: Colors.white, 143 | padding: 144 | const EdgeInsets.symmetric(horizontal: 30, vertical: 20), 145 | child: Text('HIRE ME NOW'), 146 | ), 147 | const SizedBox(height: 20), 148 | RaisedButton( 149 | onPressed: _downloadCV, 150 | color: AppColors.black, 151 | textColor: Colors.white, 152 | padding: 153 | const EdgeInsets.symmetric(horizontal: 30, vertical: 20), 154 | child: Text('VIEW RESUME'), 155 | ), 156 | const SizedBox(height: 50), 157 | Text('MY SKILLS', style: AppStyles.title), 158 | Container(width: 75, height: 2, color: AppColors.yellow), 159 | const SizedBox(height: 3), 160 | Container(width: 50, height: 2, color: AppColors.yellow), 161 | const SizedBox(height: 25), 162 | Wrap( 163 | spacing: 10, 164 | runSpacing: 10, 165 | alignment: WrapAlignment.center, 166 | runAlignment: WrapAlignment.spaceBetween, 167 | children: SKILLS.map(_buildSkill).toList(), 168 | ), 169 | ], 170 | ), 171 | ), 172 | ); 173 | 174 | void _downloadCV() { 175 | launch(AppConstants.cv); 176 | } 177 | 178 | Widget _buildSkill(Skill skill) => Chip(label: Text(skill.name!)); 179 | } 180 | -------------------------------------------------------------------------------- /lib/ui/contact_us.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_web_portfolio/ui/icon.dart'; 5 | import 'package:mailto/mailto.dart'; 6 | 7 | import 'responsive_widget.dart'; 8 | import '../config/constants.dart'; 9 | import '../config/styles.dart'; 10 | import '../config/colors.dart'; 11 | import '../utils/extensions.dart'; 12 | 13 | class ContactUs extends StatefulWidget { 14 | @override 15 | _ContactUsState createState() => _ContactUsState(); 16 | } 17 | 18 | class _ContactUsState extends State { 19 | final _formKey = GlobalKey(); 20 | 21 | final _nameController = TextEditingController(), 22 | _emailController = TextEditingController(), 23 | _contentController = TextEditingController(); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return ResponsiveWidget( 28 | desktopScreen: Container( 29 | color: Colors.white, 30 | padding: EdgeInsets.symmetric( 31 | horizontal: MediaQuery.of(context).size.width * .15, 32 | vertical: 100, 33 | ), 34 | child: Column( 35 | children: [ 36 | Text('GET IN TOUCH', style: AppStyles.title), 37 | Container(width: 100, height: 2, color: AppColors.yellow), 38 | const SizedBox(height: 3), 39 | Container(width: 75, height: 2, color: AppColors.yellow), 40 | const SizedBox(height: 50), 41 | Row( 42 | crossAxisAlignment: CrossAxisAlignment.start, 43 | children: [ 44 | Expanded( 45 | child: Column( 46 | crossAxisAlignment: CrossAxisAlignment.start, 47 | children: [ 48 | _buildContactInfo( 49 | 'icons/email.png', 50 | 'Mail Us:', 51 | AppConstants.mail, 52 | ), 53 | const SizedBox(height: 20), 54 | _buildContactInfo( 55 | 'icons/call.png', 56 | 'Call Us:', 57 | AppConstants.phone, 58 | ), 59 | const SizedBox(height: 20), 60 | _buildContactInfo( 61 | 'icons/pin.png', 62 | 'Visit Us:', 63 | AppConstants.location, 64 | ), 65 | ], 66 | ), 67 | ), 68 | Expanded( 69 | child: _buildContactForm(context), 70 | ), 71 | ], 72 | ) 73 | ], 74 | ), 75 | ), 76 | mobileScreen: Container( 77 | color: Colors.white, 78 | padding: EdgeInsets.symmetric( 79 | horizontal: MediaQuery.of(context).size.width * .15, 80 | vertical: 100, 81 | ), 82 | child: Column( 83 | children: [ 84 | Text( 85 | 'GET IN TOUCH', 86 | style: AppStyles.title, 87 | textAlign: TextAlign.center, 88 | ), 89 | Container(width: 75, height: 2, color: AppColors.yellow), 90 | const SizedBox(height: 3), 91 | Container(width: 50, height: 2, color: AppColors.yellow), 92 | const SizedBox(height: 50), 93 | Column( 94 | children: [ 95 | Column( 96 | crossAxisAlignment: CrossAxisAlignment.start, 97 | children: [ 98 | _buildContactInfo( 99 | 'icons/email.png', 100 | 'Mail Us:', 101 | AppConstants.mail, 102 | ), 103 | const SizedBox(height: 20), 104 | _buildContactInfo( 105 | 'icons/call.png', 106 | 'Call Us:', 107 | AppConstants.phone, 108 | ), 109 | const SizedBox(height: 20), 110 | _buildContactInfo( 111 | 'icons/pin.png', 112 | 'Visit Us:', 113 | AppConstants.location, 114 | ), 115 | ], 116 | ), 117 | const SizedBox(height: 50), 118 | _buildContactForm(context), 119 | ], 120 | ) 121 | ], 122 | ), 123 | ), 124 | ); 125 | } 126 | 127 | Widget _buildContactInfo(String imagePath, String title, String content) { 128 | return FittedBox( 129 | child: Row( 130 | crossAxisAlignment: CrossAxisAlignment.start, 131 | children: [ 132 | AppIcon(imagePath, color: AppColors.black.withOpacity(.7), size: 20), 133 | const SizedBox(width: 10), 134 | Column( 135 | crossAxisAlignment: CrossAxisAlignment.start, 136 | children: [ 137 | Text( 138 | title, 139 | style: TextStyle( 140 | color: AppColors.black, 141 | fontWeight: FontWeight.bold, 142 | ), 143 | ), 144 | const SizedBox(height: 5), 145 | Text( 146 | content, 147 | style: TextStyle(color: AppColors.black.withOpacity(.7)), 148 | ), 149 | ], 150 | ) 151 | ], 152 | ), 153 | ); 154 | } 155 | 156 | Widget _buildContactForm(BuildContext context) { 157 | return Column( 158 | crossAxisAlignment: CrossAxisAlignment.start, 159 | children: [ 160 | Text( 161 | 'Have Something To Write?', 162 | style: TextStyle( 163 | color: AppColors.black, 164 | fontSize: 20, 165 | fontWeight: FontWeight.bold, 166 | ), 167 | ), 168 | const SizedBox(height: 25), 169 | Form( 170 | key: _formKey, 171 | child: Column( 172 | crossAxisAlignment: CrossAxisAlignment.start, 173 | children: [ 174 | Row( 175 | children: [ 176 | Expanded( 177 | child: TextFormField( 178 | validator: (text) { 179 | return (text!.isValidName()) 180 | ? null 181 | : 'Please insert valid name!'; 182 | }, 183 | decoration: InputDecoration( 184 | hintText: 'Your Name', 185 | border: OutlineInputBorder(), 186 | ), 187 | ), 188 | ), 189 | const SizedBox(width: 15), 190 | Expanded( 191 | child: TextFormField( 192 | validator: (text) { 193 | return (text!.isValidEmail) 194 | ? null 195 | : 'Please insert valid email!'; 196 | }, 197 | decoration: InputDecoration( 198 | hintText: 'Your Email', 199 | border: OutlineInputBorder(), 200 | ), 201 | ), 202 | ), 203 | ], 204 | ), 205 | const SizedBox(height: 20), 206 | TextFormField( 207 | minLines: 3, 208 | maxLines: 10, 209 | validator: (text) { 210 | return (text!.isValidName(minLength: 10)) 211 | ? null 212 | : 'Please insert valid message!, at least 10 characters'; 213 | }, 214 | decoration: InputDecoration( 215 | hintText: 'Your Message', 216 | border: OutlineInputBorder(), 217 | ), 218 | ), 219 | const SizedBox(height: 20), 220 | RaisedButton( 221 | color: AppColors.yellow, 222 | textColor: Colors.white, 223 | padding: 224 | const EdgeInsets.symmetric(horizontal: 30, vertical: 20), 225 | onPressed: _sendMail, 226 | child: Text('Send'), 227 | ), 228 | ], 229 | ), 230 | ) 231 | ], 232 | ); 233 | } 234 | 235 | void _sendMail() async { 236 | bool isValidForm = _formKey.currentState!.validate(); 237 | if (!isValidForm) return; 238 | 239 | final mailto = Mailto( 240 | to: [AppConstants.mail], 241 | subject: _nameController.text.trim(), 242 | body: _contentController.text.trim(), 243 | ); 244 | 245 | final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 3000); 246 | String renderHtml(Mailto mailto) => 247 | '''mailto exampleOpen mail client'''; 248 | await for (HttpRequest request in server) { 249 | request.response 250 | ..statusCode = HttpStatus.ok 251 | ..headers.contentType = ContentType.html 252 | ..write(renderHtml(mailto)); 253 | await request.response.close(); 254 | } 255 | } 256 | 257 | @override 258 | void dispose() { 259 | _nameController.dispose(); 260 | _emailController.dispose(); 261 | _contentController.dispose(); 262 | super.dispose(); 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /lib/ui/footer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:url_launcher/url_launcher.dart'; 3 | 4 | import 'responsive_widget.dart'; 5 | import '../data/projects.dart'; 6 | import '../config/constants.dart'; 7 | import '../config/colors.dart'; 8 | import 'icon.dart'; 9 | 10 | class Footer extends StatelessWidget { 11 | final String _getInTouch = 12 | "You have an idea, I am here to turn your dream into real digital solution."; 13 | final String _description = 14 | "I am developer has around 4 years experience developing mobile and web applications, using different languages and techniques."; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return ResponsiveWidget( 19 | desktopScreen: Container( 20 | color: Colors.black, 21 | padding: EdgeInsets.symmetric( 22 | horizontal: MediaQuery.of(context).size.width * .15, 23 | vertical: 30, 24 | ), 25 | child: Column( 26 | children: [ 27 | Row( 28 | crossAxisAlignment: CrossAxisAlignment.start, 29 | children: [ 30 | // Get in touch 31 | Expanded( 32 | child: Column( 33 | crossAxisAlignment: CrossAxisAlignment.start, 34 | children: [ 35 | Row( 36 | children: [ 37 | Container( 38 | width: 2, 39 | height: 20, 40 | color: AppColors.yellow, 41 | ), 42 | const SizedBox(width: 7.5), 43 | Text( 44 | 'GET IN TOUCH', 45 | style: TextStyle( 46 | color: Colors.white, 47 | fontWeight: FontWeight.w700, 48 | ), 49 | ) 50 | ], 51 | ), 52 | const SizedBox(height: 20), 53 | Text( 54 | _getInTouch, 55 | style: TextStyle( 56 | color: AppColors.greyLight, 57 | fontSize: 13, 58 | ), 59 | ), 60 | const SizedBox(height: 20), 61 | Text( 62 | 'Email Address', 63 | style: TextStyle( 64 | color: AppColors.greyLight, 65 | fontWeight: FontWeight.w800, 66 | ), 67 | ), 68 | const SizedBox(height: 7), 69 | Text( 70 | AppConstants.mail, 71 | style: TextStyle( 72 | color: AppColors.greyLight, 73 | fontSize: 13, 74 | ), 75 | ), 76 | const SizedBox(height: 20), 77 | Text( 78 | 'Phone Number', 79 | style: TextStyle( 80 | color: AppColors.greyLight, 81 | fontWeight: FontWeight.w800, 82 | ), 83 | ), 84 | const SizedBox(height: 7), 85 | Text( 86 | AppConstants.phone, 87 | style: TextStyle( 88 | color: AppColors.greyLight, 89 | fontSize: 13, 90 | ), 91 | ), 92 | const SizedBox(height: 20), 93 | Text( 94 | 'Location', 95 | style: TextStyle( 96 | color: AppColors.greyLight, 97 | fontWeight: FontWeight.w800, 98 | ), 99 | ), 100 | const SizedBox(height: 7), 101 | Text( 102 | AppConstants.location, 103 | style: TextStyle( 104 | color: AppColors.greyLight, 105 | fontSize: 13, 106 | ), 107 | ) 108 | ], 109 | ), 110 | ), 111 | const SizedBox(width: 20), 112 | // Aout me 113 | Expanded( 114 | child: Column( 115 | crossAxisAlignment: CrossAxisAlignment.start, 116 | children: [ 117 | Row( 118 | children: [ 119 | Container( 120 | width: 2, 121 | height: 20, 122 | color: AppColors.yellow, 123 | ), 124 | const SizedBox(width: 7.5), 125 | Text( 126 | 'ABOUT ME', 127 | style: TextStyle( 128 | color: Colors.white, 129 | fontWeight: FontWeight.w700, 130 | ), 131 | ) 132 | ], 133 | ), 134 | const SizedBox(height: 20), 135 | Text( 136 | _description, 137 | style: TextStyle( 138 | color: AppColors.greyLight, 139 | fontSize: 13, 140 | ), 141 | ), 142 | ], 143 | ), 144 | ), 145 | const SizedBox(width: 20), 146 | // My projects 147 | Expanded( 148 | child: Column( 149 | crossAxisAlignment: CrossAxisAlignment.start, 150 | children: [ 151 | Row( 152 | children: [ 153 | Container( 154 | width: 2, 155 | height: 20, 156 | color: AppColors.yellow, 157 | ), 158 | const SizedBox(width: 7.5), 159 | Text( 160 | 'RECENT PROJECTS', 161 | style: TextStyle( 162 | color: Colors.white, 163 | fontWeight: FontWeight.w700, 164 | ), 165 | ) 166 | ], 167 | ), 168 | const SizedBox(height: 20), 169 | Wrap( 170 | spacing: 10, 171 | runSpacing: 10, 172 | children: PROJECTS 173 | .take(4) 174 | .map((p) => _buildProject(context, p)) 175 | .toList(), 176 | ) 177 | ], 178 | ), 179 | ), 180 | ], 181 | ), 182 | const SizedBox(height: 30), 183 | Divider( 184 | color: AppColors.greyLight!.withOpacity(.75), 185 | thickness: .5, 186 | ), 187 | const SizedBox(height: 20), 188 | Row( 189 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 190 | children: [ 191 | Text( 192 | 'Proudly powered by OuahidDev ©${DateTime.now().year}', 193 | style: TextStyle( 194 | color: AppColors.greyLight!.withOpacity(.75), 195 | ), 196 | ), 197 | Row(children: _socialMedia()), 198 | ], 199 | ) 200 | ], 201 | ), 202 | ), 203 | mobileScreen: Container( 204 | color: Colors.black, 205 | padding: EdgeInsets.symmetric( 206 | horizontal: MediaQuery.of(context).size.width * .15, 207 | vertical: 30, 208 | ), 209 | child: Column( 210 | children: [ 211 | Column( 212 | crossAxisAlignment: CrossAxisAlignment.start, 213 | children: [ 214 | Row( 215 | children: [ 216 | Container( 217 | width: 2, 218 | height: 20, 219 | color: AppColors.yellow, 220 | ), 221 | const SizedBox(width: 7.5), 222 | Text( 223 | 'GET IN TOUCH', 224 | style: TextStyle( 225 | color: Colors.white, 226 | fontWeight: FontWeight.w700, 227 | ), 228 | ) 229 | ], 230 | ), 231 | const SizedBox(height: 20), 232 | Text( 233 | _getInTouch, 234 | style: TextStyle( 235 | color: AppColors.greyLight, 236 | fontSize: 13, 237 | ), 238 | ), 239 | const SizedBox(height: 20), 240 | Text( 241 | 'Email Address', 242 | style: TextStyle( 243 | color: AppColors.greyLight, 244 | fontWeight: FontWeight.w800, 245 | ), 246 | ), 247 | const SizedBox(height: 7), 248 | Text( 249 | AppConstants.mail, 250 | style: TextStyle( 251 | color: AppColors.greyLight, 252 | fontSize: 13, 253 | ), 254 | ), 255 | const SizedBox(height: 20), 256 | Text( 257 | 'Phone Number', 258 | style: TextStyle( 259 | color: AppColors.greyLight, 260 | fontWeight: FontWeight.w800, 261 | ), 262 | ), 263 | const SizedBox(height: 7), 264 | Text( 265 | AppConstants.phone, 266 | style: TextStyle( 267 | color: AppColors.greyLight, 268 | fontSize: 13, 269 | ), 270 | ), 271 | const SizedBox(height: 20), 272 | Text( 273 | 'Location', 274 | style: TextStyle( 275 | color: AppColors.greyLight, 276 | fontWeight: FontWeight.w800, 277 | ), 278 | ), 279 | const SizedBox(height: 7), 280 | Text( 281 | AppConstants.location, 282 | style: TextStyle( 283 | color: AppColors.greyLight, 284 | fontSize: 13, 285 | ), 286 | ) 287 | ], 288 | ), 289 | const SizedBox(height: 30), 290 | // Aout me 291 | Column( 292 | crossAxisAlignment: CrossAxisAlignment.start, 293 | children: [ 294 | Row( 295 | children: [ 296 | Container( 297 | width: 2, 298 | height: 20, 299 | color: AppColors.yellow, 300 | ), 301 | const SizedBox(width: 7.5), 302 | Text( 303 | 'ABOUT ME', 304 | style: TextStyle( 305 | color: Colors.white, 306 | fontWeight: FontWeight.w700, 307 | ), 308 | ) 309 | ], 310 | ), 311 | const SizedBox(height: 20), 312 | Text( 313 | _description, 314 | style: TextStyle( 315 | color: AppColors.greyLight, 316 | fontSize: 13, 317 | ), 318 | ), 319 | ], 320 | ), 321 | const SizedBox(height: 30), 322 | // My projects 323 | Column( 324 | crossAxisAlignment: CrossAxisAlignment.start, 325 | children: [ 326 | Row( 327 | children: [ 328 | Container( 329 | width: 2, 330 | height: 20, 331 | color: AppColors.yellow, 332 | ), 333 | const SizedBox(width: 7.5), 334 | Text( 335 | 'RECENT PROJECTS', 336 | style: TextStyle( 337 | color: Colors.white, 338 | fontWeight: FontWeight.w700, 339 | ), 340 | ) 341 | ], 342 | ), 343 | const SizedBox(height: 20), 344 | Wrap( 345 | spacing: 10, 346 | runSpacing: 10, 347 | children: PROJECTS 348 | .take(4) 349 | .map((p) => _buildProject(context, p)) 350 | .toList(), 351 | ) 352 | ], 353 | ), 354 | const SizedBox(height: 30), 355 | Divider( 356 | color: AppColors.greyLight!.withOpacity(.75), 357 | thickness: .5, 358 | ), 359 | const SizedBox(height: 20), 360 | FittedBox( 361 | child: Row( 362 | mainAxisAlignment: MainAxisAlignment.center, 363 | children: _socialMedia(), 364 | ), 365 | ), 366 | const SizedBox(height: 20), 367 | Text( 368 | 'Proudly powered by OuahidDev ©${DateTime.now().year}', 369 | style: TextStyle( 370 | color: AppColors.greyLight!.withOpacity(.75), 371 | ), 372 | textAlign: TextAlign.center, 373 | ), 374 | ], 375 | ), 376 | ), 377 | ); 378 | } 379 | 380 | Widget _buildProject(BuildContext context, Project project) => InkWell( 381 | onTap: () { 382 | launch(project.url!); 383 | }, 384 | child: ResponsiveWidget( 385 | desktopScreen: Container( 386 | color: AppColors.greyLight, 387 | padding: const EdgeInsets.all(15), 388 | width: MediaQuery.of(context).size.width * .1, 389 | height: MediaQuery.of(context).size.width * .1, 390 | child: Image.asset(project.image!), 391 | ), 392 | mobileScreen: Container( 393 | color: AppColors.greyLight, 394 | padding: const EdgeInsets.all(15), 395 | width: MediaQuery.of(context).size.width * .2, 396 | height: MediaQuery.of(context).size.width * .2, 397 | child: Image.asset(project.image!), 398 | ), 399 | ), 400 | ); 401 | 402 | List _socialMedia() => [ 403 | InkWell( 404 | onTap: () async { 405 | launch(AppConstants.github); 406 | }, 407 | child: AppIcon('icons/github.png'), 408 | ), 409 | const SizedBox(width: 20), 410 | InkWell( 411 | onTap: () { 412 | launch(AppConstants.linkedin); 413 | }, 414 | child: AppIcon('icons/linkedin.png'), 415 | ), 416 | const SizedBox(width: 20), 417 | InkWell( 418 | onTap: () { 419 | launch(AppConstants.twitter); 420 | }, 421 | child: AppIcon('icons/twitter.png'), 422 | ), 423 | const SizedBox(width: 20), 424 | InkWell( 425 | onTap: () { 426 | launch(AppConstants.facebook); 427 | }, 428 | child: AppIcon('icons/facebook.png'), 429 | ), 430 | ]; 431 | } 432 | -------------------------------------------------------------------------------- /lib/ui/header.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_web_portfolio/ui/responsive_widget.dart'; 3 | import 'package:url_launcher/url_launcher.dart'; 4 | 5 | import '../config/constants.dart'; 6 | import '../config/colors.dart'; 7 | 8 | class Header extends StatelessWidget { 9 | final String _name = "Abdelouahed"; 10 | final String _job = "Mobile Developer"; 11 | final String _description = 12 | "I am developer has around 4 years experience developing mobile and web applications, using different languages and techniques."; 13 | 14 | @override 15 | Widget build(BuildContext context) => ResponsiveWidget( 16 | desktopScreen: Container( 17 | width: double.infinity, 18 | padding: EdgeInsets.symmetric( 19 | horizontal: MediaQuery.of(context).size.width * .15, 20 | ), 21 | child: Column( 22 | crossAxisAlignment: CrossAxisAlignment.start, 23 | children: [ 24 | Text( 25 | 'I’m $_name', 26 | style: TextStyle( 27 | color: Colors.white, 28 | fontSize: 40, 29 | fontWeight: FontWeight.w900, 30 | ), 31 | ), 32 | Text( 33 | _job, 34 | style: TextStyle( 35 | color: AppColors.yellow, 36 | fontSize: 40, 37 | fontWeight: FontWeight.w900, 38 | ), 39 | ), 40 | const SizedBox(height: 5), 41 | SizedBox( 42 | width: MediaQuery.of(context).size.width / 2, 43 | child: Text( 44 | _description, 45 | style: Theme.of(context).textTheme.bodyText2!.copyWith( 46 | color: Colors.grey[100], 47 | fontSize: 17, 48 | ), 49 | ), 50 | ), 51 | const SizedBox(height: 30), 52 | RaisedButton( 53 | color: AppColors.yellow, 54 | textColor: Colors.white, 55 | padding: 56 | const EdgeInsets.symmetric(horizontal: 30, vertical: 20), 57 | onPressed: _downloadCV, 58 | child: Text('Download CV'), 59 | ), 60 | const SizedBox(height: 100), 61 | ], 62 | ), 63 | ), 64 | mobileScreen: Container( 65 | width: double.infinity, 66 | padding: EdgeInsets.symmetric( 67 | horizontal: MediaQuery.of(context).size.width * .15, 68 | ), 69 | child: FittedBox( 70 | child: Column( 71 | children: [ 72 | Text( 73 | 'I’m $_name', 74 | style: TextStyle( 75 | color: Colors.white, 76 | fontSize: 30, 77 | fontWeight: FontWeight.w900, 78 | ), 79 | ), 80 | Text( 81 | _job, 82 | style: TextStyle( 83 | color: AppColors.yellow, 84 | fontSize: 30, 85 | fontWeight: FontWeight.w900, 86 | ), 87 | ), 88 | const SizedBox(height: 5), 89 | SizedBox( 90 | width: MediaQuery.of(context).size.width, 91 | child: Text( 92 | _description, 93 | style: Theme.of(context).textTheme.bodyText2!.copyWith( 94 | color: Colors.grey[100], 95 | fontSize: 15, 96 | height: 1.8, 97 | ), 98 | textAlign: TextAlign.center, 99 | ), 100 | ), 101 | const SizedBox(height: 30), 102 | RaisedButton( 103 | color: AppColors.yellow, 104 | textColor: Colors.white, 105 | padding: 106 | const EdgeInsets.symmetric(horizontal: 30, vertical: 20), 107 | onPressed: _downloadCV, 108 | child: Text('Download CV'), 109 | ), 110 | const SizedBox(height: 100), 111 | ], 112 | ), 113 | ), 114 | ), 115 | ); 116 | 117 | void _downloadCV() { 118 | launch(AppConstants.cv); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /lib/ui/home.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_web_portfolio/ui/responsive_widget.dart'; 5 | import 'package:url_launcher/url_launcher.dart'; 6 | 7 | import 'about.dart'; 8 | import 'contact_us.dart'; 9 | import 'footer.dart'; 10 | import 'header.dart'; 11 | import 'icon.dart'; 12 | import 'my_projects.dart'; 13 | import 'statistics.dart'; 14 | import 'working_process.dart'; 15 | import '../config/colors.dart'; 16 | import '../config/constants.dart'; 17 | 18 | class Home extends StatefulWidget { 19 | Home({Key? key}) : super(key: key); 20 | 21 | @override 22 | _HomeState createState() => _HomeState(); 23 | } 24 | 25 | class _HomeState extends State { 26 | final _headerGlobalKey = GlobalKey(); 27 | final _aboutGlobaleKey = GlobalKey(); 28 | final _statisticsGlobaleKey = GlobalKey(); 29 | final _workingProcessGlobaleKye = GlobalKey(); 30 | final _recentProjectsGlobaleKey = GlobalKey(); 31 | final _contactUsGlobaleKey = GlobalKey(); 32 | 33 | final _scrollController = ScrollController(); 34 | 35 | final _fabStream = StreamController(); 36 | 37 | @override 38 | void initState() { 39 | super.initState(); 40 | _scrollController.addListener(() { 41 | _fabStream.sink.add(_scrollController.offset > 500); 42 | }); 43 | } 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | return ResponsiveWidget( 48 | desktopScreen: Scaffold( 49 | body: Container( 50 | decoration: BoxDecoration( 51 | image: DecorationImage( 52 | image: AssetImage('images/background.jpg'), 53 | fit: BoxFit.cover, 54 | ), 55 | ), 56 | child: CustomScrollView( 57 | controller: _scrollController, 58 | slivers: [ 59 | SliverAppBar( 60 | key: _headerGlobalKey, 61 | titleSpacing: 0, 62 | toolbarHeight: 100, 63 | backgroundColor: Colors.transparent, 64 | flexibleSpace: Container( 65 | decoration: BoxDecoration( 66 | image: DecorationImage( 67 | image: AssetImage('images/cover.jpg'), 68 | fit: BoxFit.cover, 69 | ), 70 | ), 71 | child: Container( 72 | decoration: BoxDecoration( 73 | gradient: LinearGradient( 74 | begin: Alignment.bottomCenter, 75 | end: Alignment.topCenter, 76 | colors: [ 77 | Colors.black, 78 | Colors.black87, 79 | Colors.transparent 80 | ], 81 | ), 82 | ), 83 | ), 84 | ), 85 | title: Padding( 86 | padding: EdgeInsets.only( 87 | left: MediaQuery.of(context).size.width * .15, 88 | ), 89 | child: ClipRRect( 90 | borderRadius: BorderRadius.circular(1000), 91 | child: Container( 92 | width: 40, 93 | height: 40, 94 | color: AppColors.yellow, 95 | child: Image.asset('images/ouahid.png'), 96 | ), 97 | ), 98 | ), 99 | bottom: PreferredSize( 100 | preferredSize: Size.fromHeight(500), 101 | child: Header(), 102 | ), 103 | actions: [ 104 | Row( 105 | children: [ 106 | MaterialButton( 107 | onPressed: _scrollToAbout, 108 | highlightColor: Colors.white60, 109 | child: Text( 110 | 'About Me', 111 | style: TextStyle( 112 | color: Colors.white, fontWeight: FontWeight.bold), 113 | ), 114 | ), 115 | MaterialButton( 116 | onPressed: _scrollToStatistics, 117 | child: Text( 118 | 'Experience', 119 | style: TextStyle( 120 | color: Colors.white, fontWeight: FontWeight.bold), 121 | ), 122 | ), 123 | MaterialButton( 124 | onPressed: _scrollToWorkingProcess, 125 | child: Text( 126 | 'Process', 127 | style: TextStyle( 128 | color: Colors.white, fontWeight: FontWeight.bold), 129 | ), 130 | ), 131 | MaterialButton( 132 | onPressed: _scrollToRecentProjects, 133 | child: Text( 134 | 'Portfolio', 135 | style: TextStyle( 136 | color: Colors.white, fontWeight: FontWeight.bold), 137 | ), 138 | ), 139 | const SizedBox(width: 20), 140 | RaisedButton( 141 | onPressed: _scrollToContactUs, 142 | color: AppColors.yellow, 143 | padding: const EdgeInsets.symmetric( 144 | horizontal: 40, 145 | vertical: 15, 146 | ), 147 | child: Text( 148 | 'Contact Me', 149 | style: TextStyle( 150 | color: Colors.white, fontWeight: FontWeight.bold), 151 | ), 152 | ), 153 | ], 154 | ), 155 | SizedBox(width: MediaQuery.of(context).size.width * .15), 156 | ], 157 | ), 158 | ..._slivers(), 159 | ], 160 | ), 161 | ), 162 | floatingActionButton: _buildFab(), 163 | ), 164 | mobileScreen: Scaffold( 165 | drawer: Drawer( 166 | child: SingleChildScrollView( 167 | child: Column( 168 | children: [ 169 | Container( 170 | width: 100, 171 | height: 100, 172 | margin: const EdgeInsets.symmetric(vertical: 20), 173 | decoration: BoxDecoration( 174 | color: AppColors.yellow, 175 | borderRadius: BorderRadius.circular(1000), 176 | ), 177 | child: ClipRRect( 178 | borderRadius: BorderRadius.circular(1000), 179 | child: Image.asset( 180 | 'images/ouahid.png', 181 | fit: BoxFit.cover, 182 | ), 183 | ), 184 | ), 185 | Divider(), 186 | ListTile( 187 | onTap: _scrollToAbout, 188 | title: Text( 189 | 'About Me', 190 | style: TextStyle(fontWeight: FontWeight.bold), 191 | ), 192 | ), 193 | ListTile( 194 | onTap: _scrollToStatistics, 195 | title: Text( 196 | 'Experience', 197 | style: TextStyle(fontWeight: FontWeight.bold), 198 | ), 199 | ), 200 | ListTile( 201 | onTap: _scrollToWorkingProcess, 202 | title: Text( 203 | 'Process', 204 | style: TextStyle(fontWeight: FontWeight.bold), 205 | ), 206 | ), 207 | ListTile( 208 | onTap: _scrollToRecentProjects, 209 | title: Text( 210 | 'Portfolio', 211 | style: TextStyle(fontWeight: FontWeight.bold), 212 | ), 213 | ), 214 | Divider(), 215 | const SizedBox(height: 20), 216 | ListTile( 217 | title: RaisedButton( 218 | onPressed: _scrollToContactUs, 219 | color: AppColors.yellow, 220 | padding: const EdgeInsets.symmetric( 221 | horizontal: 40, 222 | vertical: 15, 223 | ), 224 | child: Text( 225 | 'Contact Me', 226 | style: TextStyle(fontWeight: FontWeight.bold), 227 | ), 228 | ), 229 | ), 230 | const SizedBox(height: 20), 231 | Row( 232 | mainAxisAlignment: MainAxisAlignment.center, 233 | children: [ 234 | InkWell( 235 | onTap: () async { 236 | launch(AppConstants.github); 237 | }, 238 | child: AppIcon( 239 | 'icons/github.png', 240 | color: AppColors.black, 241 | ), 242 | ), 243 | const SizedBox(width: 20), 244 | InkWell( 245 | onTap: () { 246 | launch(AppConstants.linkedin); 247 | }, 248 | child: AppIcon( 249 | 'icons/linkedin.png', 250 | color: AppColors.black, 251 | ), 252 | ), 253 | const SizedBox(width: 20), 254 | InkWell( 255 | onTap: () { 256 | launch(AppConstants.twitter); 257 | }, 258 | child: AppIcon( 259 | 'icons/twitter.png', 260 | color: AppColors.black, 261 | ), 262 | ), 263 | const SizedBox(width: 20), 264 | InkWell( 265 | onTap: () { 266 | launch(AppConstants.facebook); 267 | }, 268 | child: AppIcon( 269 | 'icons/facebook.png', 270 | color: AppColors.black, 271 | ), 272 | ), 273 | ], 274 | ), 275 | const SizedBox(height: 20), 276 | ], 277 | ), 278 | ), 279 | ), 280 | body: Container( 281 | decoration: BoxDecoration( 282 | image: DecorationImage( 283 | image: AssetImage('images/background.jpg'), 284 | fit: BoxFit.cover, 285 | ), 286 | ), 287 | child: CustomScrollView( 288 | controller: _scrollController, 289 | slivers: [ 290 | SliverAppBar( 291 | key: _headerGlobalKey, 292 | titleSpacing: 0, 293 | centerTitle: true, 294 | backgroundColor: Colors.transparent, 295 | leading: Align( 296 | child: Builder( 297 | builder: (ctx) => InkWell( 298 | onTap: () { 299 | Scaffold.of(ctx).openDrawer(); 300 | }, 301 | child: ClipRRect( 302 | borderRadius: BorderRadius.circular(1000), 303 | child: Container( 304 | width: 40, 305 | height: 40, 306 | color: AppColors.yellow, 307 | child: Image.asset('images/ouahid.png'), 308 | ), 309 | ), 310 | ), 311 | ), 312 | ), 313 | flexibleSpace: Container( 314 | decoration: BoxDecoration( 315 | image: DecorationImage( 316 | image: AssetImage('images/cover.jpg'), 317 | fit: BoxFit.cover, 318 | ), 319 | ), 320 | child: Container( 321 | decoration: BoxDecoration( 322 | gradient: LinearGradient( 323 | begin: Alignment.bottomCenter, 324 | end: Alignment.topCenter, 325 | colors: [ 326 | Colors.black, 327 | Colors.black87, 328 | Colors.transparent 329 | ], 330 | ), 331 | ), 332 | ), 333 | ), 334 | bottom: PreferredSize( 335 | preferredSize: Size.fromHeight(350), 336 | child: Header(), 337 | ), 338 | ), 339 | ..._slivers(), 340 | ], 341 | ), 342 | ), 343 | floatingActionButton: _buildFab(), 344 | ), 345 | ); 346 | } 347 | 348 | List _slivers() => [ 349 | SliverToBoxAdapter( 350 | key: _aboutGlobaleKey, 351 | child: About(), 352 | ), 353 | SliverToBoxAdapter( 354 | key: _statisticsGlobaleKey, 355 | child: Statistics(), 356 | ), 357 | SliverToBoxAdapter( 358 | key: _workingProcessGlobaleKye, 359 | child: WorkingProcess(), 360 | ), 361 | SliverToBoxAdapter( 362 | key: _recentProjectsGlobaleKey, 363 | child: MyProjects(), 364 | ), 365 | SliverToBoxAdapter( 366 | key: _contactUsGlobaleKey, 367 | child: ContactUs(), 368 | ), 369 | SliverToBoxAdapter( 370 | child: Footer(), 371 | ), 372 | ]; 373 | 374 | Widget _buildFab() { 375 | return StreamBuilder( 376 | stream: _fabStream.stream, 377 | builder: (_, data) { 378 | final bool showFab = data.hasData && data.data!; 379 | return AnimatedOpacity( 380 | opacity: showFab ? 1 : 0, 381 | duration: const Duration(milliseconds: 500), 382 | child: FloatingActionButton( 383 | onPressed: showFab 384 | ? _scrollToHeader 385 | : null, // make sure user cannot click when button hidden 386 | mini: true, 387 | child: AppIcon('icons/double-up-arrow.png', size: 20), 388 | ), 389 | ); 390 | }, 391 | ); 392 | } 393 | 394 | void _scrollToHeader() { 395 | Scrollable.ensureVisible( 396 | _headerGlobalKey.currentContext!, 397 | duration: const Duration(seconds: 1), 398 | ); 399 | } 400 | 401 | void _scrollToAbout() { 402 | Scrollable.ensureVisible( 403 | _aboutGlobaleKey.currentContext!, 404 | duration: const Duration(seconds: 1), 405 | ); 406 | } 407 | 408 | void _scrollToStatistics() { 409 | Scrollable.ensureVisible( 410 | _statisticsGlobaleKey.currentContext!, 411 | duration: const Duration(seconds: 1), 412 | ); 413 | } 414 | 415 | void _scrollToWorkingProcess() { 416 | Scrollable.ensureVisible( 417 | _workingProcessGlobaleKye.currentContext!, 418 | duration: const Duration(seconds: 1), 419 | ); 420 | } 421 | 422 | void _scrollToRecentProjects() { 423 | Scrollable.ensureVisible( 424 | _recentProjectsGlobaleKey.currentContext!, 425 | duration: const Duration(seconds: 1), 426 | ); 427 | } 428 | 429 | void _scrollToContactUs() { 430 | Scrollable.ensureVisible( 431 | _contactUsGlobaleKey.currentContext!, 432 | duration: const Duration(seconds: 1), 433 | ); 434 | } 435 | 436 | @override 437 | void dispose() { 438 | _fabStream.close(); 439 | super.dispose(); 440 | } 441 | } 442 | -------------------------------------------------------------------------------- /lib/ui/icon.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppIcon extends StatelessWidget { 4 | final String path; 5 | final double size; 6 | final Color color; 7 | final Color? background; 8 | 9 | const AppIcon(this.path, 10 | {Key? key, this.size = 25, this.color = Colors.white, this.background}) 11 | : super(key: key); 12 | @override 13 | Widget build(BuildContext context) { 14 | return Container( 15 | color: background, 16 | child: Image.asset(path, color: color, height: size, width: size), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/ui/my_projects.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:url_launcher/url_launcher.dart'; 3 | 4 | import 'responsive_widget.dart'; 5 | import '../data/projects.dart'; 6 | import '../config/styles.dart'; 7 | import '../config/colors.dart'; 8 | 9 | class MyProjects extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return ResponsiveWidget( 13 | desktopScreen: Container( 14 | color: AppColors.greyLight, 15 | padding: EdgeInsets.symmetric(vertical: 100), 16 | child: Column( 17 | children: [ 18 | Text('MY PROJECTS', style: AppStyles.title), 19 | Container(width: 100, height: 2, color: AppColors.yellow), 20 | const SizedBox(height: 3), 21 | Container(width: 75, height: 2, color: AppColors.yellow), 22 | const SizedBox(height: 50), 23 | ...PROJECTS.map((p) => _buildProject(context, p)).toList(), 24 | ], 25 | ), 26 | ), 27 | mobileScreen: Container( 28 | color: AppColors.greyLight, 29 | padding: EdgeInsets.symmetric( 30 | horizontal: MediaQuery.of(context).size.width * .15, 31 | vertical: 50, 32 | ), 33 | child: Column( 34 | children: [ 35 | Text( 36 | 'MY PROJECTS', 37 | style: AppStyles.title, 38 | textAlign: TextAlign.center, 39 | ), 40 | Container(width: 75, height: 2, color: AppColors.yellow), 41 | const SizedBox(height: 3), 42 | Container(width: 50, height: 2, color: AppColors.yellow), 43 | const SizedBox(height: 50), 44 | Wrap( 45 | children: PROJECTS.map((p) => _buildProject(context, p)).toList(), 46 | spacing: 5, 47 | runSpacing: 5, 48 | ), 49 | ], 50 | ), 51 | ), 52 | ); 53 | } 54 | 55 | Widget _buildProject(BuildContext context, Project project) => 56 | ResponsiveWidget( 57 | desktopScreen: SizedBox( 58 | width: MediaQuery.of(context).size.width * .7, 59 | child: Column( 60 | children: [ 61 | Row( 62 | crossAxisAlignment: CrossAxisAlignment.start, 63 | children: [ 64 | SizedBox( 65 | height: MediaQuery.of(context).size.width * .3, 66 | child: Image.asset(project.image!), 67 | ), 68 | SizedBox(width: MediaQuery.of(context).size.width * .075), 69 | Expanded( 70 | child: Column( 71 | crossAxisAlignment: CrossAxisAlignment.start, 72 | children: [ 73 | SizedBox( 74 | height: MediaQuery.of(context).size.width * .01, 75 | ), 76 | Text(project.name!, style: AppStyles.title), 77 | SizedBox( 78 | height: MediaQuery.of(context).size.width * .01, 79 | ), 80 | Text(project.description!), 81 | SizedBox( 82 | height: MediaQuery.of(context).size.width * .025, 83 | ), 84 | Wrap( 85 | spacing: 10, 86 | children: project.skills! 87 | .map((s) => Chip(label: Text(s))) 88 | .toList(), 89 | ), 90 | SizedBox( 91 | height: MediaQuery.of(context).size.width * .025, 92 | ), 93 | OutlineButton( 94 | onPressed: () { 95 | launch(project.url!); 96 | }, 97 | color: AppColors.yellow, 98 | textColor: AppColors.yellow, 99 | borderSide: BorderSide( 100 | color: AppColors.yellow!.withOpacity(.5), 101 | width: 5, 102 | ), 103 | padding: const EdgeInsets.symmetric( 104 | horizontal: 50, 105 | vertical: 20, 106 | ), 107 | shape: RoundedRectangleBorder( 108 | borderRadius: BorderRadius.circular(20), 109 | ), 110 | child: Text('Visit'), 111 | ), 112 | ], 113 | ), 114 | ), 115 | ], 116 | ), 117 | Divider( 118 | color: AppColors.black.withOpacity(.1), 119 | height: 20, 120 | thickness: 1, 121 | ), 122 | ], 123 | ), 124 | ), 125 | mobileScreen: SizedBox( 126 | width: MediaQuery.of(context).size.width * .7, 127 | child: Column( 128 | children: [ 129 | SizedBox( 130 | height: MediaQuery.of(context).size.width * .75, 131 | child: Image.asset(project.image!), 132 | ), 133 | SizedBox(width: MediaQuery.of(context).size.width * .075), 134 | SizedBox( 135 | height: MediaQuery.of(context).size.width * .01, 136 | ), 137 | Text(project.name!, style: AppStyles.title), 138 | SizedBox( 139 | height: MediaQuery.of(context).size.width * .01, 140 | ), 141 | Text( 142 | project.description!, 143 | textAlign: TextAlign.center, 144 | ), 145 | SizedBox( 146 | height: MediaQuery.of(context).size.width * .025, 147 | ), 148 | Wrap( 149 | spacing: 10, 150 | alignment: WrapAlignment.center, 151 | children: 152 | project.skills!.map((s) => Chip(label: Text(s))).toList(), 153 | ), 154 | SizedBox( 155 | height: MediaQuery.of(context).size.width * .025, 156 | ), 157 | OutlineButton( 158 | onPressed: () { 159 | launch(project.url!); 160 | }, 161 | color: AppColors.yellow, 162 | textColor: AppColors.yellow, 163 | borderSide: BorderSide( 164 | color: AppColors.yellow!.withOpacity(.5), 165 | width: 5, 166 | ), 167 | padding: const EdgeInsets.symmetric( 168 | horizontal: 50, 169 | vertical: 20, 170 | ), 171 | shape: RoundedRectangleBorder( 172 | borderRadius: BorderRadius.circular(20), 173 | ), 174 | child: Text('Visit'), 175 | ), 176 | Divider( 177 | color: AppColors.black.withOpacity(.1), 178 | height: 50, 179 | thickness: 1, 180 | ), 181 | ], 182 | ), 183 | ), 184 | ); 185 | } 186 | -------------------------------------------------------------------------------- /lib/ui/responsive_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ResponsiveWidget extends StatelessWidget { 4 | final Widget? desktopScreen; 5 | final Widget? tabletScreen; 6 | final Widget? mobileScreen; 7 | 8 | const ResponsiveWidget( 9 | {Key? key, this.desktopScreen, this.tabletScreen, this.mobileScreen}) 10 | : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | final double screenWidth = MediaQuery.of(context).size.width; 15 | 16 | if (screenWidth > 950) { 17 | return desktopScreen ?? tabletScreen ?? mobileScreen!; 18 | } 19 | if (screenWidth > 600) { 20 | return tabletScreen ?? mobileScreen ?? desktopScreen!; 21 | } 22 | 23 | return mobileScreen ?? tabletScreen ?? desktopScreen!; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/ui/statistics.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../data/projects.dart'; 4 | import 'responsive_widget.dart'; 5 | import 'icon.dart'; 6 | 7 | class Statistics extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return ResponsiveWidget( 11 | desktopScreen: Container( 12 | height: 400, 13 | color: Colors.black.withOpacity(.7), 14 | padding: EdgeInsets.symmetric( 15 | horizontal: MediaQuery.of(context).size.width * .15, 16 | ), 17 | child: 18 | Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ 19 | _buildStatistic( 20 | context, 'icons/briefcase.png', '4+', 'Years of Experience'), 21 | _buildStatistic(context, 'icons/menu.png', '${PROJECTS.length}+', 22 | 'Projects Done'), 23 | _buildStatistic(context, 'icons/happy.png', '50+', 'Happy Clients'), 24 | _buildStatistic(context, 'icons/coffee.png', '∞', 'Coffee Cups'), 25 | ]), 26 | ), 27 | mobileScreen: Container( 28 | color: Colors.black54, 29 | padding: EdgeInsets.symmetric( 30 | horizontal: MediaQuery.of(context).size.width * .15, 31 | vertical: 50, 32 | ), 33 | child: Column( 34 | children: [ 35 | _buildStatistic( 36 | context, 'icons/briefcase.png', '4+', 'Years of Experience'), 37 | const SizedBox(height: 50), 38 | _buildStatistic(context, 'icons/menu.png', '${PROJECTS.length}+', 39 | 'Projects Done'), 40 | const SizedBox(height: 50), 41 | _buildStatistic(context, 'icons/happy.png', '50+', 'Happy Clients'), 42 | const SizedBox(height: 50), 43 | _buildStatistic(context, 'icons/coffee.png', '∞', 'Coffee Cups'), 44 | ], 45 | ), 46 | ), 47 | ); 48 | } 49 | 50 | Widget _buildStatistic( 51 | BuildContext context, String icon, String total, String description) { 52 | return ResponsiveWidget( 53 | desktopScreen: Column( 54 | mainAxisSize: MainAxisSize.min, 55 | children: [ 56 | AppIcon(icon, size: 50), 57 | const SizedBox(height: 5), 58 | Text( 59 | total, 60 | style: TextStyle( 61 | color: Colors.white, 62 | fontSize: 50, 63 | fontWeight: FontWeight.w800, 64 | ), 65 | ), 66 | const SizedBox(height: 5), 67 | Text( 68 | description, 69 | style: TextStyle( 70 | color: Colors.white, 71 | fontSize: 20, 72 | fontWeight: FontWeight.w700, 73 | ), 74 | ), 75 | ], 76 | ), 77 | mobileScreen: Column( 78 | mainAxisSize: MainAxisSize.min, 79 | children: [ 80 | AppIcon(icon, size: 40), 81 | const SizedBox(height: 5), 82 | Text( 83 | total, 84 | style: TextStyle( 85 | color: Colors.white, 86 | fontSize: 30, 87 | fontWeight: FontWeight.w800, 88 | ), 89 | ), 90 | const SizedBox(height: 5), 91 | Text( 92 | description, 93 | style: TextStyle( 94 | color: Colors.white, 95 | fontSize: 15, 96 | fontWeight: FontWeight.w700, 97 | ), 98 | ), 99 | ], 100 | ), 101 | ); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /lib/ui/working_process.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_web_portfolio/ui/responsive_widget.dart'; 3 | 4 | import '../config/styles.dart'; 5 | import '../config/colors.dart'; 6 | import 'icon.dart'; 7 | 8 | class WorkingProcess extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return ResponsiveWidget( 12 | desktopScreen: Container( 13 | color: Colors.white, 14 | padding: EdgeInsets.symmetric( 15 | horizontal: MediaQuery.of(context).size.width * .15, 16 | vertical: 100, 17 | ), 18 | child: Column( 19 | children: [ 20 | Text('WORKING PROCESS', style: AppStyles.title), 21 | Container(width: 100, height: 2, color: AppColors.yellow), 22 | const SizedBox(height: 3), 23 | Container(width: 75, height: 2, color: AppColors.yellow), 24 | const SizedBox(height: 50), 25 | Row( 26 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 27 | children: [ 28 | Expanded( 29 | child: __buildProcess( 30 | context, 31 | '01.', 32 | 'icons/pencil.png', 33 | 'Plan', 34 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor laboris nisi ut aliquip ex ea commodo.'), 35 | ), 36 | const SizedBox(width: 10), 37 | Expanded( 38 | child: __buildProcess( 39 | context, 40 | '02.', 41 | 'icons/design.png', 42 | 'Design', 43 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor laboris nisi ut aliquip ex ea commodo.'), 44 | ), 45 | const SizedBox(width: 10), 46 | Expanded( 47 | child: __buildProcess( 48 | context, 49 | '03.', 50 | 'icons/coding.png', 51 | 'Code', 52 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor laboris nisi ut aliquip ex ea commodo.'), 53 | ) 54 | ], 55 | ), 56 | ], 57 | ), 58 | ), 59 | mobileScreen: Container( 60 | color: Colors.white, 61 | padding: EdgeInsets.symmetric( 62 | horizontal: MediaQuery.of(context).size.width * .15, 63 | vertical: 50, 64 | ), 65 | child: Column( 66 | children: [ 67 | Text( 68 | 'WORKING PROCESS', 69 | style: AppStyles.title, 70 | textAlign: TextAlign.center, 71 | ), 72 | Container(width: 75, height: 2, color: AppColors.yellow), 73 | const SizedBox(height: 3), 74 | Container(width: 50, height: 2, color: AppColors.yellow), 75 | const SizedBox(height: 50), 76 | __buildProcess(context, '01.', 'icons/pencil.png', 'Plan', 77 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor laboris nisi ut aliquip ex ea commodo.'), 78 | const SizedBox(height: 10), 79 | __buildProcess(context, '02.', 'icons/design.png', 'Design', 80 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor laboris nisi ut aliquip ex ea commodo.'), 81 | const SizedBox(height: 10), 82 | __buildProcess(context, '03.', 'icons/coding.png', 'Code', 83 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor laboris nisi ut aliquip ex ea commodo.'), 84 | ], 85 | ), 86 | ), 87 | ); 88 | } 89 | 90 | Widget __buildProcess(BuildContext context, String index, String iconPath, 91 | String title, String description) { 92 | return Card( 93 | elevation: 3, 94 | child: Padding( 95 | padding: const EdgeInsets.all(20), 96 | child: Column( 97 | mainAxisSize: MainAxisSize.min, 98 | children: [ 99 | Align( 100 | alignment: Alignment.topRight, 101 | child: Text( 102 | index, 103 | style: TextStyle( 104 | fontSize: 30, 105 | fontWeight: FontWeight.w700, 106 | ), 107 | ), 108 | ), 109 | const SizedBox(height: 10), 110 | Divider(color: AppColors.greyLight), 111 | const SizedBox(height: 10), 112 | AppIcon(iconPath, color: AppColors.black, size: 40), 113 | const SizedBox(height: 20), 114 | Text( 115 | title, 116 | style: TextStyle( 117 | color: AppColors.black, 118 | fontSize: 25, 119 | fontWeight: FontWeight.bold, 120 | ), 121 | ), 122 | const SizedBox(height: 10), 123 | Text( 124 | description, 125 | style: TextStyle( 126 | color: Colors.black45, 127 | ), 128 | textAlign: TextAlign.center, 129 | ) 130 | ], 131 | ), 132 | ), 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/utils/extensions.dart: -------------------------------------------------------------------------------- 1 | // String 2 | extension StringExtensions on String { 3 | bool get isValidEmail => RegExp( 4 | "^[a-zA-Z0-9.a-zA-Z0-9.!#\$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") 5 | .hasMatch(this.trim()); 6 | 7 | bool isValidName({minLength = 3}) => 8 | this.trim().isNotEmpty && (this.trim().length >= minLength); 9 | } 10 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_web_portfolio 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: '>=2.12.0 <3.0.0' 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.3 31 | url_launcher: ^6.0.10 32 | url_launcher_web: ^2.0.4 33 | mailto: ^2.0.0 34 | 35 | dev_dependencies: 36 | flutter_test: 37 | sdk: flutter 38 | 39 | # For information on the generic Dart part of this file, see the 40 | # following page: https://dart.dev/tools/pub/pubspec 41 | 42 | # The following section is specific to Flutter. 43 | flutter: 44 | 45 | # The following line ensures that the Material Icons font is 46 | # included with your application, so that you can use the icons in 47 | # the material Icons class. 48 | uses-material-design: true 49 | 50 | # To add assets to your application, add an assets section, like this: 51 | # assets: 52 | # - images/a_dot_burr.jpeg 53 | # - images/a_dot_ham.jpeg 54 | 55 | # An image asset can refer to one or more resolution-specific "variants", see 56 | # https://flutter.dev/assets-and-images/#resolution-aware. 57 | 58 | # For details regarding adding assets from package dependencies, see 59 | # https://flutter.dev/assets-and-images/#from-packages 60 | 61 | # To add custom fonts to your application, add a fonts section here, 62 | # in this "flutter" section. Each entry in this list should have a 63 | # "family" key with the font family name, and a "fonts" key with a 64 | # list giving the asset and other descriptors for the font. For 65 | # example: 66 | # fonts: 67 | # - family: Schyler 68 | # fonts: 69 | # - asset: fonts/Schyler-Regular.ttf 70 | # - asset: fonts/Schyler-Italic.ttf 71 | # style: italic 72 | # - family: Trajan Pro 73 | # fonts: 74 | # - asset: fonts/TrajanPro.ttf 75 | # - asset: fonts/TrajanPro_Bold.ttf 76 | # weight: 700 77 | # 78 | # For details regarding fonts from package dependencies, 79 | # see https://flutter.dev/custom-fonts/#from-packages 80 | -------------------------------------------------------------------------------- /screenshots/desktop-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/screenshots/desktop-screenshot.png -------------------------------------------------------------------------------- /screenshots/mobile-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/screenshots/mobile-screenshot.png -------------------------------------------------------------------------------- /screenshots/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/screenshots/screenshot.png -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_web_portfolio/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /web/assets/FontManifest.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "fonts": [ 4 | { 5 | "asset": "fonts/MaterialIcons-Regular.ttf" 6 | } 7 | ], 8 | "family": "MaterialIcons" 9 | } 10 | ] -------------------------------------------------------------------------------- /web/assets/fonts/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/fonts/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /web/assets/icons/briefcase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/briefcase.png -------------------------------------------------------------------------------- /web/assets/icons/call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/call.png -------------------------------------------------------------------------------- /web/assets/icons/coding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/coding.png -------------------------------------------------------------------------------- /web/assets/icons/coffee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/coffee.png -------------------------------------------------------------------------------- /web/assets/icons/design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/design.png -------------------------------------------------------------------------------- /web/assets/icons/double-up-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/double-up-arrow.png -------------------------------------------------------------------------------- /web/assets/icons/email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/email.png -------------------------------------------------------------------------------- /web/assets/icons/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/facebook.png -------------------------------------------------------------------------------- /web/assets/icons/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/github.png -------------------------------------------------------------------------------- /web/assets/icons/happy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/happy.png -------------------------------------------------------------------------------- /web/assets/icons/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/linkedin.png -------------------------------------------------------------------------------- /web/assets/icons/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/list.png -------------------------------------------------------------------------------- /web/assets/icons/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/menu.png -------------------------------------------------------------------------------- /web/assets/icons/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/pencil.png -------------------------------------------------------------------------------- /web/assets/icons/pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/pin.png -------------------------------------------------------------------------------- /web/assets/icons/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/icons/twitter.png -------------------------------------------------------------------------------- /web/assets/images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/background.jpg -------------------------------------------------------------------------------- /web/assets/images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/cover.jpg -------------------------------------------------------------------------------- /web/assets/images/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/icon.jpg -------------------------------------------------------------------------------- /web/assets/images/ouahid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/ouahid.png -------------------------------------------------------------------------------- /web/assets/images/projects/juda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/projects/juda.png -------------------------------------------------------------------------------- /web/assets/images/projects/nataloe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/projects/nataloe.png -------------------------------------------------------------------------------- /web/assets/images/projects/omran.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/projects/omran.png -------------------------------------------------------------------------------- /web/assets/images/projects/topfood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/projects/topfood.png -------------------------------------------------------------------------------- /web/assets/images/projects/toptaxi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/assets/images/projects/toptaxi.png -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekAbdelouahed/flutter-web-portfolio/c49749c31990c3d78402637837a3d875570d8dee/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | flutter_web_portfolio 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_web_portfolio", 3 | "short_name": "flutter_web_portfolio", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | --------------------------------------------------------------------------------