diff --git a/lib/components/project_card.dart b/lib/components/project_card.dart new file mode 100644 index 0000000..bcbe5f0 --- /dev/null +++ b/lib/components/project_card.dart @@ -0,0 +1,96 @@ +import 'package:devfolio/constants/theme.dart'; +import 'package:jaspr/jaspr.dart'; + +@client +class ProjectCard extends StatelessComponent { + final String title; + final String description; + final String icon; + final String banner; + final String url; + const ProjectCard({ + super.key, + required this.title, + required this.description, + required this.icon, + required this.banner, + required this.url, + }); + + @override + Iterable build(BuildContext context) sync* { + yield a(href: url, target: Target.blank, classes: 'banner-card', [ + div( + classes: 'banner-image', + styles: Styles.combine([ + Styles.background( + image: ImageStyle.url(banner), + size: BackgroundSize.cover, + ), + ]), + []), + img(src: icon, height: 40), + span(classes: 'service-title', [ + text(title), + ]), + span(classes: 'service-description', [ + text(description), + ]), + ]); + } + + @css + static final List styles = [ + css('.banner-card') + .flexbox( + direction: FlexDirection.column, + alignItems: AlignItems.center, + justifyContent: JustifyContent.center, + ) + .box( + height: 200.px, + width: 350.px, + radius: BorderRadius.circular(12.px), + margin: EdgeInsets.only(top: 25.px, left: 15.px, right: 15.px), + ) + .background( + color: themeGray, + ) + .text( + decoration: TextDecoration.none, + ), + css('.banner-card:hover').box( + shadow: BoxShadow( + color: primaryColor, + offsetX: 0.px, + offsetY: 0.px, + blur: 8.px, + spread: 2.px, + ), + transition: Transition('box-shadow', duration: 500), + cursor: Cursor.pointer, + ), + css('.banner-image').box( + height: 200.px, + width: 350.px, + ), + css('.service-description') + .text( + fontSize: 12.px, + align: TextAlign.center, + ) + .box( + padding: EdgeInsets.symmetric(horizontal: 10.px), + margin: EdgeInsets.only(top: 10.px), + ), + css('.banner-image').box( + opacity: 1.0, + radius: BorderRadius.circular(12.px), + position: Position.absolute(), + ), + css('.banner-image:hover').box( + opacity: 0, + transition: Transition('opacity', duration: 500), + ), + ]; +} diff --git a/lib/components/service_card.dart b/lib/components/service_card.dart index ce81a83..579e224 100644 --- a/lib/components/service_card.dart +++ b/lib/components/service_card.dart @@ -1,6 +1,7 @@ import 'package:devfolio/constants/theme.dart'; import 'package:jaspr/jaspr.dart'; +@client class ServiceCard extends StatelessComponent { final String icon; final String label; diff --git a/lib/jaspr_options.dart b/lib/jaspr_options.dart index 0bacd27..c1fc130 100644 --- a/lib/jaspr_options.dart +++ b/lib/jaspr_options.dart @@ -4,12 +4,14 @@ import 'package:jaspr/jaspr.dart'; import 'package:devfolio/components/app_button.dart' as prefix0; import 'package:devfolio/components/nav_bar.dart' as prefix1; -import 'package:devfolio/components/service_card.dart' as prefix2; -import 'package:devfolio/pages/home.dart' as prefix3; -import 'package:devfolio/sections/about_me.dart' as prefix4; -import 'package:devfolio/sections/basic_info.dart' as prefix5; -import 'package:devfolio/sections/services.dart' as prefix6; -import 'package:devfolio/app.dart' as prefix7; +import 'package:devfolio/components/project_card.dart' as prefix2; +import 'package:devfolio/components/service_card.dart' as prefix3; +import 'package:devfolio/pages/home.dart' as prefix4; +import 'package:devfolio/sections/about_me.dart' as prefix5; +import 'package:devfolio/sections/basic_info.dart' as prefix6; +import 'package:devfolio/sections/projects.dart' as prefix7; +import 'package:devfolio/sections/services.dart' as prefix8; +import 'package:devfolio/app.dart' as prefix9; /// Default [JasprOptions] for use with your jaspr project. /// @@ -29,22 +31,29 @@ import 'package:devfolio/app.dart' as prefix7; /// ``` final defaultJasprOptions = JasprOptions( clients: { - prefix7.App: ClientTarget('app'), + prefix9.App: ClientTarget('app'), prefix0.AppButton: ClientTarget('components/app_button', params: _prefix0AppButton), prefix1.NavBar: ClientTarget('components/nav_bar'), - prefix4.AboutMeSection: ClientTarget('sections/about_me'), + prefix2.ProjectCard: ClientTarget('components/project_card', params: _prefix2ProjectCard), + prefix3.ServiceCard: ClientTarget('components/service_card', params: _prefix3ServiceCard), + prefix5.AboutMeSection: ClientTarget('sections/about_me'), }, styles: () => [ ...prefix0.AppButton.styles, ...prefix1.NavBar.styles, - ...prefix2.ServiceCard.styles, - ...prefix3.Home.styles, - ...prefix4.AboutMeSection.styles, - ...prefix5.BasicInfoSection.styles, - ...prefix6.ServicesSection.styles, - ...prefix7.AppState.styles, + ...prefix2.ProjectCard.styles, + ...prefix3.ServiceCard.styles, + ...prefix4.Home.styles, + ...prefix5.AboutMeSection.styles, + ...prefix6.BasicInfoSection.styles, + ...prefix7.ProjectsSections.styles, + ...prefix8.ServicesSection.styles, + ...prefix9.AppState.styles, ], ); Map _prefix0AppButton(prefix0.AppButton c) => {'label': c.label, 'onPressed': c.onPressed, 'width': c.width, 'height': c.height}; +Map _prefix2ProjectCard(prefix2.ProjectCard c) => + {'title': c.title, 'description': c.description, 'icon': c.icon, 'banner': c.banner, 'url': c.url}; +Map _prefix3ServiceCard(prefix3.ServiceCard c) => {'icon': c.icon, 'label': c.label}; diff --git a/lib/pages/home.dart b/lib/pages/home.dart index bd08546..609b050 100644 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -1,6 +1,7 @@ import 'package:devfolio/components/nav_bar.dart'; import 'package:devfolio/sections/about_me.dart'; import 'package:devfolio/sections/basic_info.dart'; +import 'package:devfolio/sections/projects.dart'; import 'package:devfolio/sections/services.dart'; import 'package:jaspr/jaspr.dart'; @@ -14,6 +15,7 @@ class Home extends StatelessComponent { BasicInfoSection(), AboutMeSection(), ServicesSection(), + ProjectsSections(), ]); } diff --git a/lib/sections/projects.dart b/lib/sections/projects.dart new file mode 100644 index 0000000..d1610cb --- /dev/null +++ b/lib/sections/projects.dart @@ -0,0 +1,107 @@ +import 'package:devfolio/components/app_button.dart'; +import 'package:devfolio/components/project_card.dart'; +import 'package:devfolio/utils/assets.dart'; +import 'package:jaspr/jaspr.dart'; + +class ProjectsSections extends StatelessComponent { + const ProjectsSections({super.key}); + + @override + Iterable build(BuildContext context) sync* { + final List> projects = [ + { + 'banner': StaticAssets.snackbar, + 'icon': StaticAssets.flutter, + 'title': 'Awesome Snackbar', + 'description': + "A very unique dart package to uplift the snackbar experience in flutter. Available at pub.dev now!", + 'link': 'https://pub.dev/packages/awesome_snackbar', + }, + { + 'banner': StaticAssets.quranB, + 'icon': StaticAssets.quran, + 'title': 'Quran App', + 'description': + "Application of Holy book of Muslims, Al-Qur'an. Developed using Flutter. Powered with live RestAPI given in README.md", + 'link': 'https://github.com/mhmzdev/the-holy-quran-app', + }, + { + 'banner': StaticAssets.medkitB, + 'icon': StaticAssets.medkit, + 'title': 'MedKit', + 'description': + "A Phramacy app developed using Flutter powered with Firebase as database with Doctor and Patient panels.", + 'link': "https://github.com/mhmzdev/MedKit-Pharmacy-App-Using-Flutter", + }, + { + 'banner': StaticAssets.hereiamB, + 'icon': StaticAssets.hereiam, + 'title': 'Here I Am', + 'description': + "Here I am is an Alert app that Sends alert SMS holding your location (Address and Google Maps) to your loved ones.", + 'link': "https://github.com/mhmzdev/Here-I-Am-Alert-App", + }, + { + 'banner': StaticAssets.covidB, + 'icon': StaticAssets.covid, + 'title': 'Covid-19 Tracker', + 'description': + "A live trakcer for COVID19 stats across the Globe and my Home country Pakistan. It uses APIs so the data is live.", + 'link': "https://github.com/mhmzdev/Covid19-Tracker-App", + }, + ]; + + yield section(classes: 'projects-section', [ + span(classes: 'title', [ + text('Portfolio'), + ]), + span(classes: 'subtitle', [ + text("Here are few samples of my work :)"), + ]), + div(classes: 'section-body-projects', id: 'projects', [ + for (final project in projects) + ProjectCard( + banner: project['banner'], + icon: project['icon'], + title: project['title'], + description: project['description'], + url: project['link'], + ), + ]), + div(styles: Styles.box(height: 45.px), []), + AppButton( + label: 'See more', + onPressed: () {}, + ), + ]); + } + + @css + static final List styles = [ + css('.projects-section') + .flexbox( + direction: FlexDirection.column, + alignItems: AlignItems.center, + justifyContent: JustifyContent.start, + ) + .box( + padding: EdgeInsets.symmetric(vertical: 5.vh, horizontal: 10.vw), + ), + css('.title').text( + fontFamily: FontFamily('Montserrat'), + fontWeight: FontWeight.w100, + fontSize: 40.px, + ), + css('.section-body-projects') + .flexbox( + direction: FlexDirection.row, + alignItems: AlignItems.center, + justifyContent: JustifyContent.center, + wrap: FlexWrap.wrap, + ) + .box( + margin: EdgeInsets.only(top: 50.px), + width: 100.percent, + ), + ]; +} diff --git a/lib/utils/assets.dart b/lib/utils/assets.dart index 0158f5a..c93dab4 100644 --- a/lib/utils/assets.dart +++ b/lib/utils/assets.dart @@ -1,9 +1,6 @@ abstract class StaticAssets { static const String waveGif = '/images/hi.gif'; - /// Icons (SVG) - static const String playIcon = '/icons/play-solid.svg'; - /// Profile Images /// Three variants are required /// 1. Black and white @@ -28,4 +25,17 @@ abstract class StaticAssets { static const String dsc = '/images/work/dsc.png'; static const String flutterisl = '/images/work/flutterIsl.png'; static const String st = '/images/work/st.png'; + + /// Projects Images + static const String covid = '/images/projects/covid.png'; + static const String covidB = '/images/projects/covidB.png'; + static const String devfolio = '/images/projects/devfolio.png'; + static const String snackbar = '/images/projects/snackbar.png'; + static const String quran = '/images/projects/quran.png'; + static const String quranB = '/images/projects/quranB.png'; + static const String medkit = '/images/projects/medkit.png'; + static const String medkitB = '/images/projects/medkitB.png'; + static const String hereiam = '/images/projects/hereiam.png'; + static const String hereiamB = '/images/projects/hereiamB.png'; + static const String flutter = '/images/projects/flutter.png'; }