swot loading fixed

This commit is contained in:
mohamadmahdi jebeli 2025-07-02 15:20:56 +03:30
parent 75241cf93e
commit 283938d759
3 changed files with 182 additions and 166 deletions

View File

@ -48,9 +48,10 @@ class _MainPageState extends State<MainPage> {
children: [
if (state.stories.isNotEmpty) StorySection(stories: state.stories),
const SizedBox(height: 12),
// محتوای اصلی صفحه
// Main page content
const MainPageMainContent(),
// START: MODIFIED SECTION
Builder(builder: (context) {
final List<Widget> pageContent = [];
if (state.content != null && state.content!.lists.isNotEmpty) {
@ -114,9 +115,9 @@ class _MainPageState extends State<MainPage> {
list: currentList,
isLast: i == lists.length - 1,
));
if (currentList.type == 'startup') {
pageContent.add(const _SwotSection());
pageContent.add(_SwotSection(swotItems: state.swotItems));
}
}
}
@ -129,100 +130,84 @@ class _MainPageState extends State<MainPage> {
}
class _SwotSection extends StatelessWidget {
const _SwotSection();
final List<SwotItem> swotItems;
const _SwotSection({required this.swotItems});
@override
Widget build(BuildContext context) {
return FutureBuilder<List<SwotItem>>(
future: SwotService.fetchSwotItems(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const SizedBox(
height: 10,
);
} else if (snapshot.hasError) {
return const SizedBox(
height: 10,
);
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return const SizedBox(
height: 10,
);
}
final items = snapshot.data!;
return Padding(
padding: const EdgeInsets.all(0.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// Title Row
Padding(
padding: const EdgeInsets.only(right: 20, top: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
if (swotItems.isEmpty) {
return const SizedBox.shrink();
}
return Padding(
padding: const EdgeInsets.all(0.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// Title Row
Padding(
padding: const EdgeInsets.only(right: 20, top: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Row(
children: [
SvgPicture.asset(
"lib/assets/images/features/Saha Solid.svg",
),
const SizedBox(width: 5),
DidvanText(
"ماژول فرصت و تهدید",
style: Theme.of(context).textTheme.titleMedium,
color: Theme.of(context).colorScheme.title,
),
],
SvgPicture.asset(
"lib/assets/images/features/Saha Solid.svg",
),
GestureDetector(
onTap: () {
AppInitializer.openWebLink(
navigatorKey.currentContext!,
'http://opportunity-threat.didvan.com/?accessToken=${RequestService.token}',
mode: LaunchMode.inAppWebView,
);
},
child: Padding(
padding: const EdgeInsets.only(left: 20),
child: Row(
children: [
DidvanText(
"همه",
color: Theme.of(context).colorScheme.primary,
),
Icon(
DidvanIcons.angle_left_light,
color: Theme.of(context).colorScheme.primary,
),
],
),
),
const SizedBox(width: 5),
DidvanText(
"ماژول فرصت و تهدید",
style: Theme.of(context).textTheme.titleMedium,
color: Theme.of(context).colorScheme.title,
),
],
),
),
const SizedBox(height: 16),
/// Swot Items Slider
DidvanSlider(
height: 335,
itemCount: items.length,
viewportFraction: 0.65,
itemBuilder: (context, index, realIndex) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 0.0),
GestureDetector(
onTap: () {
AppInitializer.openWebLink(
navigatorKey.currentContext!,
'http://opportunity-threat.didvan.com/?accessToken=${RequestService.token}',
mode: LaunchMode.inAppWebView,
);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SwotItemCard(item: items[index]),
padding: const EdgeInsets.only(left: 20),
child: Row(
children: [
DidvanText(
"همه",
color: Theme.of(context).colorScheme.primary,
),
Icon(
DidvanIcons.angle_left_light,
color: Theme.of(context).colorScheme.primary,
),
],
),
),
),
),
],
],
),
),
);
},
const SizedBox(height: 16),
/// Swot Items Slider
DidvanSlider(
height: 330,
itemCount: 7,
viewportFraction: 0.65,
itemBuilder: (context, index, realIndex) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 0.0),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SwotItemCard(item: swotItems[index]),
),
),
),
],
),
);
}
}
@ -306,83 +291,102 @@ class _MainPageSection extends StatelessWidget {
if (list.contents.isEmpty) {
return const SizedBox();
}
// This condition handles the "Soha" module, which should not display the Opportunity/Threat module.
if (list.type == 'delphi') {
return Column(
children: [
_buildSectionHeader(context, icon),
_buildSectionSlider(context),
],
);
}
// For all other modules, display as before.
return Column(
children: [
Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 16,
top: 28,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
if (icon != null) Icon(icon),
const SizedBox(width: 4),
DidvanText(
list.header,
style: Theme.of(context).textTheme.titleMedium,
color: Theme.of(context).colorScheme.title,
),
],
),
GestureDetector(
onTap: () => _moreHandler(context),
child: Row(
children: [
DidvanText(
list.more,
color: Theme.of(context).colorScheme.primary,
),
Icon(
DidvanIcons.angle_left_light,
color: Theme.of(context).colorScheme.primary,
)
],
),
)
],
),
),
if (list.type != 'podcast')
DidvanSlider(
height: 260 +
(_maxSublistCount() - (list.type == 'radar' ? 1 : 0)) * 20,
itemCount: list.contents.length,
viewportFraction: 0.65,
itemBuilder: (context, index, realIndex) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: MainPageGeneralItem(
content: list.contents[index],
type: list.type,
),
),
),
if (list.type == 'podcast')
Padding(
padding: const EdgeInsets.only(top: 28),
child: Column(
children: list.contents
.map(
(e) => Padding(
padding: const EdgeInsets.only(
bottom: 12,
left: 28,
right: 28,
),
child: MainPagePodcastItem(
content: e,
),
),
)
.toList(),
),
),
_buildSectionHeader(context, icon),
_buildSectionSlider(context),
],
);
}
Padding _buildSectionHeader(BuildContext context, IconData? icon) {
return Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 16,
top: 28,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
if (icon != null) Icon(icon),
const SizedBox(width: 4),
DidvanText(
list.header,
style: Theme.of(context).textTheme.titleMedium,
color: Theme.of(context).colorScheme.title,
),
],
),
GestureDetector(
onTap: () => _moreHandler(context),
child: Row(
children: [
DidvanText(
list.more,
color: Theme.of(context).colorScheme.primary,
),
Icon(
DidvanIcons.angle_left_light,
color: Theme.of(context).colorScheme.primary,
)
],
),
)
],
),
);
}
Widget _buildSectionSlider(BuildContext context) {
if (list.type == 'podcast') {
return Padding(
padding: const EdgeInsets.only(top: 28),
child: Column(
children: list.contents
.map(
(e) => Padding(
padding: const EdgeInsets.only(
bottom: 12,
left: 28,
right: 28,
),
child: MainPagePodcastItem(
content: e,
),
),
)
.toList(),
),
);
}
return DidvanSlider(
height: 260 + (_maxSublistCount() - (list.type == 'radar' ? 1 : 0)) * 20,
itemCount: list.contents.length,
viewportFraction: 0.65,
itemBuilder: (context, index, realIndex) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: MainPageGeneralItem(
content: list.contents[index],
type: list.type,
),
),
);
}
}

