187 lines
5.3 KiB
Dart
Raw Normal View History

2024-11-02 21:09:05 +04:00
part of '../../presentation/home_page/home_page.dart';
class Stock {
final String? name;
final double? price;
final String? imageUrl;
final StockCategory? category;
Stock({
this.name, this.price, this.imageUrl, this.category,
});
}
class StocksWidget extends StatefulWidget {
const StocksWidget({super.key});
@override
State<StocksWidget> createState() => _StocksWidgetState();
}
class _StocksWidgetState extends State<StocksWidget> {
final List<double> prices = [52.90, 77, 89, 111, 135.43, 157.50, 111.11];
Future<void> _fetchNewPrice() async {
await Future.delayed(const Duration(seconds: 1));
setState(() {
prices.add(prices.last + (prices.last * 0.1));
//if (prices.length > 5) {
// prices.removeAt(0);
//}
});
}
@override
Widget build(BuildContext context) {
final stocks = [
Stock(
name: 'Алроса',
price: 52.90,
imageUrl:
'https://data.cbonds.info/organisations_logos/18/1617957662ALROSA_Rus_COLOUR_RGB.jpg',
category: StockCategory.mining),
Stock(
name: 'Газпром',
price: 135.431111,
imageUrl: 'https://data.cbonds.info/organisations_logos/21/21.png',
category: StockCategory.oilgas),
Stock(
name: 'Сбербанк',
imageUrl:
'https://data.cbonds.info/organisations_logos/313/1615279834sberbank__2-01.png',
category: StockCategory.finance),
Stock(),
];
return Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 300,
child: LineChart(
LineChartData(
lineBarsData: [
LineChartBarData(
spots: prices
.asMap()
.map((index, price) => MapEntry(index.toDouble(), FlSpot(index.toDouble(), price)))
.values
.toList(),
isCurved: true,
color: Colors.blue,
barWidth: 3,
dotData: const FlDotData(show: false),
),
],
),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _fetchNewPrice,
child: const Text('Добавить новую цену'),
),
const SizedBox(height: 20),
// ...stocks.map((e) => StockCard(stock: e)),
...stocks.map((e) => StockCard.fromData(e,
onLike: () => _showSnackBar(context),)), // .toList()
],
),
),
);
}
void _showSnackBar(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
'Stock liked',
style: Theme.of(context).textTheme.bodyLarge,
),
backgroundColor: Colors.red,
duration: const Duration(seconds: 1),
));
});
}
}
class StockCard extends StatefulWidget {
// final Stock stock;
final String? name;
final double? price;
final String? imageUrl;
final StockCategory? category;
final VoidCallback? onLike;
const StockCard({super.key, this.name, this.price, this.imageUrl, this.category, this.onLike});
factory StockCard.fromData(Stock data, {VoidCallback? onLike}) => StockCard(
name: data.name,
price: data.price,
imageUrl: data.imageUrl,
category: data.category,
onLike: onLike,
);
@override
State<StockCard> createState() => _StockCardState();
}
class _StockCardState extends State<StockCard> {
bool isLiked = false;
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(8.5),
child: Padding(
padding: const EdgeInsets.all(20),
child: Row(
children: [
Image.network(
widget.imageUrl ?? 'https://img.freepik.com/premium-vector/vector-illustration-about-concept-of-no-result-data-or-document-or-file-not-found_675567-5734.jpg',
width: 85,
height: 85,
),
const SizedBox(width: 20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.name ?? '',
style: Theme.of(context).textTheme.headlineSmall,
),
Text(
'${widget.price?.toStringAsFixed(2)} р',
style: Theme.of(context).textTheme.bodyLarge,
),
Text(
widget.category?.name ?? '',
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
GestureDetector(
onTap: () {
setState(() {
isLiked = !isLiked;
});
},
child: Icon(
Icons.favorite,
color: isLiked ? Colors.red : Colors.grey,
size: 30.0,
),
),
],
),
),
);
}
}