Compare commits
2 Commits
ff29598ec5
...
26f822e83a
| Author | SHA1 | Date | |
|---|---|---|---|
| 26f822e83a | |||
| 8805b2a9a0 |
71
lib/components/basket_item_card.dart
Normal file
71
lib/components/basket_item_card.dart
Normal file
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BasketItemCard extends StatelessWidget {
|
||||
final String name;
|
||||
final String price;
|
||||
final String id;
|
||||
final Image image;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const BasketItemCard({
|
||||
super.key,
|
||||
required this.name,
|
||||
required this.price,
|
||||
required this.id,
|
||||
required this.image,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsetsDirectional.symmetric(horizontal: 10, vertical: 10),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
minHeight: 100,
|
||||
maxHeight: 200,
|
||||
minWidth: 400,
|
||||
maxWidth: 600,
|
||||
),
|
||||
child: Card(
|
||||
elevation: 4,
|
||||
color: const Color(0xFFF2F3F9),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.symmetric(horizontal: 20),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
image,
|
||||
const SizedBox(width: 20),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
name,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
Text('\$$price'),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
IconButton(
|
||||
onPressed: onTap,
|
||||
icon: const Icon(Icons.close),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,8 @@ const List<Map<String, String>> testData = [
|
||||
"name": "Протеин",
|
||||
"image": "product.png",
|
||||
"price": "150",
|
||||
"details": "Test details",
|
||||
"details":
|
||||
"that name factory say string eaten order harbor easier said tone now floor nest it comfortable such difficulty labor bridge fact market women badly chamber heading forest allow shirt possibly story strip elephant extra even joy lungs than low discussion barn rapidly evidence is stream crew let more sold bag river triangle court slept knowledge flat package research balloon station underline careful market better make curious secret boy poor captured creature harder public tool ring subject charge planet tone scientist piece page stone support bush way feathers summer describe back should said complex song giant his that name factory say string eaten order harbor easier said tone now floor nest it comfortable such difficulty labor bridge fact market women badly chamber heading forest allow shirt possibly story strip elephant extra even joy lungs than low discussion barn rapidly evidence is stream crew let more sold bag river triangle court slept knowledge flat package research balloon station underline careful market better make curious secret boy poor captured creature harder public tool ring subject charge planet tone scientist piece page stone support bush way feathers summer describe back should said complex song giant his that name factory say string eaten order harbor easier said tone now floor nest it comfortable such difficulty labor bridge fact market women badly chamber heading forest allow shirt possibly story strip elephant extra even joy lungs than low discussion barn rapidly evidence is stream crew let more sold bag river triangle court slept knowledge flat package research balloon station underline careful market better make curious secret boy poor captured creature harder public tool ring subject charge planet tone scientist piece page stone support bush way feathers summer describe back should said complex song giant his that name factory say string eaten order harbor easier said tone now floor nest it comfortable such difficulty labor bridge fact market women badly chamber heading forest allow shirt possibly story strip elephant extra even joy lungs than low discussion barn rapidly evidence is stream crew let more sold bag river triangle court slept knowledge flat package research balloon station underline careful market better make curious secret boy poor captured creature harder public tool ring subject charge planet tone scientist piece page stone support bush way feathers summer describe back should said complex song giant his",
|
||||
"id": "34a26e82-7656-5e98-a44a-c2d01d0b1ad1123"
|
||||
},
|
||||
{
|
||||
@@ -166,7 +167,9 @@ class _MainPageState extends State<MainPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Spacer(
|
||||
flex: 2,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
@@ -175,7 +178,7 @@ class _MainPageState extends State<MainPage> {
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.all(0),
|
||||
minimumSize: const Size(40, kMinInteractiveDimension),
|
||||
minimumSize: const Size(50, kMinInteractiveDimension),
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
shape: const CircleBorder(
|
||||
side: BorderSide(
|
||||
@@ -190,7 +193,9 @@ class _MainPageState extends State<MainPage> {
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
@@ -199,7 +204,7 @@ class _MainPageState extends State<MainPage> {
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.all(0),
|
||||
minimumSize: const Size(40, kMinInteractiveDimension),
|
||||
minimumSize: const Size(50, kMinInteractiveDimension),
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
shape: const CircleBorder(
|
||||
side: BorderSide(
|
||||
@@ -214,6 +219,9 @@ class _MainPageState extends State<MainPage> {
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,8 +1,47 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gymlink_module_web/components/app_bar.dart';
|
||||
import 'package:gymlink_module_web/components/basket_item_card.dart';
|
||||
import 'package:gymlink_module_web/components/heading.dart';
|
||||
import 'package:gymlink_module_web/tools/prefs.dart';
|
||||
|
||||
List<Map<String, dynamic>> cart = [
|
||||
{
|
||||
"name": "Протеин",
|
||||
"image": "product.png",
|
||||
"price": "120",
|
||||
"details": "Test details",
|
||||
"id": "34fa3126-bfaf-5dec-8f4a-b246c097ef73"
|
||||
},
|
||||
{
|
||||
"name": "Протеин",
|
||||
"image": "product.png",
|
||||
"price": "150",
|
||||
"details": "Test details",
|
||||
"id": "34a26e82-7656-5e98-a44a-c2d01d0b1ad1123"
|
||||
},
|
||||
{
|
||||
"name": "Протеин",
|
||||
"image": "product.png",
|
||||
"price": "250",
|
||||
"details": "Test details",
|
||||
"id": "4fb204b7-3f9e-52a2-bed1-415c00a31a37123"
|
||||
},
|
||||
{
|
||||
"name": "Протеин",
|
||||
"image": "product.png",
|
||||
"price": "300",
|
||||
"details": "Test details",
|
||||
"id": "09b2f5bb-683e-5c39-ae89-b8e152fa8bcf123"
|
||||
},
|
||||
{
|
||||
"name": "Протеин",
|
||||
"image": "product.png",
|
||||
"price": "100",
|
||||
"details": "Test details",
|
||||
"id": "cd1b6817-db94-5394-be1d-af88af79749f123"
|
||||
}
|
||||
];
|
||||
|
||||
//TODO: Вывод корзины из shared_prefs
|
||||
class BasketPage extends StatefulWidget {
|
||||
const BasketPage({super.key});
|
||||
|
||||
@@ -11,15 +50,113 @@ class BasketPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _BasketPageState extends State<BasketPage> {
|
||||
List<Map<String, dynamic>> cartItems = [];
|
||||
int totalPrice = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getCart().then((value) {
|
||||
setState(() {
|
||||
cartItems = cart
|
||||
.where((element) => value.any((e) => e['id'] == element['id']))
|
||||
.toList();
|
||||
totalPrice =
|
||||
cartItems.fold(0, (sum, item) => sum + int.parse(item['price']));
|
||||
debugPrint(totalPrice.toString());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void removeItem(String id) async {
|
||||
setState(() {
|
||||
cartItems.removeWhere((element) => element['id'] == id);
|
||||
totalPrice =
|
||||
cartItems.fold(0, (sum, item) => sum + int.parse(item['price']));
|
||||
});
|
||||
await removeItemFromCart(id);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
appBar: GymLinkAppBar(),
|
||||
return Scaffold(
|
||||
appBar: const GymLinkAppBar(),
|
||||
body: Column(
|
||||
children: [
|
||||
GymLinkHeader(title: 'Корзина'),
|
||||
Center(
|
||||
child: Text('Корзина'),
|
||||
const GymLinkHeader(title: "Корзина"),
|
||||
cartItems.isEmpty
|
||||
? Expanded(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('Корзина пуста',
|
||||
style: Theme.of(context).textTheme.bodyLarge),
|
||||
const SizedBox(height: 10),
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(50)),
|
||||
),
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
child: const Text('Вернуться назад'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: cartItems.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = cartItems[index];
|
||||
return BasketItemCard(
|
||||
name: item['name'],
|
||||
price: item['price'],
|
||||
id: item['id'],
|
||||
image: Image.asset(
|
||||
item['image'],
|
||||
width: 50,
|
||||
),
|
||||
onTap: () => removeItem(item['id']),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.symmetric(
|
||||
horizontal: 10, vertical: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'Итого: $totalPrice',
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(50)),
|
||||
),
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
child: const Text('Оформить заказ'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 50),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -31,7 +31,6 @@ class _DetailPageState extends State<DetailPage> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
getCart().then((value) {
|
||||
debugPrint(value.toString());
|
||||
setState(() {
|
||||
isInCart = value.any((element) => element['id'] == widget.id);
|
||||
if (isInCart) {
|
||||
@@ -109,23 +108,32 @@ class _DetailPageState extends State<DetailPage> {
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
widget.image,
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsetsDirectional.fromSTEB(0, 30, 60, 60),
|
||||
child: SizedBox(
|
||||
width: 340,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 340,
|
||||
maxWidth: 340,
|
||||
maxHeight: 600,
|
||||
),
|
||||
child: Card(
|
||||
elevation: 4,
|
||||
color: const Color(0xFFF2F3F9),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||
20, 15, 10, 15),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
minHeight: 100,
|
||||
),
|
||||
child: Text(
|
||||
widget.description,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
@@ -134,6 +142,8 @@ class _DetailPageState extends State<DetailPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: const AlignmentDirectional(0, -1),
|
||||
child: Padding(
|
||||
|
||||
Reference in New Issue
Block a user