View File

@ -1,6 +1,7 @@
import 'package:didvan/main.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/home_page_content/home_page_content.dart';
import 'package:didvan/models/home_page_content/swot.dart';
import 'package:didvan/models/requests/infography.dart';
import 'package:didvan/models/requests/news.dart';
import 'package:didvan/models/requests/radar.dart';
@ -11,6 +12,7 @@ import 'package:didvan/services/app_initalizer.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/story_service.dart';
import 'package:didvan/services/swot_service.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';
@ -18,6 +20,7 @@ class MainPageState extends CoreProvier {
MainPageContent? content;
int unread = 0;
List<UserStories> stories = [];
List<SwotItem> swotItems = [];
Future<void> _getMainPageContent() async {
final service = RequestService(RequestHelper.mainPageContent);
@ -30,6 +33,14 @@ class MainPageState extends CoreProvier {
}
}
Future<void> _getSwotItems() async { // این متد را اضافه کنید
try {
swotItems = await SwotService.fetchSwotItems();
} catch (e) {
// در صورت بروز خطا، میتوانید اینجا آن را مدیریت کنید
}
}
Future<void> _fetchStories() async {
try {
stories = await StoryService.getStories();
@ -47,6 +58,7 @@ class MainPageState extends CoreProvier {
await Future.wait([
_getMainPageContent(),
_fetchStories(),
_getSwotItems(),
]);
appState = AppState.idle;
} catch (e) {

View File

@ -387,13 +387,13 @@ class _UserInfo extends StatelessWidget {
fontWeight: FontWeight.w600,
),
),
DidvanText(
DateTimeUtils.momentGenerator(user.createdAt),
style: const TextStyle(
color: Colors.white70,
fontSize: 14.0,
),
),
// DidvanText(
// DateTimeUtils.momentGenerator(user.createdAt),
// style: const TextStyle(
// color: Colors.white70,
// fontSize: 14.0,
// ),
// ),
],
),
),