feat(app): responsive asset detail layout, full width chart, reactive hero header, shimmer loaders and enriched fundamentals
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/widgets/glass_container.dart';
|
||||
import '../../favorites/cubit/favorites_cubit.dart';
|
||||
import '../../favorites/models/favorite_asset_model.dart';
|
||||
import '../models/trade_model.dart';
|
||||
import 'trade_detail_modal.dart';
|
||||
|
||||
@@ -26,23 +29,34 @@ class TradeCard extends StatelessWidget {
|
||||
final isActive = trade.isActive;
|
||||
final isClosed = trade.isClosed;
|
||||
|
||||
final pnlAbs = trade.calculatedPnlAbs;
|
||||
final pnlPct = trade.calculatedPnlPct;
|
||||
final isPnlPos = pnlAbs >= 0;
|
||||
final pnlColor = isPnlPos ? AppTheme.primaryEmerald : AppTheme.accentRed;
|
||||
return BlocBuilder<FavoritesCubit, FavoritesState>(
|
||||
builder: (context, favState) {
|
||||
double livePrice = 0.0;
|
||||
final keyUpper = (trade.isin.isNotEmpty ? trade.isin : trade.symbol).toUpperCase();
|
||||
final match = favState.favoriteDetails.firstWhere(
|
||||
(f) => f.isin.toUpperCase() == keyUpper || f.symbol.toUpperCase() == keyUpper,
|
||||
orElse: () => const FavoriteAssetModel(isin: '', symbol: '', name: '', currentPrice: 0.0, change24h: 0.0),
|
||||
);
|
||||
if (match.currentPrice > 0) {
|
||||
livePrice = match.currentPrice;
|
||||
}
|
||||
|
||||
final currPrice = trade.effectiveCurrentPrice;
|
||||
final pnlAbs = livePrice > 0 ? trade.calculateLivePnlAbs(livePrice) : trade.calculatedPnlAbs;
|
||||
final pnlPct = livePrice > 0 ? trade.calculateLivePnlPct(livePrice) : trade.calculatedPnlPct;
|
||||
final isPnlPos = pnlAbs >= 0;
|
||||
final pnlColor = isPnlPos ? AppTheme.primaryEmerald : AppTheme.accentRed;
|
||||
final currPrice = livePrice > 0 ? livePrice : trade.effectiveCurrentPrice;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => TradeDetailModal.show(
|
||||
context,
|
||||
trade: trade,
|
||||
onAccept: onAccept,
|
||||
onClose: onClose,
|
||||
),
|
||||
child: GlassContainer(
|
||||
margin: const EdgeInsets.only(bottom: 14),
|
||||
padding: const EdgeInsets.all(16),
|
||||
return GestureDetector(
|
||||
onTap: () => TradeDetailModal.show(
|
||||
context,
|
||||
trade: trade,
|
||||
onAccept: onAccept,
|
||||
onClose: onClose,
|
||||
),
|
||||
child: GlassContainer(
|
||||
margin: const EdgeInsets.only(bottom: 14),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -187,7 +201,7 @@ class TradeCard extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'${trade.instrumentType.isNotEmpty ? trade.instrumentType : "Stock"} • ${trade.timeframe.isNotEmpty ? trade.timeframe : "1D"}${trade.leverageUsed > 1 ? " • ${trade.leverageUsed.toStringAsFixed(0)}x Hebel" : ""}',
|
||||
'${trade.instrumentType.isNotEmpty ? trade.instrumentType : "Stock"}${trade.derivativeIsin.isNotEmpty ? " (${trade.derivativeIsin})" : ""} • ${trade.timeframe.isNotEmpty ? trade.timeframe : "1D"}${trade.leverageUsed > 1 ? " • ${trade.leverageUsed.toStringAsFixed(0)}x Hebel" : ""}',
|
||||
style: TextStyle(color: AppTheme.textMuted, fontSize: 11),
|
||||
),
|
||||
|
||||
@@ -241,14 +255,16 @@ class TradeCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _priceItem(String label, String val, Color valColor) {
|
||||
|
||||
Reference in New Issue
Block a user