├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── libraries
│ ├── Dart_Packages.xml
│ └── Dart_SDK.xml
├── modules.xml
├── portfolio_demo.iml
└── vcs.xml
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── analysis_options.yaml
├── android
├── app
│ └── src
│ │ └── main
│ │ └── java
│ │ └── io
│ │ └── flutter
│ │ └── plugins
│ │ └── GeneratedPluginRegistrant.java
└── local.properties
├── ios
├── Flutter
│ └── Generated.xcconfig
└── Runner
│ ├── GeneratedPluginRegistrant.h
│ └── GeneratedPluginRegistrant.m
├── lib
├── constants
│ ├── assets.dart
│ ├── fonts.dart
│ ├── strings.dart
│ └── text_styles.dart
├── main.dart
├── models
│ └── education.dart
├── ui
│ └── home.dart
├── utils
│ └── screen
│ │ └── screen_utils.dart
└── widgets
│ └── responsive_widget.dart
├── pubspec.yaml
├── screenshots
└── portfolio.png
└── web
├── assets
├── FontManifest.json
├── fonts
│ ├── MaterialIcons-Regular.ttf
│ ├── Nexa-Bold.otf
│ ├── Nexa-Light.otf
│ ├── Product-Sans-Regular.ttf
│ └── Quicksand-Regular.otf
├── icons
│ ├── ic_dribbble.png
│ ├── ic_evernote.png
│ ├── ic_google.png
│ ├── ic_linkedIn.png
│ └── ic_twitter.png
└── images
│ └── programmer-3.gif
├── favicon.ico
├── index.html
└── main.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | # Files and directories created by pub
2 | .dart_tool/
3 | .packages
4 | # Remove the following pattern if you wish to check in your lock file
5 | pubspec.lock
6 |
7 | # Conventional directory for build outputs
8 | build/
9 |
10 | # Directory created by dartdoc
11 | doc/api/
12 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_Packages.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/portfolio_demo.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.0.0
2 |
3 | - Initial version, created by Stagehand
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Zubair Rehman
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Portfolio
2 |
3 | A portfolio build by using flutter for web.
4 |
5 | ## Demo
6 |
7 |
8 |
9 |
10 |
11 | ## How to Create and Deploy
12 | Follow the links below to learn more about how to create and deploy web applications in flutter.
13 |
14 | * Flutter For Web: [A Complete Guide to Create & Run a Web Application](https://medium.com/@zubairehman.work/flutter-for-web-c75011a41956)
15 |
16 | * Flutter For Web: [A Complete Guide to Deploy a Web Application](https://medium.com/@zubairehman.work/flutter-for-web-a-complete-guide-to-deploy-a-web-application-3fa9463377a8)
17 |
18 | ## How to Use
19 |
20 | **Step 1:**
21 |
22 | Download or clone this repo by using the link below:
23 |
24 | ```
25 | https://github.com/zubairehman/Portfolio-Demo.git
26 | ```
27 |
28 | **Step 2:**
29 |
30 | Go to project root and execute the following command in console to get the required dependencies:
31 |
32 | ```
33 | flutter pub get
34 | ```
35 |
36 | **Step 3:**
37 |
38 | To use the Flutter SDK with the flutter_web preview make sure you have upgraded Flutter to at least v1.5.4 by running flutter upgrade from your machine. Follow the link to learn more about how to configure flutter for web: https://medium.com/@zubairehman.work/flutter-for-web-c75011a41956
39 |
40 | **Step 4:**
41 |
42 | To run this application simply type in the following command:
43 |
44 | ```
45 | flutter packages pub global run webdev serve
46 | ```
47 |
48 | ## Folder Structure
49 | Here is the core folder structure which flutter provides.
50 |
51 | ```
52 | flutter-app/
53 | |- android
54 | |- build
55 | |- ios
56 | |- lib
57 | |- test
58 | ```
59 |
60 | Here is the folder structure we have been using in this project
61 |
62 | ```
63 | lib/
64 | |- constants/
65 | |- ui/
66 | |- utils/
67 | |- widgets/
68 | |- main.dart
69 | ```
70 |
71 | Now, lets dive into the lib folder which has the main code for the application.
72 |
73 | ```
74 | 1- constants - All the application level constants are defined in this directory with-in their respective files. This directory contains the constants for `theme`, `dimentions`, `api endpoints`, `preferences` and `strings`.
75 | 2- ui — Contains all the ui of your project, contains sub directory for each screen.
76 | 3- util — Contains the utilities/common functions of your application.
77 | 4- widgets — Contains the common widgets for your applications. For example, Button, TextField etc.
78 | 5- main.dart - This is the starting point of the application. All the application level configurations are defined in this file i.e, theme, routes, title, orientation etc.
79 | ```
80 |
81 | ### Constants
82 |
83 | This directory contains all the application level constants. A separate file is created for each type as shown in example below:
84 |
85 | ```
86 | constants/
87 | |- assets.dart
88 | |- fonts.dart
89 | |- strings.dart
90 | |- text_styles.dart
91 | ```
92 |
93 | ### UI
94 |
95 | This directory contains all the ui of your application. Each screen is located in a separate folder making it easy to combine group of files related to that particular screen. All the screen specific widgets will be placed in `widgets` directory as shown in the example below:
96 |
97 | ```
98 | ui/
99 | |- login
100 | |- login_screen.dart
101 | |- widgets
102 | |- login_form.dart
103 | |- login_button.dart
104 | ```
105 |
106 | ### Utils
107 |
108 | Contains the common file(s) and utilities used in a project. The folder structure is as follows:
109 |
110 | ```
111 | utils/
112 | |- encryption
113 | |- xxtea.dart
114 | |- date
115 | |- date_time.dart
116 | ```
117 |
118 | ### Widgets
119 |
120 | Contains the common widgets that are shared across multiple screens. For example, Button, TextField etc.
121 |
122 | ```
123 | widgets/
124 | |- app_icon_widget.dart
125 | |- empty_app_bar.dart
126 | |- progress_indicator.dart
127 | ```
128 |
129 | ### Main
130 |
131 | This is the starting point of the application. All the application level configurations are defined in this file i.e, theme, routes, title, orientation etc.
132 |
133 | ```
134 | import 'package:flutter_web/material.dart';
135 | import 'package:portfolio/ui/home.dart';
136 |
137 | import 'package:portfolio/utils/screen/screen_utils.dart';
138 |
139 | void main() {
140 | runApp(MyApp());
141 | }
142 |
143 | class MyApp extends StatelessWidget {
144 |
145 | @override
146 | Widget build(BuildContext context) {
147 |
148 | return MaterialApp(
149 | debugShowCheckedModeBanner: false,
150 | theme: ThemeData(
151 | brightness: Brightness.light,
152 | primaryColorBrightness: Brightness.light,
153 | accentColorBrightness: Brightness.light
154 | ),
155 | home: MyAppChild(),
156 | );
157 | }
158 | }
159 |
160 | class MyAppChild extends StatefulWidget {
161 |
162 | @override
163 | _MyAppChildState createState() => _MyAppChildState();
164 | }
165 |
166 | class _MyAppChildState extends State {
167 | @override
168 | Widget build(BuildContext context) {
169 | // instantiating ScreenUtil singleton instance, as this will be used throughout
170 | // the app to get screen size and other stuff
171 | ScreenUtil.instance = ScreenUtil.getInstance()..init(context);
172 | return HomePage();
173 | }
174 | }
175 | ```
176 |
177 | If you liked my work, don’t forget to ⭐ star the repo to show your support.
178 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # Defines a default set of lint rules enforced for
2 | # projects at Google. For details and rationale,
3 | # see https://github.com/dart-lang/pedantic#enabled-lints.
4 | include: package:pedantic/analysis_options.yaml
5 |
6 | # For lint rules and documentation, see http://dart-lang.github.io/linter/lints.
7 | # Uncomment to specify additional rules.
8 | # linter:
9 | # rules:
10 | # - camel_case_types
11 |
12 | analyzer:
13 | # exclude:
14 | # - path/to/excluded/files/**
15 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java:
--------------------------------------------------------------------------------
1 | package io.flutter.plugins;
2 |
3 | import io.flutter.plugin.common.PluginRegistry;
4 |
5 | /**
6 | * Generated file. Do not edit.
7 | */
8 | public final class GeneratedPluginRegistrant {
9 | public static void registerWith(PluginRegistry registry) {
10 | if (alreadyRegisteredWith(registry)) {
11 | return;
12 | }
13 | }
14 |
15 | private static boolean alreadyRegisteredWith(PluginRegistry registry) {
16 | final String key = GeneratedPluginRegistrant.class.getCanonicalName();
17 | if (registry.hasPlugin(key)) {
18 | return true;
19 | }
20 | registry.registrarFor(key);
21 | return false;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/android/local.properties:
--------------------------------------------------------------------------------
1 | sdk.dir=/Users/macbookpro/Library/Android/sdk
2 | flutter.sdk=/Users/macbookpro/Documents/flutter
--------------------------------------------------------------------------------
/ios/Flutter/Generated.xcconfig:
--------------------------------------------------------------------------------
1 | // This is a generated file; do not edit or check into version control.
2 | FLUTTER_ROOT=/Users/zubairehman/Desktop/flutter
3 | FLUTTER_APPLICATION_PATH=/Users/zubairehman/Desktop/Zubair/Practice Projects/outdoor_furniture
4 | FLUTTER_TARGET=lib/main.dart
5 | FLUTTER_BUILD_DIR=build
6 | SYMROOT=${SOURCE_ROOT}/../build/ios
7 | FLUTTER_FRAMEWORK_DIR=/Users/zubairehman/Desktop/flutter/bin/cache/artifacts/engine/ios
8 |
--------------------------------------------------------------------------------
/ios/Runner/GeneratedPluginRegistrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #ifndef GeneratedPluginRegistrant_h
6 | #define GeneratedPluginRegistrant_h
7 |
8 | #import
9 |
10 | @interface GeneratedPluginRegistrant : NSObject
11 | + (void)registerWithRegistry:(NSObject*)registry;
12 | @end
13 |
14 | #endif /* GeneratedPluginRegistrant_h */
15 |
--------------------------------------------------------------------------------
/ios/Runner/GeneratedPluginRegistrant.m:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #import "GeneratedPluginRegistrant.h"
6 |
7 | @implementation GeneratedPluginRegistrant
8 |
9 | + (void)registerWithRegistry:(NSObject*)registry {
10 | }
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/lib/constants/assets.dart:
--------------------------------------------------------------------------------
1 | class Assets {
2 | Assets._();
3 |
4 | static const String programmer3 = 'assets/images/programmer-3.gif';
5 |
6 | // social icons
7 | static const String dribble = 'assets/icons/ic_dribbble.png';
8 | static const String evernote = 'assets/icons/ic_evernote.png';
9 | static const String google = 'assets/icons/ic_google.png';
10 | static const String twitter = 'assets/icons/ic_twitter.png';
11 | static const String linkedin = 'assets/icons/ic_linkedIn.png';
12 | }
--------------------------------------------------------------------------------
/lib/constants/fonts.dart:
--------------------------------------------------------------------------------
1 | class Fonts {
2 | Fonts._();
3 |
4 | static const String product = 'ProductSans';
5 | static const String nexa_light = 'NexaLight';
6 | static const String nexa_bold = 'NexaBold';
7 |
8 | }
--------------------------------------------------------------------------------
/lib/constants/strings.dart:
--------------------------------------------------------------------------------
1 | class Strings {
2 | Strings._();
3 |
4 | static const String about_me = 'About Me';
5 | static const String about = 'About';
6 | static const String me = ' Me';
7 | static const String portfoli = 'Portfoli';
8 | static const String o = 'o';
9 | static const String headline = 'I\'am Zubair Rehman, Mobile App Developer from Islamabad, Pakistan';
10 | static const String summary = 'Focused professional having excellent technical and communication skills, and offering 6 years of experience in Computer industry. Proficient at designing and formulating test automation frameworks, writing code in various languages, feature development and implementation. Specialize in thinking outside the box to find unique solutions to difficult engineering problems.';
11 | static const String experience = 'Experience';
12 | static const String skills_i_have = 'What Skill I Have';
13 | static const String rights_reserved = '© 2019 IOTECK SOLUTIONS. ALL RIGHTS RESERVED.';
14 |
15 | // menu items
16 | static const String menu_home = 'Home';
17 | static const String menu_about = 'About';
18 | static const String menu_contact = 'Contact';
19 |
20 | }
--------------------------------------------------------------------------------
/lib/constants/text_styles.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_web/material.dart';
2 | import 'package:portfolio/constants/fonts.dart';
3 |
4 | class TextStyles {
5 | TextStyles._();
6 |
7 | static TextStyle get logo => TextStyle(
8 | fontFamily: Fonts.product,
9 | color: Color(0xFF45405B),
10 | fontSize: 22.0, //22.0
11 | fontWeight: FontWeight.bold,
12 | letterSpacing: 1.0,
13 | );
14 |
15 | static TextStyle get menu_item => TextStyle(
16 | fontFamily: Fonts.product,
17 | fontSize: 12.0, //12,.0
18 | letterSpacing: 1.0,
19 | color: Color(0xFF45405B),
20 | );
21 |
22 | static TextStyle get heading => TextStyle(
23 | fontFamily: Fonts.nexa_bold,
24 | color: Color(0xFF45405B),
25 | fontSize: 45.0, //45.0
26 | fontWeight: FontWeight.bold,
27 | letterSpacing: 1.0,
28 | );
29 |
30 | static TextStyle get sub_heading => TextStyle(
31 | color: Color(0xFF45405B),
32 | fontFamily: Fonts.product,
33 | fontSize: 17.0, //17.0
34 | letterSpacing: 1.2,
35 | );
36 |
37 | static TextStyle get company => TextStyle(
38 | fontFamily: Fonts.product,
39 | color: Color(0xFF45405B),
40 | height: 1.5,
41 | fontSize: 15.0, //15.0
42 | letterSpacing: 1.0,
43 | );
44 |
45 | static TextStyle get body => TextStyle(
46 | fontFamily: Fonts.product,
47 | color: Color(0xFF85819C),
48 | height: 1.5,
49 | fontSize: 12.0, //12.0
50 | letterSpacing: 1.0,
51 | );
52 |
53 | static TextStyle get body1 => TextStyle(
54 | fontFamily: Fonts.product,
55 | color: Color(0xFF85819C),
56 | height: 1.5,
57 | fontSize: 10.0, //10.0
58 | letterSpacing: 1.0,
59 | );
60 |
61 | static TextStyle get chip => TextStyle(
62 | fontFamily: Fonts.product,
63 | color: Color(0xFF85819C),
64 | height: 1.5,
65 | fontSize: 12.0, //12.0
66 | letterSpacing: 1.0,
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_web/material.dart';
2 | import 'package:portfolio/ui/home.dart';
3 |
4 | import 'package:portfolio/utils/screen/screen_utils.dart';
5 |
6 | void main() {
7 | runApp(MyApp());
8 | }
9 |
10 | class MyApp extends StatelessWidget {
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 |
15 | return MaterialApp(
16 | debugShowCheckedModeBanner: false,
17 | theme: ThemeData(
18 | brightness: Brightness.light,
19 | primaryColorBrightness: Brightness.light,
20 | accentColorBrightness: Brightness.light
21 | ),
22 | home: MyAppChild(),
23 | );
24 | }
25 | }
26 |
27 | class MyAppChild extends StatefulWidget {
28 |
29 | @override
30 | _MyAppChildState createState() => _MyAppChildState();
31 | }
32 |
33 | class _MyAppChildState extends State {
34 | @override
35 | Widget build(BuildContext context) {
36 | // instantiating ScreenUtil singleton instance, as this will be used throughout
37 | // the app to get screen size and other stuff
38 | ScreenUtil.instance = ScreenUtil.getInstance()..init(context);
39 | return HomePage();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/lib/models/education.dart:
--------------------------------------------------------------------------------
1 | class Education {
2 | String from;
3 | String to;
4 | String organization;
5 | String post;
6 |
7 | Education(this.from, this.to, this.organization, this.post);
8 | }
9 |
--------------------------------------------------------------------------------
/lib/ui/home.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_web/material.dart';
2 | import 'package:portfolio/constants/assets.dart';
3 | import 'package:portfolio/constants/fonts.dart';
4 | import 'package:portfolio/constants/strings.dart';
5 | import 'package:portfolio/constants/text_styles.dart';
6 | import 'package:portfolio/models/education.dart';
7 | import 'package:portfolio/utils/screen/screen_utils.dart';
8 | import 'package:portfolio/widgets/responsive_widget.dart';
9 | import 'dart:html' as html;
10 |
11 | class HomePage extends StatelessWidget {
12 | @override
13 | Widget build(BuildContext context) {
14 | return Material(
15 | color: Color(0xFFF7F8FA),
16 | child: Padding(
17 | padding: EdgeInsets.symmetric(
18 | horizontal: (ScreenUtil.getInstance().setWidth(108))), //144
19 | child: Scaffold(
20 | backgroundColor: Colors.transparent,
21 | appBar: _buildAppBar(context),
22 | drawer: _buildDrawer(context),
23 | body: LayoutBuilder(builder: (context, constraints) {
24 | return _buildBody(context, constraints);
25 | }),
26 | ),
27 | ),
28 | );
29 | }
30 |
31 | //AppBar Methods:-------------------------------------------------------------
32 | Widget _buildAppBar(BuildContext context) {
33 | return AppBar(
34 | titleSpacing: 0.0,
35 | title: _buildTitle(),
36 | backgroundColor: Colors.transparent,
37 | elevation: 0.0,
38 | actions:
39 | !ResponsiveWidget.isSmallScreen(context) ? _buildActions() : null,
40 | );
41 | }
42 |
43 | Widget _buildTitle() {
44 | return RichText(
45 | text: TextSpan(
46 | // Note: Styles for TextSpans must be explicitly defined.
47 | // Child text spans will inherit styles from parent
48 | style: TextStyle(
49 | fontSize: 14.0,
50 | color: Colors.black,
51 | ),
52 | children: [
53 | TextSpan(
54 | text: Strings.portfoli,
55 | style: TextStyles.logo,
56 | ),
57 | TextSpan(
58 | text: Strings.o,
59 | style: TextStyles.logo.copyWith(
60 | color: Color(0xFF50AFC0),
61 | ),
62 | ),
63 | ],
64 | ),
65 | );
66 | }
67 |
68 | List _buildActions() {
69 | return [
70 | MaterialButton(
71 | child: Text(
72 | Strings.menu_home,
73 | style: TextStyles.menu_item.copyWith(
74 | color: Color(0xFF50AFC0),
75 | ),
76 | ),
77 | onPressed: () {},
78 | ),
79 | MaterialButton(
80 | child: Text(
81 | Strings.menu_about,
82 | style: TextStyles.menu_item,
83 | ),
84 | onPressed: () {},
85 | ),
86 | MaterialButton(
87 | child: Text(
88 | Strings.menu_contact,
89 | style: TextStyles.menu_item,
90 | ),
91 | onPressed: () {},
92 | ),
93 | ];
94 | }
95 |
96 | Widget _buildDrawer(BuildContext context) {
97 | return ResponsiveWidget.isSmallScreen(context)
98 | ? Drawer(
99 | child: ListView(
100 | padding: const EdgeInsets.all(20),
101 | children: _buildActions(),
102 | ),
103 | )
104 | : null;
105 | }
106 |
107 | //Screen Methods:-------------------------------------------------------------
108 | Widget _buildBody(BuildContext context, BoxConstraints constraints) {
109 | return SingleChildScrollView(
110 | child: ConstrainedBox(
111 | constraints: BoxConstraints(
112 | minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
113 | child: ResponsiveWidget(
114 | largeScreen: _buildLargeScreen(context),
115 | mediumScreen: _buildMediumScreen(context),
116 | smallScreen: _buildSmallScreen(context),
117 | ),
118 | ),
119 | );
120 | }
121 |
122 | Widget _buildLargeScreen(BuildContext context) {
123 | return IntrinsicHeight(
124 | child: Column(
125 | mainAxisSize: MainAxisSize.min,
126 | mainAxisAlignment: MainAxisAlignment.start,
127 | children: [
128 | Expanded(
129 | child: Row(
130 | mainAxisSize: MainAxisSize.max,
131 | children: [
132 | Expanded(flex: 1, child: _buildContent(context)),
133 | _buildIllustration(),
134 | ],
135 | ),
136 | ),
137 | _buildFooter(context)
138 | ],
139 | ),
140 | );
141 | }
142 |
143 | Widget _buildMediumScreen(BuildContext context) {
144 | return IntrinsicHeight(
145 | child: Column(
146 | mainAxisSize: MainAxisSize.min,
147 | mainAxisAlignment: MainAxisAlignment.start,
148 | children: [
149 | Expanded(
150 | child: Row(
151 | mainAxisSize: MainAxisSize.max,
152 | children: [
153 | Expanded(flex: 1, child: _buildContent(context)),
154 | ],
155 | ),
156 | ),
157 | _buildFooter(context)
158 | ],
159 | ),
160 | );
161 | }
162 |
163 | Widget _buildSmallScreen(BuildContext context) {
164 | return IntrinsicHeight(
165 | child: Column(
166 | mainAxisSize: MainAxisSize.min,
167 | children: [
168 | Expanded(flex: 1, child: _buildContent(context)),
169 | Divider(),
170 | _buildCopyRightText(context),
171 | SizedBox(
172 | height: ResponsiveWidget.isSmallScreen(context) ? 12.0 : 0.0),
173 | _buildSocialIcons(),
174 | SizedBox(
175 | height: ResponsiveWidget.isSmallScreen(context) ? 12.0 : 0.0),
176 | ],
177 | ),
178 | );
179 | }
180 |
181 | // Body Methods:--------------------------------------------------------------
182 | Widget _buildIllustration() {
183 | return Image.network(
184 | Assets.programmer3,
185 | height: ScreenUtil.getInstance().setWidth(345), //480.0
186 | );
187 | }
188 |
189 | Widget _buildContent(BuildContext context) {
190 | return Column(
191 | mainAxisSize: MainAxisSize.min,
192 | mainAxisAlignment: MainAxisAlignment.center,
193 | crossAxisAlignment: CrossAxisAlignment.start,
194 | children: [
195 | SizedBox(height: ResponsiveWidget.isSmallScreen(context) ? 24.0 : 0.0),
196 | _buildAboutMe(context),
197 | SizedBox(height: 4.0),
198 | _buildHeadline(context),
199 | SizedBox(height: ResponsiveWidget.isSmallScreen(context) ? 12.0 : 24.0),
200 | _buildSummary(),
201 | SizedBox(height: ResponsiveWidget.isSmallScreen(context) ? 24.0 : 48.0),
202 | ResponsiveWidget.isSmallScreen(context)
203 | ? Column(
204 | mainAxisSize: MainAxisSize.min,
205 | crossAxisAlignment: CrossAxisAlignment.start,
206 | children: [
207 | _buildEducation(),
208 | SizedBox(height: 24.0),
209 | _buildSkills(context),
210 | ],
211 | )
212 | : _buildSkillsAndEducation(context)
213 | ],
214 | );
215 | }
216 |
217 | Widget _buildAboutMe(BuildContext context) {
218 | return RichText(
219 | text: TextSpan(
220 | // Note: Styles for TextSpans must be explicitly defined.
221 | // Child text spans will inherit styles from parent
222 | style: TextStyle(
223 | fontSize: 14.0,
224 | color: Colors.black,
225 | ),
226 | children: [
227 | TextSpan(
228 | text: Strings.about,
229 | style: TextStyles.heading.copyWith(
230 | fontFamily: Fonts.nexa_light,
231 | fontSize: ResponsiveWidget.isSmallScreen(context) ? 36 : 45.0,
232 | ),
233 | ),
234 | TextSpan(
235 | text: Strings.me,
236 | style: TextStyles.heading.copyWith(
237 | color: Color(0xFF50AFC0),
238 | fontSize: ResponsiveWidget.isSmallScreen(context) ? 36 : 45.0,
239 | ),
240 | ),
241 | ],
242 | ),
243 | );
244 | }
245 |
246 | Widget _buildHeadline(BuildContext context) {
247 | return Text(
248 | ResponsiveWidget.isSmallScreen(context)
249 | ? Strings.headline
250 | : Strings.headline.replaceFirst(RegExp(r' f'), '\nf'),
251 | style: TextStyles.sub_heading,
252 | );
253 | }
254 |
255 | Widget _buildSummary() {
256 | return Padding(
257 | padding: EdgeInsets.only(right: 80.0),
258 | child: Text(
259 | Strings.summary,
260 | style: TextStyles.body,
261 | ),
262 | );
263 | }
264 |
265 | Widget _buildSkillsAndEducation(BuildContext context) {
266 | return Row(
267 | crossAxisAlignment: CrossAxisAlignment.start,
268 | children: [
269 | Expanded(
270 | flex: 1,
271 | child: _buildEducation(),
272 | ),
273 | SizedBox(width: 40.0),
274 | Expanded(
275 | flex: 1,
276 | child: _buildSkills(context),
277 | ),
278 | ],
279 | );
280 | }
281 |
282 | // Skills Methods:------------------------------------------------------------
283 | final skills = [
284 | 'Java',
285 | 'Kotlin',
286 | 'Dart',
287 | 'Flutter',
288 | 'Android',
289 | 'iOS',
290 | 'Xamarin',
291 | 'Reactive Programming',
292 | 'Jenkins',
293 | 'Photoshop',
294 | 'JFrog Atrtifactory',
295 | 'Code Magic',
296 | ];
297 |
298 | Widget _buildSkills(BuildContext context) {
299 | final List widgets = skills
300 | .map((skill) => Padding(
301 | padding: EdgeInsets.only(right: 8.0),
302 | child: _buildSkillChip(context, skill),
303 | ))
304 | .toList();
305 |
306 | return Column(
307 | mainAxisSize: MainAxisSize.max,
308 | crossAxisAlignment: CrossAxisAlignment.start,
309 | children: [
310 | _buildSkillsContainerHeading(),
311 | Wrap(children: widgets),
312 | // _buildNavigationArrows(),
313 | ],
314 | );
315 | }
316 |
317 | Widget _buildSkillsContainerHeading() {
318 | return Text(
319 | Strings.skills_i_have,
320 | style: TextStyles.sub_heading,
321 | );
322 | }
323 |
324 | Widget _buildSkillChip(BuildContext context, String label) {
325 | return Chip(
326 | label: Text(
327 | label,
328 | style: TextStyles.chip.copyWith(
329 | fontSize: ResponsiveWidget.isSmallScreen(context) ? 10.0 : 11.0,
330 | ),
331 | ),
332 | );
333 | }
334 |
335 | // Education Methods:---------------------------------------------------------
336 | final educationList = [
337 | Education(
338 | 'Apr 2018',
339 | 'Present',
340 | 'Embrace-it Pakistan',
341 | 'Sr. Software Engineer',
342 | ),
343 | Education(
344 | 'Apr 2016',
345 | 'Apr 2018',
346 | 'TEO International',
347 | 'Sr. Software Engineer',
348 | ),
349 | Education(
350 | 'July 2014',
351 | 'March 2016',
352 | 'Citrusbits',
353 | 'Software Engineer',
354 | ),
355 | ];
356 |
357 | Widget _buildEducation() {
358 | return Column(
359 | crossAxisAlignment: CrossAxisAlignment.start,
360 | children: [
361 | _buildEducationContainerHeading(),
362 | _buildEducationSummary(),
363 | SizedBox(height: 8.0),
364 | _buildEducationTimeline(),
365 | ],
366 | );
367 | }
368 |
369 | Widget _buildEducationContainerHeading() {
370 | return Text(
371 | Strings.experience,
372 | style: TextStyles.sub_heading,
373 | );
374 | }
375 |
376 | Widget _buildEducationSummary() {
377 | return Text(
378 | 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
379 | style: TextStyles.body,
380 | );
381 | }
382 |
383 | Widget _buildEducationTimeline() {
384 | final List widgets = educationList
385 | .map((education) => _buildEducationTile(education))
386 | .toList();
387 | return Column(children: widgets);
388 | }
389 |
390 | Widget _buildEducationTile(Education education) {
391 | return Padding(
392 | padding: EdgeInsets.symmetric(vertical: 8.0),
393 | child: Column(
394 | crossAxisAlignment: CrossAxisAlignment.stretch,
395 | children: [
396 | Text(
397 | '${education.post}',
398 | style: TextStyles.company,
399 | ),
400 | Text(
401 | '${education.organization}',
402 | style: TextStyles.body.copyWith(
403 | color: Color(0xFF45405B),
404 | ),
405 | ),
406 | Text(
407 | '${education.from}-${education.to}',
408 | style: TextStyles.body,
409 | ),
410 | ],
411 | ),
412 | );
413 | }
414 |
415 | // Footer Methods:------------------------------------------------------------
416 | Widget _buildFooter(BuildContext context) {
417 | return Column(
418 | children: [
419 | Divider(),
420 | Padding(
421 | padding: EdgeInsets.all(12.0),
422 | child: Row(
423 | mainAxisSize: MainAxisSize.max,
424 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
425 | children: [
426 | Align(
427 | child: _buildCopyRightText(context),
428 | alignment: Alignment.centerLeft,
429 | ),
430 | Align(
431 | child: _buildSocialIcons(),
432 | alignment: Alignment.centerRight,
433 | ),
434 | ],
435 | ),
436 | ),
437 | ],
438 | );
439 | }
440 |
441 | Widget _buildCopyRightText(BuildContext context) {
442 | return Text(
443 | Strings.rights_reserved,
444 | style: TextStyles.body1.copyWith(
445 | fontSize: ResponsiveWidget.isSmallScreen(context) ? 8 : 10.0,
446 | ),
447 | );
448 | }
449 |
450 | Widget _buildSocialIcons() {
451 | return Row(
452 | mainAxisSize: MainAxisSize.max,
453 | mainAxisAlignment: MainAxisAlignment.center,
454 | children: [
455 | GestureDetector(
456 | onTap: () {
457 | html.window
458 | .open("https://www.linkedin.com/in/zubairehman/", "LinkedIn");
459 | },
460 | child: Image.network(
461 | Assets.linkedin,
462 | color: Color(0xFF45405B),
463 | height: 20.0,
464 | width: 20.0,
465 | ),
466 | ),
467 | SizedBox(width: 16.0),
468 | GestureDetector(
469 | onTap: () {
470 | html.window.open("https://medium.com/@zubairehman.work", "Medium");
471 | },
472 | child: Image.network(
473 | Assets.evernote,
474 | color: Color(0xFF45405B),
475 | height: 20.0,
476 | width: 20.0,
477 | ),
478 | ),
479 | SizedBox(width: 16.0),
480 | GestureDetector(
481 | onTap: () {
482 | html.window.open("https://github.com/zubairehman", "Github");
483 | },
484 | child: Image.network(
485 | Assets.google,
486 | color: Color(0xFF45405B),
487 | height: 20.0,
488 | width: 20.0,
489 | ),
490 | ),
491 | SizedBox(width: 16.0),
492 | GestureDetector(
493 | onTap: () {
494 | html.window.open("https://twitter.com/zubair340", "Twitter");
495 | },
496 | child: Image.network(
497 | Assets.twitter,
498 | color: Color(0xFF45405B),
499 | height: 20.0,
500 | width: 20.0,
501 | ),
502 | ),
503 | ],
504 | );
505 | }
506 | }
507 |
--------------------------------------------------------------------------------
/lib/utils/screen/screen_utils.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/29.
3 | * email: zhuoyuan93@gmail.com
4 | */
5 |
6 | import 'package:flutter_web/material.dart';
7 |
8 | class ScreenUtil {
9 | static ScreenUtil instance = new ScreenUtil();
10 |
11 | //设计稿的设备尺寸修改
12 | double width;
13 | double height;
14 | bool allowFontScaling;
15 |
16 | static MediaQueryData _mediaQueryData;
17 | static double _screenWidth;
18 | static double _screenHeight;
19 | static double _pixelRatio;
20 | static double _statusBarHeight;
21 |
22 | static double _bottomBarHeight;
23 |
24 | static double _textScaleFactor;
25 |
26 | ScreenUtil({
27 | this.width = 1080,
28 | this.height = 1920,
29 | this.allowFontScaling = false,
30 | });
31 |
32 | static ScreenUtil getInstance() {
33 | return instance;
34 | }
35 |
36 | void init(BuildContext context) {
37 | MediaQueryData mediaQuery = MediaQuery.of(context);
38 | _mediaQueryData = mediaQuery;
39 | _pixelRatio = mediaQuery.devicePixelRatio;
40 | _screenWidth = mediaQuery.size.width;
41 | _screenHeight = mediaQuery.size.height;
42 | _statusBarHeight = mediaQuery.padding.top;
43 | _bottomBarHeight = _mediaQueryData.padding.bottom;
44 | _textScaleFactor = mediaQuery.textScaleFactor;
45 | }
46 |
47 | static MediaQueryData get mediaQueryData => _mediaQueryData;
48 |
49 | ///每个逻辑像素的字体像素数,字体的缩放比例
50 | static double get textScaleFactory => _textScaleFactor;
51 |
52 | ///设备的像素密度
53 | static double get pixelRatio => _pixelRatio;
54 |
55 | ///当前设备宽度 dp
56 | static double get screenWidthDp => _screenWidth;
57 |
58 | ///当前设备高度 dp
59 | static double get screenHeightDp => _screenHeight;
60 |
61 | ///当前设备宽度 px
62 | static double get screenWidth => _screenWidth * _pixelRatio;
63 |
64 | ///当前设备高度 px
65 | static double get screenHeight => _screenHeight * _pixelRatio;
66 |
67 | ///状态栏高度 dp 刘海屏会更高
68 | static double get statusBarHeight => _statusBarHeight;
69 |
70 | ///底部安全区距离 dp
71 | static double get bottomBarHeight => _bottomBarHeight;
72 |
73 | ///实际的dp与设计稿px的比例
74 | get scaleWidth => _screenWidth / instance.width;
75 |
76 | get scaleHeight => _screenHeight / instance.height;
77 |
78 | ///根据设计稿的设备宽度适配
79 | ///高度也根据这个来做适配可以保证不变形
80 | setWidth(double width) => width * scaleWidth;
81 |
82 | /// 根据设计稿的设备高度适配
83 | /// 当发现设计稿中的一屏显示的与当前样式效果不符合时,
84 | /// 或者形状有差异时,高度适配建议使用此方法
85 | /// 高度适配主要针对想根据设计稿的一屏展示一样的效果
86 | setHeight(double height) => height * scaleHeight;
87 |
88 | ///字体大小适配方法
89 | ///@param fontSize 传入设计稿上字体的px ,
90 | ///@param allowFontScaling 控制字体是否要根据系统的“字体大小”辅助选项来进行缩放。默认值为false。
91 | ///@param allowFontScaling Specifies whether fonts should scale to respect Text Size accessibility settings. The default is false.
92 | setSp(double fontSize) => allowFontScaling
93 | ? setWidth(fontSize)
94 | : setWidth(fontSize) / _textScaleFactor;
95 | }
--------------------------------------------------------------------------------
/lib/widgets/responsive_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_web/material.dart';
2 |
3 | class ResponsiveWidget extends StatelessWidget {
4 | final Widget largeScreen;
5 | final Widget mediumScreen;
6 | final Widget smallScreen;
7 |
8 | const ResponsiveWidget(
9 | {Key key,
10 | @required this.largeScreen,
11 | this.mediumScreen,
12 | this.smallScreen})
13 | : super(key: key);
14 |
15 | static bool isSmallScreen(BuildContext context) {
16 | return MediaQuery.of(context).size.width < 768;
17 | }
18 |
19 | static bool isLargeScreen(BuildContext context) {
20 | return MediaQuery.of(context).size.width > 768;
21 | }
22 |
23 | static bool isMediumScreen(BuildContext context) {
24 | return MediaQuery.of(context).size.width > 768 &&
25 | MediaQuery.of(context).size.width < 1200;
26 | }
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return LayoutBuilder(
31 | builder: (context, constraints) {
32 | if (constraints.maxWidth > 768) {
33 | return largeScreen;
34 | } else if (constraints.maxWidth < 1200 && constraints.maxWidth > 425) {
35 | return mediumScreen ?? largeScreen;
36 | } else {
37 | return smallScreen ?? largeScreen;
38 | }
39 | },
40 | );
41 | }
42 | }
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: portfolio
2 | description: A portfolio build by using flutter for web.
3 | # version: 1.0.0
4 | #homepage: http://zubair-portfolio.surge.sh/#/
5 | #author: zubairehman
6 |
7 | environment:
8 | sdk: '>=2.2.0 <3.0.0'
9 |
10 | dependencies:
11 | flutter_web: any
12 | flutter_web_ui: any
13 |
14 | dev_dependencies:
15 | # Enables the `pub run build_runner` command
16 | build_runner: ^1.6.5
17 |
18 | # Includes the JavaScript compilers
19 | build_web_compilers: ^2.1.5
20 |
21 | # The Font Awesome Icon pack available as Flutter Icons.
22 | font_awesome: any
23 |
24 | # font_awesome_flutter: ^8.5.0
25 |
26 | # flutter_web packages are not published to pub.dartlang.org
27 | # These overrides tell the package tools to get them from GitHub
28 | dependency_overrides:
29 | flutter_web:
30 | git:
31 | url: https://github.com/flutter/flutter_web
32 | path: packages/flutter_web
33 | flutter_web_ui:
34 | git:
35 | url: https://github.com/flutter/flutter_web
36 | path: packages/flutter_web_ui
37 |
38 | flutter:
39 | uses-material-design: true
40 |
--------------------------------------------------------------------------------
/screenshots/portfolio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/screenshots/portfolio.png
--------------------------------------------------------------------------------
/web/assets/FontManifest.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "fonts": [
4 | {
5 | "asset": "fonts/MaterialIcons-Regular.ttf"
6 | }
7 | ],
8 | "family": "MaterialIcons"
9 | },
10 | {
11 | "fonts": [
12 | {
13 | "asset": "fonts/Quicksand-Regular.otf"
14 | }
15 | ],
16 | "family": "Quicksand"
17 | },
18 | {
19 | "fonts": [
20 | {
21 | "asset": "fonts/Product-Sans-Regular.ttf"
22 | }
23 | ],
24 | "family": "ProductSans"
25 | },
26 | {
27 | "fonts": [
28 | {
29 | "asset": "fonts/Nexa-Bold.otf"
30 | }
31 | ],
32 | "family": "NexaBold"
33 | },
34 | {
35 | "fonts": [
36 | {
37 | "asset": "fonts/Nexa-Light.otf"
38 | }
39 | ],
40 | "family": "NexaLight"
41 | }
42 | ]
--------------------------------------------------------------------------------
/web/assets/fonts/MaterialIcons-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/fonts/MaterialIcons-Regular.ttf
--------------------------------------------------------------------------------
/web/assets/fonts/Nexa-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/fonts/Nexa-Bold.otf
--------------------------------------------------------------------------------
/web/assets/fonts/Nexa-Light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/fonts/Nexa-Light.otf
--------------------------------------------------------------------------------
/web/assets/fonts/Product-Sans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/fonts/Product-Sans-Regular.ttf
--------------------------------------------------------------------------------
/web/assets/fonts/Quicksand-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/fonts/Quicksand-Regular.otf
--------------------------------------------------------------------------------
/web/assets/icons/ic_dribbble.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/icons/ic_dribbble.png
--------------------------------------------------------------------------------
/web/assets/icons/ic_evernote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/icons/ic_evernote.png
--------------------------------------------------------------------------------
/web/assets/icons/ic_google.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/icons/ic_google.png
--------------------------------------------------------------------------------
/web/assets/icons/ic_linkedIn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/icons/ic_linkedIn.png
--------------------------------------------------------------------------------
/web/assets/icons/ic_twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/icons/ic_twitter.png
--------------------------------------------------------------------------------
/web/assets/images/programmer-3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/assets/images/programmer-3.gif
--------------------------------------------------------------------------------
/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ezin-rev/portfolio-flutter/9fb3d9728e65745c99d48e94ec2e844ca7a05f5e/web/favicon.ico
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Portfolio
6 |
22 |
66 |
67 |
68 |
69 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/web/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:portfolio/main.dart' as app;
2 | import 'package:flutter_web_ui/ui.dart' as ui;
3 |
4 | main() async {
5 | await ui.webOnlyInitializePlatform();
6 | app.main();
7 | }
8 |
--------------------------------------------------------------------------------