From c60c081f99e06d645266e1a1b9e8064480b15b48 Mon Sep 17 00:00:00 2001 From: "Mr.Jebelli" Date: Tue, 23 Jun 2026 09:16:41 +0330 Subject: [PATCH] =?UTF-8?q?render=20top=20banner=20from=20new=20"=D9=91Foo?= =?UTF-8?q?ladinfo"=20category?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/infography/infography_screen.dart | 32 ++++++++++++++ .../infography/infography_screen_state.dart | 43 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/lib/views/home/infography/infography_screen.dart b/lib/views/home/infography/infography_screen.dart index f1acb33..5e567bf 100644 --- a/lib/views/home/infography/infography_screen.dart +++ b/lib/views/home/infography/infography_screen.dart @@ -195,6 +195,38 @@ class _InfographyScreenState extends State { value: context.watch().lastSearch, isFiltered: context.watch().filtering), ), + // پوستر بالای صفحه — از دسته‌ی «بنر فولادینفو» کشیده می‌شود. + // اگر هیچ آیتم منتشرشده‌ای در آن دسته نباشد، چیزی نمایش داده نمی‌شود. + Builder(builder: (context) { + final bannerUrl = + context.watch().topBannerImageUrl; + if (bannerUrl == null || bannerUrl.isEmpty) { + return const SizedBox.shrink(); + } + return Padding( + padding: const EdgeInsets.fromLTRB(16, 8, 16, 0), + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: AspectRatio( + aspectRatio: 16 / 7, + child: Image.network( + bannerUrl, + fit: BoxFit.cover, + errorBuilder: (_, __, ___) => const SizedBox.shrink(), + loadingBuilder: (context, child, progress) { + if (progress == null) return child; + return Container( + color: Theme.of(context) + .colorScheme + .surface + .withOpacity(0.4), + ); + }, + ), + ), + ), + ); + }), StateHandler( placeholder: SingleChildScrollView( child: Column( diff --git a/lib/views/home/infography/infography_screen_state.dart b/lib/views/home/infography/infography_screen_state.dart index e4318c5..58d75ad 100644 --- a/lib/views/home/infography/infography_screen_state.dart +++ b/lib/views/home/infography/infography_screen_state.dart @@ -72,6 +72,15 @@ class InfographyScreenState extends CoreProvier { static const String _infographyCategoryId = '3e53627d-9a18-4bad-b4ae-1f0c55438147'; + /// شناسه‌ی دسته‌ی «بنر فولادینفو» — تصویر کاور آخرین content این دسته + /// به‌عنوان پوستر بالای صفحه‌ی فولادینفو در اپ نمایش داده می‌شود. + static const String _foladinfoBannerCategoryId = + 'd1a5e9b3-6f47-4c82-9e1d-3b8f2c5a4d76'; + + /// URL تصویر بنر فولادینفو که در بالای صفحه نمایش داده می‌شود؛ + /// اگر null یا خالی بود، بنر اصلاً رندر نمی‌شود. + String? topBannerImageUrl; + /// فقط محتوای منتشرشده/تأییدشده. status فقط IN دارد. static const String _visibleStatusFilter = '\$in:accepted,published'; @@ -167,6 +176,39 @@ class InfographyScreenState extends CoreProvier { appState = AppState.idle; } + /// آخرین content منتشرشده در دسته‌ی «بنر فولادینفو» را می‌گیریم و + /// `coverImage` آن را در [topBannerImageUrl] می‌گذاریم. در صورت خطا + /// یا خالی‌بودن، بنر نمایش داده نمی‌شود (مقدار null می‌ماند). + Future _fetchTopBanner() async { + try { + final res = await ContentService.instance.getContents( + page: 1, + limit: 1, + filterStatus: _visibleStatusFilter, + categoryId: _foladinfoBannerCategoryId, + sortBy: const [MapEntry('createdAt', 'DESC')], + ); + if (!res.isSuccess || res.data == null || res.data!.data.isEmpty) { + topBannerImageUrl = null; + update(); + return; + } + final first = res.data!.data.first; + // The list endpoint may already include coverImage; if not, fetch detail. + String? cover = first.coverImage; + if (cover == null || cover.isEmpty) { + final detail = await ContentService.instance.getContent(first.id); + if (detail.isSuccess && detail.data != null) { + cover = detail.data!.coverImage; + } + } + topBannerImageUrl = (cover != null && cover.isNotEmpty) ? cover : null; + update(); + } catch (_) { + topBannerImageUrl = null; + } + } + void resetFilters(bool isInit) { selectedCats.clear(); selectedTags.clear(); @@ -184,6 +226,7 @@ class InfographyScreenState extends CoreProvier { resetFilters(true); Future.delayed(Duration.zero, () { getInfographyContent(page: 1); + _fetchTopBanner(); }); categories = [ CategoryData(