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

View File

@@ -1,26 +1,22 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gymlink_module_web/components/app_bar.dart'; import 'package:gymlink_module_web/components/app_bar.dart';
import 'package:gymlink_module_web/components/heading.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/pages/basket.dart';
import 'package:gymlink_module_web/providers/cart.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/prefs.dart';
import 'package:gymlink_module_web/tools/routes.dart'; import 'package:gymlink_module_web/tools/routes.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
//TODO: Сделать получение инфы через объект
class DetailPage extends StatefulWidget { class DetailPage extends StatefulWidget {
final String name;
final String description;
final String price;
final String id; final String id;
final Image image;
const DetailPage({ const DetailPage({
super.key, super.key,
required this.name,
required this.description,
required this.price,
required this.id, required this.id,
required this.image,
}); });
@override @override
@@ -30,10 +26,10 @@ class DetailPage extends StatefulWidget {
class _DetailPageState extends State<DetailPage> { class _DetailPageState extends State<DetailPage> {
bool isInCart = false; bool isInCart = false;
int quantity = 0; int quantity = 0;
GymItem? item;
@override @override
void initState() { void initState() {
super.initState();
getCart().then((value) { getCart().then((value) {
setState(() { setState(() {
isInCart = value.any((element) => element['id'] == widget.id); 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( Widget _buildRowOrCol(
@@ -147,8 +158,9 @@ class _DetailPageState extends State<DetailPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: const GymLinkAppBar(), appBar: const GymLinkAppBar(),
body: Column(mainAxisAlignment: MainAxisAlignment.start, children: [ body: item != null
GymLinkHeader(title: widget.name), ? Column(mainAxisAlignment: MainAxisAlignment.start, children: [
GymLinkHeader(title: item!.title),
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Padding( child: Padding(
@@ -161,8 +173,10 @@ class _DetailPageState extends State<DetailPage> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
widget.image, Image(
widget.description != '' image: NetworkImage(item!.images[0].url),
),
item!.description != ''
? Padding( ? Padding(
padding: const EdgeInsetsDirectional.all(30), padding: const EdgeInsetsDirectional.all(30),
child: ConstrainedBox( child: ConstrainedBox(
@@ -173,21 +187,22 @@ class _DetailPageState extends State<DetailPage> {
), ),
child: Card( child: Card(
elevation: 4, elevation: 4,
color: color: Theme.of(context)
Theme.of(context).scaffoldBackgroundColor, .scaffoldBackgroundColor,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Padding( child: Padding(
padding: padding:
const EdgeInsetsDirectional.all(15), const EdgeInsetsDirectional.all(
15),
child: ConstrainedBox( child: ConstrainedBox(
constraints: const BoxConstraints( constraints: const BoxConstraints(
minHeight: 100, minHeight: 100,
), ),
child: Text( child: Text(
widget.description, item!.description,
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.bodyMedium, .bodyMedium,
@@ -202,14 +217,15 @@ class _DetailPageState extends State<DetailPage> {
Align( Align(
alignment: const AlignmentDirectional(0, -1), alignment: const AlignmentDirectional(0, -1),
child: Padding( child: Padding(
padding: padding: const EdgeInsetsDirectional.fromSTEB(
const EdgeInsetsDirectional.fromSTEB(0, 30, 0, 0), 0, 30, 0, 0),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
'Стоимость ${widget.price}руб.', 'Стоимость ${item!.price}руб.',
style: Theme.of(context).textTheme.bodyLarge, style:
Theme.of(context).textTheme.bodyLarge,
), ),
_buildButton() _buildButton()
], ],
@@ -222,7 +238,10 @@ class _DetailPageState extends State<DetailPage> {
), ),
), ),
), ),
]), ])
: const Center(
child: CircularProgressIndicator(),
),
); );
} }
} }

View File

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