From de6250794daffee9f422b68577cd65e8c1a8b55f Mon Sep 17 00:00:00 2001 From: Shrouk Mohamed <96442266+ShroukMohamed16@users.noreply.github.com> Date: Sat, 25 Oct 2025 02:46:25 +0300 Subject: [PATCH 1/5] feature: implement weakly weather ui --- lib/ui/components/daily_weather.dart | 135 +++++++++++++++++++++++++++ lib/ui/model/daily_weather.dart | 13 +++ lib/ui/theme/app_colors.dart | 1 + 3 files changed, 149 insertions(+) create mode 100644 lib/ui/components/daily_weather.dart create mode 100644 lib/ui/model/daily_weather.dart diff --git a/lib/ui/components/daily_weather.dart b/lib/ui/components/daily_weather.dart new file mode 100644 index 0000000..a124a9e --- /dev/null +++ b/lib/ui/components/daily_weather.dart @@ -0,0 +1,135 @@ +import 'package:flutter/material.dart'; +import 'package:weather_app/ui/model/daily_weather.dart'; +import '../theme/app_colors.dart'; + +class WeaklyWeatherForecastPage extends StatelessWidget { + final List dailyWeatherList; + const WeaklyWeatherForecastPage({super.key, required this.dailyWeatherList}); + + @override + Widget build(BuildContext context) { + return Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(24), + side: const BorderSide(color: AppColors.dayBorder, width: 1), + ), + clipBehavior: Clip.antiAlias, + child: Container( + color: AppColors.dayBackground, + child: ListView.separated( + padding: EdgeInsets.zero, + shrinkWrap: true, + + itemCount: dailyWeatherList.length, + + itemBuilder: (context, index) { + return DailyWeatherDetails(dailyWeather: dailyWeatherList[index]); + }, + + separatorBuilder: (context, index) { + return const Divider( + height: 1, + thickness: 1, + color: AppColors.dayBorder, + ); + }, + ), + ), + ); + } +} + +class DailyWeatherDetails extends StatelessWidget { + final DailyWeatherInfo dailyWeather; + + const DailyWeatherDetails({super.key, required this.dailyWeather}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0), + child: Row( + children: [ + Expanded( + child: Container( + alignment: Alignment.centerLeft, + child: Text( + dailyWeather.dayOfWeek, + textAlign: TextAlign.start, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: AppColors.dayText60, + ), + ), + ), + ), + + Expanded( + child: Center( + child: Image.asset(dailyWeather.iconPath, width: 32, height: 32), + ), + ), + + Expanded( + child: Row( + + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + _TempDisplay( + icon: Icons.arrow_upward, + text: '${dailyWeather.maxTemperature}°C', + ), + + const Padding( + padding: EdgeInsets.symmetric(horizontal: 4.0), + child: Text( + '|', + style: TextStyle( + color: AppColors.daySeparator, + fontWeight: FontWeight.w100, + ), + ), + ), + + _TempDisplay( + icon: Icons.arrow_downward, + text: '${dailyWeather.minTemperature}°C', + ), + + ], + ), + ), + ], + ), + ); + } +} + +class _TempDisplay extends StatelessWidget { + final IconData icon; + final String text; + + const _TempDisplay({required this.icon, required this.text}); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Icon(icon, size: 12, color: AppColors.dayText87), + const SizedBox(width: 2.5), + Text( + text, + style: TextStyle( + fontSize: 14, + color: AppColors.dayText87, + fontWeight: FontWeight.w500, + letterSpacing: 0.25, + ), + ), + ], + ); + } +} diff --git a/lib/ui/model/daily_weather.dart b/lib/ui/model/daily_weather.dart new file mode 100644 index 0000000..a268d7a --- /dev/null +++ b/lib/ui/model/daily_weather.dart @@ -0,0 +1,13 @@ +class DailyWeatherInfo { + final String iconPath; + final int maxTemperature; + final int minTemperature; + final String dayOfWeek; + + const DailyWeatherInfo({ + required this.iconPath, + required this.maxTemperature, + required this.minTemperature, + required this.dayOfWeek, + }); +} \ No newline at end of file diff --git a/lib/ui/theme/app_colors.dart b/lib/ui/theme/app_colors.dart index d199096..5ea7886 100644 --- a/lib/ui/theme/app_colors.dart +++ b/lib/ui/theme/app_colors.dart @@ -10,6 +10,7 @@ class AppColors { static const Color dayText87 = Color(0xDE000000); static const Color dayBackground = Color(0xB3FFFFFF); static const Color dayElementBackgroundColor = Color(0xFF060414); + static const Color daySeparator = Color(0x3D060414); static const Color dayBackgroundStart = Color(0xFF87CEFA); static const Color dayBackgroundEnd = Color(0xFFFFFFFF); static const Color dayBorder = Color(0x14060414); From 70c7e5f0bd00108ceddc4fdc8005154dd5f63239 Mon Sep 17 00:00:00 2001 From: Shrouk Mohamed <96442266+ShroukMohamed16@users.noreply.github.com> Date: Sat, 25 Oct 2025 14:47:00 +0300 Subject: [PATCH 2/5] refactor : solve ui issues --- lib/ui/components/daily_weather.dart | 155 ++++++++++++++------------- 1 file changed, 81 insertions(+), 74 deletions(-) diff --git a/lib/ui/components/daily_weather.dart b/lib/ui/components/daily_weather.dart index a124a9e..20c9d33 100644 --- a/lib/ui/components/daily_weather.dart +++ b/lib/ui/components/daily_weather.dart @@ -1,115 +1,117 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:weather_app/ui/model/daily_weather.dart'; +import 'package:weather_app/ui/theme/font_families.dart'; import '../theme/app_colors.dart'; -class WeaklyWeatherForecastPage extends StatelessWidget { +class NextDaysWeatherForecastTable extends StatelessWidget { final List dailyWeatherList; - const WeaklyWeatherForecastPage({super.key, required this.dailyWeatherList}); + + const NextDaysWeatherForecastTable ({super.key, required this.dailyWeatherList}); @override Widget build(BuildContext context) { - return Card( - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(24), - side: const BorderSide(color: AppColors.dayBorder, width: 1), - ), - clipBehavior: Clip.antiAlias, - child: Container( + return Container( + decoration: BoxDecoration( color: AppColors.dayBackground, - child: ListView.separated( - padding: EdgeInsets.zero, - shrinkWrap: true, - - itemCount: dailyWeatherList.length, - - itemBuilder: (context, index) { - return DailyWeatherDetails(dailyWeather: dailyWeatherList[index]); - }, - - separatorBuilder: (context, index) { - return const Divider( - height: 1, - thickness: 1, - color: AppColors.dayBorder, - ); - }, - ), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(24), + border: Border.all(color: AppColors.dayBorder, width: 1), + ), + child: ListView.separated( + padding: EdgeInsets.zero, + shrinkWrap: true, + + itemCount: dailyWeatherList.length, + + itemBuilder: (context, index) { + return _DailyWeatherDetails(dailyWeather: dailyWeatherList[index]); + }, + + separatorBuilder: (context, index) { + return const Divider( + height: 1, + thickness: 1, + color: AppColors.dayBorder, + ); + }, ), ); } } -class DailyWeatherDetails extends StatelessWidget { +class _DailyWeatherDetails extends StatelessWidget { final DailyWeatherInfo dailyWeather; - const DailyWeatherDetails({super.key, required this.dailyWeather}); + const _DailyWeatherDetails({required this.dailyWeather}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0), - child: Row( - children: [ - Expanded( - child: Container( - alignment: Alignment.centerLeft, - child: Text( - dailyWeather.dayOfWeek, - textAlign: TextAlign.start, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: AppColors.dayText60, + child: Row( + children: [ + Expanded( + child: Container( + alignment: Alignment.centerLeft, + child: Text( + dailyWeather.dayOfWeek, + textAlign: TextAlign.start, + style: const TextStyle( + fontFamily: urbanist, + fontSize: 16, + fontWeight: FontWeight.w400, + color: AppColors.dayText60, + ), ), ), ), - ), - Expanded( - child: Center( - child: Image.asset(dailyWeather.iconPath, width: 32, height: 32), + Expanded( + child: Center( + child: Image.asset(dailyWeather.iconPath, height: 32), + ), ), - ), - Expanded( - child: Row( + Expanded( + child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - _TempDisplay( - icon: Icons.arrow_upward, - text: '${dailyWeather.maxTemperature}°C', - ), + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + _TempDisplay( + icon: 'assets/images/arrow_up.svg', + text: '${dailyWeather.maxTemperature}°C', + ), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 4.0), - child: Text( - '|', - style: TextStyle( - color: AppColors.daySeparator, - fontWeight: FontWeight.w100, + const Padding( + padding: EdgeInsets.symmetric(horizontal: 4.0), + child: Text( + '|', + style: TextStyle( + fontFamily: urbanist, + color: AppColors.daySeparator, + fontWeight: FontWeight.w100, + ), ), ), - ), - _TempDisplay( - icon: Icons.arrow_downward, - text: '${dailyWeather.minTemperature}°C', - ), + _TempDisplay( + icon: 'assets/images/arrow_up.svg', + text: '${dailyWeather.minTemperature}°C', + ), - ], + ], + ), ), - ), - ], - ), + ], + ), ); } } class _TempDisplay extends StatelessWidget { - final IconData icon; + final String icon; final String text; const _TempDisplay({required this.icon, required this.text}); @@ -118,11 +120,16 @@ class _TempDisplay extends StatelessWidget { Widget build(BuildContext context) { return Row( children: [ - Icon(icon, size: 12, color: AppColors.dayText87), + SvgPicture.asset(icon, height: 12, colorFilter: ColorFilter.mode( + AppColors.dayText87, + BlendMode.srcIn, + ), + ), const SizedBox(width: 2.5), Text( text, style: TextStyle( + fontFamily: urbanist, fontSize: 14, color: AppColors.dayText87, fontWeight: FontWeight.w500, From c21c7a0e87522fbb1ecf18e7166ada164da30d95 Mon Sep 17 00:00:00 2001 From: Shrouk Mohamed <96442266+ShroukMohamed16@users.noreply.github.com> Date: Sat, 25 Oct 2025 15:16:20 +0300 Subject: [PATCH 3/5] refactor : apply theme to daily weather --- lib/ui/components/daily_weather.dart | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/ui/components/daily_weather.dart b/lib/ui/components/daily_weather.dart index 20c9d33..4d17671 100644 --- a/lib/ui/components/daily_weather.dart +++ b/lib/ui/components/daily_weather.dart @@ -1,8 +1,9 @@ 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 'package:weather_app/ui/theme/font_families.dart'; -import '../theme/app_colors.dart'; +import '../cubit/theme/theme_cubit.dart'; class NextDaysWeatherForecastTable extends StatelessWidget { final List dailyWeatherList; @@ -11,12 +12,14 @@ class NextDaysWeatherForecastTable extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = context.watch().state; + return Container( decoration: BoxDecoration( - color: AppColors.dayBackground, + color: theme.colors.background, shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(24), - border: Border.all(color: AppColors.dayBorder, width: 1), + border: Border.all(color: theme.colors.border, width: 1), ), child: ListView.separated( padding: EdgeInsets.zero, @@ -29,10 +32,10 @@ class NextDaysWeatherForecastTable extends StatelessWidget { }, separatorBuilder: (context, index) { - return const Divider( + return Divider( height: 1, thickness: 1, - color: AppColors.dayBorder, + color: theme.colors.border, ); }, ), @@ -47,6 +50,7 @@ class _DailyWeatherDetails extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = context.watch().state; return Padding( padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0), child: Row( @@ -57,11 +61,11 @@ class _DailyWeatherDetails extends StatelessWidget { child: Text( dailyWeather.dayOfWeek, textAlign: TextAlign.start, - style: const TextStyle( + style: TextStyle( fontFamily: urbanist, fontSize: 16, fontWeight: FontWeight.w400, - color: AppColors.dayText60, + color:theme.colors.text60, ), ), ), @@ -84,13 +88,13 @@ class _DailyWeatherDetails extends StatelessWidget { text: '${dailyWeather.maxTemperature}°C', ), - const Padding( + Padding( padding: EdgeInsets.symmetric(horizontal: 4.0), child: Text( '|', style: TextStyle( fontFamily: urbanist, - color: AppColors.daySeparator, + color: theme.colors.backgroundStart.withAlpha(14), fontWeight: FontWeight.w100, ), ), @@ -118,10 +122,11 @@ class _TempDisplay extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = context.watch().state; return Row( children: [ SvgPicture.asset(icon, height: 12, colorFilter: ColorFilter.mode( - AppColors.dayText87, + theme.colors.text87, BlendMode.srcIn, ), ), @@ -131,7 +136,7 @@ class _TempDisplay extends StatelessWidget { style: TextStyle( fontFamily: urbanist, fontSize: 14, - color: AppColors.dayText87, + color: theme.colors.text87, fontWeight: FontWeight.w500, letterSpacing: 0.25, ), From edc75b649c51850546919e71df10db256dc0c0db Mon Sep 17 00:00:00 2001 From: Shrouk Mohamed <96442266+ShroukMohamed16@users.noreply.github.com> Date: Sat, 25 Oct 2025 15:38:26 +0300 Subject: [PATCH 4/5] fix: solve build issue --- lib/ui/screen/weather_screen.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ui/screen/weather_screen.dart b/lib/ui/screen/weather_screen.dart index 4b8be93..035a362 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 '../cubit/theme/theme_cubit.dart'; class WeatherScreen extends StatelessWidget { @@ -13,6 +14,7 @@ class WeatherScreen extends StatelessWidget { child: Text( 'Welcome to Weather App', style: TextStyle( + color: theme.colors.backgroundStart, fontSize: 24, fontWeight: FontWeight.bold, ), From 9def2e96b8c92c502f5eb5fdc9eb80bf5e7667bd Mon Sep 17 00:00:00 2001 From: Shrouk Mohamed <96442266+ShroukMohamed16@users.noreply.github.com> Date: Sat, 25 Oct 2025 15:52:15 +0300 Subject: [PATCH 5/5] refactor : use Assets.images --- lib/ui/components/daily_weather.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/ui/components/daily_weather.dart b/lib/ui/components/daily_weather.dart index 4d17671..3484bc5 100644 --- a/lib/ui/components/daily_weather.dart +++ b/lib/ui/components/daily_weather.dart @@ -3,6 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:weather_app/ui/model/daily_weather.dart'; import 'package:weather_app/ui/theme/font_families.dart'; + +import '../../gen/assets.gen.dart'; import '../cubit/theme/theme_cubit.dart'; class NextDaysWeatherForecastTable extends StatelessWidget { @@ -84,7 +86,7 @@ class _DailyWeatherDetails extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ _TempDisplay( - icon: 'assets/images/arrow_up.svg', + icon: Assets.images.arrowUp.path, text: '${dailyWeather.maxTemperature}°C', ), @@ -101,7 +103,7 @@ class _DailyWeatherDetails extends StatelessWidget { ), _TempDisplay( - icon: 'assets/images/arrow_up.svg', + icon: Assets.images.arrowDown.path, text: '${dailyWeather.minTemperature}°C', ),