189 lines
7.0 KiB
Dart
189 lines
7.0 KiB
Dart
import 'package:didvan/models/home_page_content/content.dart';
|
|
import 'package:didvan/models/home_page_content/swot.dart';
|
|
import 'package:didvan/views/home/main/main_page_state.dart';
|
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
|
import 'package:didvan/services/app_initalizer.dart';
|
|
import 'package:didvan/services/network/request.dart';
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
|
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:url_launcher/url_launcher_string.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
|
|
class SimpleExploreCard extends StatelessWidget {
|
|
final MainPageContentType? content;
|
|
final String? type;
|
|
final SwotItem? swotItem;
|
|
|
|
const SimpleExploreCard({
|
|
super.key,
|
|
this.content,
|
|
this.type,
|
|
this.swotItem,
|
|
}) : assert(
|
|
(content != null && type != null && swotItem == null) ||
|
|
(content == null && type == null && swotItem != null),
|
|
'Either provide content and type, or swotItem, but not both',
|
|
);
|
|
|
|
String _getCategoryIcon(String? contentType, bool isSwot) {
|
|
if (isSwot) {
|
|
// For SWOT items (فرصت تهدید)
|
|
return 'lib/assets/icons/swot.svg';
|
|
}
|
|
|
|
switch (contentType?.toLowerCase()) {
|
|
case 'startup':
|
|
return 'lib/assets/icons/bi_rocket-fill.svg';
|
|
case 'radar':
|
|
return 'lib/assets/icons/solar_graph-new-bold.svg'; // General radar fallback
|
|
case 'trend': // رادار روند
|
|
case 'trends':
|
|
return 'lib/assets/icons/solar_graph-new-bold.svg';
|
|
case 'technology': // رادار تکنولوزی/فناوری
|
|
case 'tech':
|
|
return 'lib/assets/icons/cpu-charge.svg';
|
|
case 'risk': // رادار ریسک
|
|
return 'lib/assets/icons/risk radar.svg';
|
|
case 'survey':
|
|
case 'delphi': // دولفی
|
|
return 'lib/assets/icons/icon-park-solid_thinking-problem.svg';
|
|
case 'news':
|
|
return 'lib/assets/icons/news-icon.svg'; // You can replace with actual icon
|
|
case 'infography':
|
|
return 'lib/assets/icons/infography-icon.svg'; // You can replace with actual icon
|
|
case 'video':
|
|
return 'lib/assets/icons/video-icon.svg'; // You can replace with actual icon
|
|
case 'podcast':
|
|
return 'lib/assets/icons/podcast-icon.svg'; // You can replace with actual icon
|
|
default:
|
|
return 'lib/assets/icons/bi_rocket-fill.svg'; // Default fallback
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final isSwot = swotItem != null;
|
|
final imageUrl = isSwot ? swotItem!.imageUrl : content!.image;
|
|
final title = isSwot ? swotItem!.title : content!.title;
|
|
|
|
return GestureDetector(
|
|
onTap: () {
|
|
if (isSwot) {
|
|
AppInitializer.openWebLink(
|
|
context,
|
|
'http://opportunity-threat.didvan.com/posts/${swotItem!.id}/?accessToken=${RequestService.token}',
|
|
mode: LaunchMode.inAppWebView,
|
|
);
|
|
} else {
|
|
context.read<MainPageState>().navigationHandler(
|
|
type!,
|
|
content!.id,
|
|
content!.link,
|
|
);
|
|
}
|
|
},
|
|
child: Container(
|
|
width: 280,
|
|
height: 200,
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).cardColor,
|
|
borderRadius: BorderRadius.circular(12),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withValues(alpha: 0.1),
|
|
spreadRadius: 1,
|
|
blurRadius: 8,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Expanded(
|
|
flex: 4,
|
|
child: ClipRRect(
|
|
borderRadius: const BorderRadius.vertical(
|
|
top: Radius.circular(12),
|
|
),
|
|
child: isSwot
|
|
? CachedNetworkImage(
|
|
errorWidget: (context, url, error) {
|
|
return Container(
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.onSurface
|
|
.withValues(alpha: 0.1),
|
|
),
|
|
child: const Icon(Icons.image_not_supported_outlined),
|
|
);
|
|
},
|
|
fit: BoxFit.cover,
|
|
imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet,
|
|
httpHeaders: {
|
|
'Authorization': 'Bearer ${RequestService.token}'
|
|
},
|
|
width: double.infinity,
|
|
imageUrl: imageUrl,
|
|
placeholder: (context, _) => ShimmerPlaceholder(
|
|
width: double.infinity,
|
|
height: double.infinity,
|
|
),
|
|
)
|
|
: SkeletonImage(
|
|
imageUrl: imageUrl,
|
|
width: double.infinity,
|
|
borderRadius: BorderRadius.zero,
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
width: double.infinity,
|
|
height: 40,
|
|
decoration: const BoxDecoration(
|
|
color: Color.fromRGBO(0, 69, 92, 1),
|
|
borderRadius: BorderRadius.vertical(
|
|
bottom: Radius.circular(12),
|
|
),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
child: Row(
|
|
children: [
|
|
SvgPicture.asset(
|
|
_getCategoryIcon(type, isSwot),
|
|
width: 20,
|
|
height: 20,
|
|
colorFilter: const ColorFilter.mode(
|
|
Colors.white,
|
|
BlendMode.srcIn,
|
|
),
|
|
),
|
|
Expanded(
|
|
child: DidvanText(
|
|
title,
|
|
style: Theme.of(context).textTheme.titleSmall?.copyWith(
|
|
fontWeight: FontWeight.w600,
|
|
color: Colors.white,
|
|
),
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
textAlign: TextAlign.center,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |