didvan-app/lib/views/home/main/widgets/simple_explore_card.dart

194 lines
6.8 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) {
return 'lib/assets/icons/Swot_New.svg';
}
switch (contentType?.toLowerCase()) {
case 'startup':
return 'lib/assets/icons/Startup.svg';
case 'radar':
return 'lib/assets/icons/Pouyesh_Ofogh_New.svg';
case 'trend': // رادار روند
case 'trends':
return 'lib/assets/icons/Ravand.svg';
case 'technology': // رادار تکنولوزی/فناوری
case 'tech':
return 'lib/assets/icons/Technology.svg';
case 'risk': // رادار ریسک
return 'lib/assets/icons/RiskRadar.svg';
case 'survey':
case 'delphi':
return 'lib/assets/icons/Saha.svg';
case 'monthly':
return 'lib/assets/icons/Monthly.svg';
case 'news':
return 'lib/assets/icons/news-icon.svg';
case 'infography':
return 'lib/assets/icons/infography-icon.svg';
case 'video':
return 'lib/assets/icons/video-icon.svg';
case 'podcast':
return 'lib/assets/icons/podcast-icon.svg';
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, _) => const 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,
),
),
],
),
),
),
],
),
),
);
}
}