Add: detail page from API

This commit is contained in:
2024-05-22 22:14:24 +03:00
parent e7073cec67
commit e57c7dc0ea
3 changed files with 98 additions and 87 deletions

View File

@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:gymlink_module_web/pages/detail.dart';
import 'package:gymlink_module_web/tools/routes.dart';
class BasketItemCard extends StatelessWidget {
final String name;
@@ -34,9 +36,8 @@ class BasketItemCard extends StatelessWidget {
),
child: GestureDetector(
onTap: () {
debugPrint('name: $name');
//TODO: сделать переход по клику
// Navigator.of(context).pushReplacement(CustomPageRoute(builder: (context)=>const DetailPage(name: this.name, description: description, price: price, id: id, image: image)))
Navigator.of(context).pushReplacement(
CustomPageRoute(builder: (context) => DetailPage(id: id)));
},
child: Card(
elevation: 4,

View File

@@ -1,26 +1,22 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:gymlink_module_web/components/app_bar.dart';
import 'package:gymlink_module_web/components/heading.dart';
import 'package:gymlink_module_web/interfaces/items.dart';
import 'package:gymlink_module_web/pages/basket.dart';
import 'package:gymlink_module_web/providers/cart.dart';
import 'package:gymlink_module_web/providers/main.dart';
import 'package:gymlink_module_web/tools/prefs.dart';
import 'package:gymlink_module_web/tools/routes.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
//TODO: Сделать получение инфы через объект
class DetailPage extends StatefulWidget {
final String name;
final String description;
final String price;
final String id;
final Image image;
const DetailPage({
super.key,
required this.name,
required this.description,
required this.price,
required this.id,
required this.image,
});
@override
@@ -30,10 +26,10 @@ class DetailPage extends StatefulWidget {
class _DetailPageState extends State<DetailPage> {
bool isInCart = false;
int quantity = 0;
GymItem? item;
@override
void initState() {
super.initState();
getCart().then((value) {
setState(() {
isInCart = value.any((element) => element['id'] == widget.id);
@@ -43,6 +39,21 @@ class _DetailPageState extends State<DetailPage> {
}
});
});
_getItem();
super.initState();
}
void _getItem() async {
final Uri url =
Uri.http('gymlink.freemyip.com:8080', 'api/product/get/${widget.id}');
final response = await http.get(url, headers: {
'Authorization': 'Bearer ${context.read<GymLinkProvider>().token}',
});
if (response.statusCode == 200) {
setState(() {
item = GymItem.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
});
}
}
Widget _buildRowOrCol(
@@ -147,82 +158,90 @@ class _DetailPageState extends State<DetailPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: const GymLinkAppBar(),
body: Column(mainAxisAlignment: MainAxisAlignment.start, children: [
GymLinkHeader(title: widget.name),
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20),
child: SizedBox(
width: MediaQuery.sizeOf(context).width,
// height: MediaQuery.sizeOf(context).height,
child: _buildRowOrCol(
context: context,
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
widget.image,
widget.description != ''
? Padding(
padding: const EdgeInsetsDirectional.all(30),
child: ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 340,
maxWidth: 340,
maxHeight: 600,
),
child: Card(
elevation: 4,
color:
Theme.of(context).scaffoldBackgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: SingleChildScrollView(
child: Padding(
padding:
const EdgeInsetsDirectional.all(15),
child: ConstrainedBox(
constraints: const BoxConstraints(
minHeight: 100,
body: item != null
? Column(mainAxisAlignment: MainAxisAlignment.start, children: [
GymLinkHeader(title: item!.title),
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20),
child: SizedBox(
width: MediaQuery.sizeOf(context).width,
// height: MediaQuery.sizeOf(context).height,
child: _buildRowOrCol(
context: context,
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image(
image: NetworkImage(item!.images[0].url),
),
item!.description != ''
? Padding(
padding: const EdgeInsetsDirectional.all(30),
child: ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 340,
maxWidth: 340,
maxHeight: 600,
),
child: Card(
elevation: 4,
color: Theme.of(context)
.scaffoldBackgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Text(
widget.description,
style: Theme.of(context)
.textTheme
.bodyMedium,
child: SingleChildScrollView(
child: Padding(
padding:
const EdgeInsetsDirectional.all(
15),
child: ConstrainedBox(
constraints: const BoxConstraints(
minHeight: 100,
),
child: Text(
item!.description,
style: Theme.of(context)
.textTheme
.bodyMedium,
),
),
),
),
),
),
),
)
: const SizedBox.shrink(),
Align(
alignment: const AlignmentDirectional(0, -1),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0, 30, 0, 0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Стоимость ${item!.price}руб.',
style:
Theme.of(context).textTheme.bodyLarge,
),
_buildButton()
],
),
),
)
: const SizedBox.shrink(),
Align(
alignment: const AlignmentDirectional(0, -1),
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0, 30, 0, 0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Стоимость ${widget.price}руб.',
style: Theme.of(context).textTheme.bodyLarge,
),
_buildButton()
],
),
),
],
),
),
],
),
),
),
])
: const Center(
child: CircularProgressIndicator(),
),
),
),
]),
);
}
}

View File

@@ -218,16 +218,7 @@ class _MainPageState extends State<MainPage> {
onTap: () => Navigator.of(context).push(
CustomPageRoute(
builder: (context) => DetailPage(
name: product.title,
description: product.description,
price: product.price.toString(),
id: product.id,
image: Image(
image: Image.network(
product.images[0].url)
.image,
width: 300,
),
),
),
),