From 4437d31dcb5352ece76598f32b64e9e07f8c1b96 Mon Sep 17 00:00:00 2001 From: shahad-97 Date: Sat, 25 Oct 2025 16:40:56 +0300 Subject: [PATCH 1/9] feature: add current weather card --- lib/ui/components/current_weather_card.dart | 95 +++++++++++++++++++++ lib/ui/components/max_min_temp_card.dart | 44 ++++++++++ lib/ui/screen/weather_screen.dart | 30 +++++-- lib/ui/widgets/glassmorphism_container.dart | 44 ++++++++++ 4 files changed, 206 insertions(+), 7 deletions(-) create mode 100644 lib/ui/components/current_weather_card.dart create mode 100644 lib/ui/components/max_min_temp_card.dart create mode 100644 lib/ui/widgets/glassmorphism_container.dart diff --git a/lib/ui/components/current_weather_card.dart b/lib/ui/components/current_weather_card.dart new file mode 100644 index 0000000..fe4dfd2 --- /dev/null +++ b/lib/ui/components/current_weather_card.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import '../widgets/glassmorphism_container.dart'; +import 'max_min_temp_card.dart'; +import '../cubit/theme/theme_cubit.dart'; +import 'package:weather_app/ui/theme/font_families.dart'; + +class CurrentWeatherCard extends StatelessWidget { + const CurrentWeatherCard({super.key}); + + final String location = 'Baghdad'; + final String temperature = '24'; + final String unit = '°C'; + final String description = 'Snow'; + final String highTemp = '32'; + final String lowTemp = '20'; + + @override + Widget build(BuildContext context) { + final theme = context.watch().state; + final iconColor = (theme.brightness == Brightness.light) + ? const Color.fromARGB(255, 12, 57, 133) + : theme.colors.onPrimary; + + return GlassmorphismContainer( + width: 350, + height: 550, + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.location_on, size: 24, color: theme.colors.text87), + const SizedBox(width: 8), + Text( + location, + style: TextStyle( + fontFamily: urbanist, + fontSize: 22, fontWeight: FontWeight.bold, color: theme.colors.text87), + ), + ], + ), + + Container( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: theme.colors.primary.withOpacity(0.4), + blurRadius: 150.0, + spreadRadius: 1.0, + offset: const Offset(0, 0), + blurStyle: BlurStyle.normal + ), + ], + ), + child: Icon( + Icons.ac_unit, + size: 150, + color: iconColor, + ), + ), + + Text( + '$temperature$unit', + style: TextStyle( + fontFamily: urbanist, + fontSize: 90, + fontWeight: FontWeight.w200, + color: theme.colors.text, + ), + ), + + Text( + description, + style: TextStyle( + fontFamily: urbanist, + fontSize: 30, + fontWeight: FontWeight.w400, + color: theme.colors.text60, + ), + ), + + Divider(color: theme.colors.border, thickness: 1.0, indent: 40, endIndent: 40), + + MaxMinTempCard(highTemp: highTemp, lowTemp: lowTemp, unit: unit), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/ui/components/max_min_temp_card.dart b/lib/ui/components/max_min_temp_card.dart new file mode 100644 index 0000000..b852b6a --- /dev/null +++ b/lib/ui/components/max_min_temp_card.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import '../cubit/theme/theme_cubit.dart'; +import 'package:weather_app/ui/theme/font_families.dart'; + +class MaxMinTempCard extends StatelessWidget { + final String highTemp; + final String lowTemp; + final String unit; + + const MaxMinTempCard({ + super.key, + required this.highTemp, + required this.lowTemp, + required this.unit, + }); + + @override + Widget build(BuildContext context) { + final theme = context.watch().state; + + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '↑ $highTemp$unit', + style: TextStyle( + fontFamily: urbanist, + fontSize: 20, + color: theme.colors.text87, + fontWeight: FontWeight.bold), + ), + const SizedBox(width: 15), + Text( + '↓ $lowTemp$unit', + style: TextStyle( + fontFamily: urbanist, + fontSize: 20, + color: theme.colors.text60), + ), + ], + ); + } +} \ No newline at end of file diff --git a/lib/ui/screen/weather_screen.dart b/lib/ui/screen/weather_screen.dart index 4b8be93..458b97f 100644 --- a/lib/ui/screen/weather_screen.dart +++ b/lib/ui/screen/weather_screen.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import '../components/current_weather_card.dart'; import '../cubit/theme/theme_cubit.dart'; class WeatherScreen extends StatelessWidget { @@ -8,13 +9,28 @@ class WeatherScreen extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch().state; - return Scaffold( - body: Center( - child: Text( - 'Welcome to Weather App', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, + + return Theme( + data: theme.themeData, + child: Scaffold( + backgroundColor: Colors.transparent, + body: Container( + decoration: BoxDecoration( + gradient: theme.colors.backgroundGradient, + ), + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 40.0, horizontal: 12.0), + child: Column( + children: [ + const CurrentWeatherCard( + ), + + const SizedBox(height: 24), + + ], + ), + ), ), ), ), diff --git a/lib/ui/widgets/glassmorphism_container.dart b/lib/ui/widgets/glassmorphism_container.dart new file mode 100644 index 0000000..2cf3fef --- /dev/null +++ b/lib/ui/widgets/glassmorphism_container.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'dart:ui'; + +class GlassmorphismContainer extends StatelessWidget { + final Widget child; + final double blur; + final double opacity; + final double borderRadius; + final double? width; + final double? height; + + const GlassmorphismContainer({ + super.key, + required this.child, + this.blur = 10.0, + this.opacity = 0.15, + this.borderRadius = 30.0, + this.width, + this.height, + }); + + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: BorderRadius.circular(borderRadius), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur), + child: Container( + width: width, + height: height, + decoration: BoxDecoration( + color: Colors.white.withOpacity(opacity), + borderRadius: BorderRadius.circular(borderRadius), + border: Border.all( + color: Colors.white.withOpacity(0.3), + width: 1.5, + ), + ), + child: child, + ), + ), + ); + } +} \ No newline at end of file From 6fa5a7be3dfd00b7dafcfeefb1ec10cf0bff0f97 Mon Sep 17 00:00:00 2001 From: AhmadKharfan Date: Sat, 25 Oct 2025 20:42:55 +0000 Subject: [PATCH 2/9] add daily weather colors --- lib/ui/theme/app_colors.dart | 20 ++++++++++++++++++++ lib/ui/theme/app_colors_day.dart | 30 ++++++++++++++++++++++++++++++ lib/ui/theme/app_colors_night.dart | 30 ++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/lib/ui/theme/app_colors.dart b/lib/ui/theme/app_colors.dart index fd2d752..3c0c5df 100644 --- a/lib/ui/theme/app_colors.dart +++ b/lib/ui/theme/app_colors.dart @@ -28,4 +28,24 @@ abstract class AppColors { ); Color get border; + + Color get weatherIconColor; + + Color get glassmorphismBackground; + + Color get glassmorphismBorder; + + Color get cardShadow; + + Color get temperatureColor; + + Color get statusColor; + + Color get locationColor; + + Color get maxMinCardBackground; + + Color get maxMinDividerColor; + + Color get maxMinTextColor; } diff --git a/lib/ui/theme/app_colors_day.dart b/lib/ui/theme/app_colors_day.dart index a0f1f28..6b8a9ca 100644 --- a/lib/ui/theme/app_colors_day.dart +++ b/lib/ui/theme/app_colors_day.dart @@ -34,4 +34,34 @@ class DayAppColors extends AppColors { @override Color get border => const Color(0x14060414); + + @override + Color get weatherIconColor => const Color(0xFF00619D); + + @override + Color get glassmorphismBackground => const Color(0x33FFFFFF); + + @override + Color get glassmorphismBorder => const Color(0x4DFFFFFF); + + @override + Color get cardShadow => const Color(0x1A000000); + + @override + Color get temperatureColor => const Color(0xFF060414); + + @override + Color get statusColor => const Color(0x99060414); + + @override + Color get locationColor => const Color(0xFF323232); + + @override + Color get maxMinCardBackground => const Color(0x14060414); + + @override + Color get maxMinDividerColor => const Color(0x99060414); + + @override + Color get maxMinTextColor => const Color(0x99060414); } diff --git a/lib/ui/theme/app_colors_night.dart b/lib/ui/theme/app_colors_night.dart index 2751d5e..f76a6c1 100644 --- a/lib/ui/theme/app_colors_night.dart +++ b/lib/ui/theme/app_colors_night.dart @@ -34,4 +34,34 @@ class NightAppColors extends AppColors { @override Color get border => const Color(0x14FFFFFF); + + @override + Color get weatherIconColor => const Color(0xFFC0B7FF); + + @override + Color get glassmorphismBackground => const Color(0x33000000); + + @override + Color get glassmorphismBorder => const Color(0x1AFFFFFF); + + @override + Color get cardShadow => const Color(0x4D000000); + + @override + Color get temperatureColor => const Color(0xFFFFFFFF); + + @override + Color get statusColor => const Color(0x99FFFFFF); + + @override + Color get locationColor => const Color(0xFFFFFFFF); + + @override + Color get maxMinCardBackground => const Color(0x14FFFFFF); + + @override + Color get maxMinDividerColor => const Color(0xDEFFFFFF); + + @override + Color get maxMinTextColor => const Color(0xDEFFFFFF); } From 27c4fe7bf7ed78ffefab3720056424a3c96eff34 Mon Sep 17 00:00:00 2001 From: AhmadKharfan Date: Sat, 25 Oct 2025 20:43:18 +0000 Subject: [PATCH 3/9] use font family from new file --- lib/ui/theme/app_theme.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ui/theme/app_theme.dart b/lib/ui/theme/app_theme.dart index 6724cf9..5c9b825 100644 --- a/lib/ui/theme/app_theme.dart +++ b/lib/ui/theme/app_theme.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:weather_app/gen/fonts.gen.dart'; import 'package:weather_app/ui/theme/app_colors.dart'; +import 'package:weather_app/ui/theme/font_families.dart'; abstract class AppTheme { final Brightness brightness; @@ -10,7 +10,7 @@ abstract class AppTheme { ThemeData get themeData { return ThemeData( - fontFamily: FontFamily.urbanist, + fontFamily: urbanist, brightness: brightness, primaryColor: colors.primary, colorScheme: ColorScheme.fromSeed( From 42ba568278138416bf5aaefeac1197d81fcebe31 Mon Sep 17 00:00:00 2001 From: AhmadKharfan Date: Sat, 25 Oct 2025 20:43:52 +0000 Subject: [PATCH 4/9] use asset paths directly --- lib/ui/components/daily_weather.dart | 5 ++--- lib/ui/components/location_row.dart | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ui/components/daily_weather.dart b/lib/ui/components/daily_weather.dart index 3ec6fc7..a11feab 100644 --- a/lib/ui/components/daily_weather.dart +++ b/lib/ui/components/daily_weather.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:weather_app/ui/model/daily_weather.dart'; -import '../../gen/assets.gen.dart'; import '../cubit/theme/theme_cubit.dart'; class NextDaysWeatherForecastTable extends StatelessWidget { @@ -81,7 +80,7 @@ class _DailyWeatherDetails extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ _TempDisplay( - icon: Assets.images.arrowUp.path, + icon: 'assets/images/arrow_up.svg', text: '${dailyWeather.maxTemperature}°C', ), @@ -97,7 +96,7 @@ class _DailyWeatherDetails extends StatelessWidget { ), _TempDisplay( - icon: Assets.images.arrowDown.path, + icon: 'assets/images/arrow_down.svg', text: '${dailyWeather.minTemperature}°C', ), ], diff --git a/lib/ui/components/location_row.dart b/lib/ui/components/location_row.dart index 7d0cc92..8f16175 100644 --- a/lib/ui/components/location_row.dart +++ b/lib/ui/components/location_row.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../../gen/assets.gen.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import '../cubit/theme/theme_cubit.dart'; class LocationRow extends StatelessWidget { @@ -14,7 +14,8 @@ class LocationRow extends StatelessWidget { crossAxisAlignment: WrapCrossAlignment.center, spacing: 4, children: [ - Assets.images.location.svg( + SvgPicture.asset( + 'assets/images/location.svg', colorFilter: ColorFilter.mode(theme.colors.text, BlendMode.srcIn), ), Text( From e2675e6db2c0437bdd7d923677667106a2705cb2 Mon Sep 17 00:00:00 2001 From: AhmadKharfan Date: Sat, 25 Oct 2025 20:44:12 +0000 Subject: [PATCH 5/9] add current weather data model --- lib/ui/model/current_weather.dart | 46 +++++++++++++++++++++++++++++++ lib/ui/theme/font_families.dart | 1 + 2 files changed, 47 insertions(+) create mode 100644 lib/ui/model/current_weather.dart create mode 100644 lib/ui/theme/font_families.dart diff --git a/lib/ui/model/current_weather.dart b/lib/ui/model/current_weather.dart new file mode 100644 index 0000000..3723ba7 --- /dev/null +++ b/lib/ui/model/current_weather.dart @@ -0,0 +1,46 @@ +class CurrentWeather { + final String image; + final String temperature; + final String status; + final String highTemp; + final String lowTemp; + final String unit; + + const CurrentWeather({ + required this.image, + required this.temperature, + required this.status, + required this.highTemp, + required this.lowTemp, + this.unit = '°C', + }); + + factory CurrentWeather.sample() { + return const CurrentWeather( + image: 'assets/images/day_mainly_clear.png', + temperature: '24', + status: 'Partly cloudy', + highTemp: '32', + lowTemp: '20', + unit: '°C', + ); + } + + CurrentWeather copyWith({ + String? image, + String? temperature, + String? status, + String? highTemp, + String? lowTemp, + String? unit, + }) { + return CurrentWeather( + image: image ?? this.image, + temperature: temperature ?? this.temperature, + status: status ?? this.status, + highTemp: highTemp ?? this.highTemp, + lowTemp: lowTemp ?? this.lowTemp, + unit: unit ?? this.unit, + ); + } +} \ No newline at end of file diff --git a/lib/ui/theme/font_families.dart b/lib/ui/theme/font_families.dart new file mode 100644 index 0000000..6edd670 --- /dev/null +++ b/lib/ui/theme/font_families.dart @@ -0,0 +1 @@ +const String urbanist = 'Urbanist'; \ No newline at end of file From 92f42d896ab0c17b20a76b36ccdcd6a1206f5cf7 Mon Sep 17 00:00:00 2001 From: AhmadKharfan Date: Sat, 25 Oct 2025 20:44:28 +0000 Subject: [PATCH 6/9] update current weather card styles and structure --- lib/ui/components/current_weather_card.dart | 175 ++++++++++++-------- 1 file changed, 104 insertions(+), 71 deletions(-) diff --git a/lib/ui/components/current_weather_card.dart b/lib/ui/components/current_weather_card.dart index fe4dfd2..231c0d3 100644 --- a/lib/ui/components/current_weather_card.dart +++ b/lib/ui/components/current_weather_card.dart @@ -1,94 +1,127 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../widgets/glassmorphism_container.dart'; import 'max_min_temp_card.dart'; import '../cubit/theme/theme_cubit.dart'; import 'package:weather_app/ui/theme/font_families.dart'; +import '../model/current_weather.dart'; class CurrentWeatherCard extends StatelessWidget { - const CurrentWeatherCard({super.key}); + final CurrentWeather currentWeather; - final String location = 'Baghdad'; - final String temperature = '24'; - final String unit = '°C'; - final String description = 'Snow'; - final String highTemp = '32'; - final String lowTemp = '20'; + const CurrentWeatherCard({ + super.key, + required this.currentWeather, + }); @override Widget build(BuildContext context) { - final theme = context.watch().state; - final iconColor = (theme.brightness == Brightness.light) - ? const Color.fromARGB(255, 12, 57, 133) - : theme.colors.onPrimary; + final theme = context + .watch() + .state; - return GlassmorphismContainer( - width: 350, - height: 550, - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.location_on, size: 24, color: theme.colors.text87), - const SizedBox(width: 8), - Text( - location, - style: TextStyle( - fontFamily: urbanist, - fontSize: 22, fontWeight: FontWeight.bold, color: theme.colors.text87), + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: 250, + height: 250, + child: Stack( + clipBehavior: Clip.none, + alignment: Alignment.center, + children: [ + Positioned( + left: -15, + top: 5, + child: Container( + width: 250, + height: 250, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: RadialGradient( + colors: [ + Color.fromRGBO( + theme.colors.weatherIconColor.red, + theme.colors.weatherIconColor.green, + theme.colors.weatherIconColor.blue, + 0.25, + ), + Color.fromRGBO( + theme.colors.weatherIconColor.red, + theme.colors.weatherIconColor.green, + theme.colors.weatherIconColor.blue, + 0.08, + ), + Colors.transparent, + ], + stops: const [0.0, 0.3, 1.0], + ), + boxShadow: [ + BoxShadow( + color: Color.fromRGBO( + theme.colors.weatherIconColor.red, + theme.colors.weatherIconColor.green, + theme.colors.weatherIconColor.blue, + 0.2, + ), + blurRadius: 70, + spreadRadius: 5, + offset: const Offset(-5, 5), + ), + ], + ), + ), ), - ], - ), - - Container( - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: theme.colors.primary.withOpacity(0.4), - blurRadius: 150.0, - spreadRadius: 1.0, - offset: const Offset(0, 0), - blurStyle: BlurStyle.normal + Positioned( + top: 5, + child: SizedBox( + width: 220, + height: 200, + child: Image.asset( + currentWeather.image, + width: 220, + height: 200, + fit: BoxFit.contain, + ), ), - ], - ), - child: Icon( - Icons.ac_unit, - size: 150, - color: iconColor, - ), + ), + ], ), + ), - Text( - '$temperature$unit', - style: TextStyle( - fontFamily: urbanist, - fontSize: 90, - fontWeight: FontWeight.w200, - color: theme.colors.text, - ), + Text( + '${currentWeather.temperature}${currentWeather.unit}', + style: TextStyle( + fontFamily: urbanist, + fontSize: 64, + fontWeight: FontWeight.w600, + letterSpacing: 0.25, + color: theme.colors.temperatureColor, + height: 1.0, ), + ), - Text( - description, - style: TextStyle( - fontFamily: urbanist, - fontSize: 30, - fontWeight: FontWeight.w400, - color: theme.colors.text60, - ), + Text( + currentWeather.status, + style: TextStyle( + fontFamily: urbanist, + fontSize: 16, + fontWeight: FontWeight.w500, + letterSpacing: 0.25, + color: theme.colors.statusColor, + height: 1.0, ), + ), + const SizedBox(height: 12), - Divider(color: theme.colors.border, thickness: 1.0, indent: 40, endIndent: 40), - - MaxMinTempCard(highTemp: highTemp, lowTemp: lowTemp, unit: unit), - ], - ), + MaxMinTempCard( + highTemp: currentWeather.highTemp, + lowTemp: currentWeather.lowTemp, + unit: currentWeather.unit, + ), + ], ), ); } From 280e065df327b5ad81b17610a77ca808d63deb32 Mon Sep 17 00:00:00 2001 From: AhmadKharfan Date: Sat, 25 Oct 2025 20:44:41 +0000 Subject: [PATCH 7/9] add more styling options to `GlassmorphismContainer` --- lib/ui/widgets/glassmorphism_container.dart | 40 +++++++++++++-------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/lib/ui/widgets/glassmorphism_container.dart b/lib/ui/widgets/glassmorphism_container.dart index 2cf3fef..6f9f072 100644 --- a/lib/ui/widgets/glassmorphism_container.dart +++ b/lib/ui/widgets/glassmorphism_container.dart @@ -8,6 +8,9 @@ class GlassmorphismContainer extends StatelessWidget { final double borderRadius; final double? width; final double? height; + final Color? backgroundColor; + final Color? borderColor; + final List? shadows; const GlassmorphismContainer({ super.key, @@ -17,26 +20,35 @@ class GlassmorphismContainer extends StatelessWidget { this.borderRadius = 30.0, this.width, this.height, + this.backgroundColor, + this.borderColor, + this.shadows, }); @override Widget build(BuildContext context) { - return ClipRRect( - borderRadius: BorderRadius.circular(borderRadius), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur), - child: Container( - width: width, - height: height, - decoration: BoxDecoration( - color: Colors.white.withOpacity(opacity), - borderRadius: BorderRadius.circular(borderRadius), - border: Border.all( - color: Colors.white.withOpacity(0.3), - width: 1.5, + final effectiveBackgroundColor = backgroundColor ?? Colors.white.withOpacity(opacity); + final effectiveBorderColor = borderColor ?? Colors.white.withOpacity(0.3); + + return Container( + width: width, + height: height, + child: ClipRRect( + borderRadius: BorderRadius.circular(borderRadius), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur), + child: Container( + decoration: BoxDecoration( + color: effectiveBackgroundColor, + borderRadius: BorderRadius.circular(borderRadius), + border: Border.all( + color: effectiveBorderColor, + width: 1.5, + ), + boxShadow: shadows, ), + child: child, ), - child: child, ), ), ); From 55f0bd6ab4c81df52c56f54299d0151393dbbe74 Mon Sep 17 00:00:00 2001 From: AhmadKharfan Date: Sat, 25 Oct 2025 20:44:50 +0000 Subject: [PATCH 8/9] update max/min temperature card styles --- lib/ui/components/max_min_temp_card.dart | 90 +++++++++++++++++++----- 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/lib/ui/components/max_min_temp_card.dart b/lib/ui/components/max_min_temp_card.dart index b852b6a..b4fa781 100644 --- a/lib/ui/components/max_min_temp_card.dart +++ b/lib/ui/components/max_min_temp_card.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../cubit/theme/theme_cubit.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:weather_app/ui/theme/font_families.dart'; +import '../cubit/theme/theme_cubit.dart'; class MaxMinTempCard extends StatelessWidget { final String highTemp; @@ -19,26 +20,77 @@ class MaxMinTempCard extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch().state; - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '↑ $highTemp$unit', - style: TextStyle( + return Container( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8), + decoration: BoxDecoration( + color: theme.colors.maxMinCardBackground, + borderRadius: BorderRadius.circular(100), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 12, + height: 12, + child: SvgPicture.asset( + 'assets/images/arrow_up.svg', + width: 12, + height: 12, + colorFilter: ColorFilter.mode( + theme.colors.maxMinTextColor, + BlendMode.srcIn, + ), + ), + ), + const SizedBox(width: 8), + Text( + '$highTemp$unit', + style: TextStyle( fontFamily: urbanist, - fontSize: 20, - color: theme.colors.text87, - fontWeight: FontWeight.bold), - ), - const SizedBox(width: 15), - Text( - '↓ $lowTemp$unit', - style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + letterSpacing: 0.25, + color: theme.colors.maxMinTextColor, + height: 1.0, + ), + ), + const SizedBox(width: 8), + Container( + width: 1, + height: 20, + decoration: BoxDecoration( + color: theme.colors.maxMinDividerColor, + ), + ), + const SizedBox(width: 8), + SizedBox( + width: 12, + height: 12, + child: SvgPicture.asset( + 'assets/images/arrow_down.svg', + width: 12, + height: 12, + colorFilter: ColorFilter.mode( + theme.colors.maxMinTextColor, + BlendMode.srcIn, + ), + ), + ), + const SizedBox(width: 8), + Text( + '$lowTemp$unit', + style: TextStyle( fontFamily: urbanist, - fontSize: 20, - color: theme.colors.text60), - ), - ], + fontSize: 16, + fontWeight: FontWeight.w500, + letterSpacing: 0.25, + color: theme.colors.maxMinTextColor, + height: 1.0, + ), + ), + ], + ), ); } } \ No newline at end of file From df58b9a783c6aa24b75faff3aca5b317c27d5d1c Mon Sep 17 00:00:00 2001 From: AhmadKharfan Date: Sat, 25 Oct 2025 20:45:10 +0000 Subject: [PATCH 9/9] add current weather card to weather screen --- lib/ui/screen/weather_screen.dart | 38 ++++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/lib/ui/screen/weather_screen.dart b/lib/ui/screen/weather_screen.dart index db3bdc9..ec352b9 100644 --- a/lib/ui/screen/weather_screen.dart +++ b/lib/ui/screen/weather_screen.dart @@ -3,14 +3,14 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:weather_app/di/service_locator.dart'; import 'package:weather_app/domain/entity/weather.dart'; import 'package:weather_app/domain/model/location_coordinate.dart'; -import 'package:weather_app/ui/components/daily_weather.dart'; import 'package:weather_app/ui/cubit/location/location_cubit.dart'; import 'package:weather_app/ui/cubit/weather/weather_cubit.dart'; -import 'package:weather_app/ui/model/daily_weather.dart'; -import '../../gen/assets.gen.dart'; + +import '../components/current_weather_card.dart'; import '../components/location_row.dart'; import '../components/weather_details.dart'; import '../cubit/theme/theme_cubit.dart'; +import '../model/current_weather.dart'; import '../model/weather_info.dart'; class WeatherScreen extends StatelessWidget { @@ -44,7 +44,9 @@ class WeatherScreen extends StatelessWidget { child: BlocConsumer( listener: (context, state) { if (state is WeatherLoaded) { - context.read().updateTheme(state.weather.isDaytime); + context.read().updateTheme( + state.weather.isDaytime, + ); } }, builder: (context, state) { @@ -57,7 +59,7 @@ class WeatherScreen extends StatelessWidget { WeatherError() => _CustomLoading(), }; }, - ) + ), ), ), ), @@ -66,9 +68,7 @@ class WeatherScreen extends StatelessWidget { } class _CustomLoading extends StatelessWidget { - const _CustomLoading({ - super.key, - }); + const _CustomLoading({super.key}); @override Widget build(BuildContext context) { @@ -76,8 +76,6 @@ class _CustomLoading extends StatelessWidget { } } - - class _WeatherScreenContent extends StatelessWidget { final Weather weather; @@ -99,38 +97,46 @@ class _WeatherScreenContent extends StatelessWidget { child: LocationRow(), ), ), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: CurrentWeatherCard( + currentWeather: CurrentWeather.sample(), + ), + ), + ), SliverToBoxAdapter( child: WeatherDetails( weatherInfo: [ WeatherInfo( - iconPath: Assets.images.fastWind.path, + iconPath: 'assets/images/fast_wind.svg', value: '${weather.currentDayWeatherStatus.windSpeed.speed.round()} ${weather.currentDayWeatherStatus.windSpeed.unit.name}', label: 'Wind', ), WeatherInfo( - iconPath: Assets.images.humidity.path, + iconPath: 'assets/images/humidity.svg', value: '${weather.currentDayWeatherStatus.humidity.round()}%', label: 'Humidity', ), WeatherInfo( - iconPath: Assets.images.rain.path, + iconPath: 'assets/images/rain.svg', value: '${weather.currentDayWeatherStatus.rain.round()}%', label: 'Rain', ), WeatherInfo( - iconPath: Assets.images.uv.path, + iconPath: 'assets/images/uv.svg', value: '${weather.currentDayWeatherStatus.uvIndex.round()}', label: 'UV Index', ), WeatherInfo( - iconPath: Assets.images.pressure.path, + iconPath: 'assets/images/pressure.svg', value: '${weather.currentDayWeatherStatus.pressure.pressure.round()} ${weather.currentDayWeatherStatus.pressure.unit.name}', label: 'Pressure', ), WeatherInfo( - iconPath: Assets.images.temperature.path, + iconPath: 'assets/images/temperature.svg', value: '${weather.currentDayWeatherStatus.feelsLike.temperature.round()} ${weather.currentDayWeatherStatus.feelsLike.unit.name}', label: 'Feels Like',