Product card on main screen

This commit is contained in:
2024-05-01 16:44:18 +03:00
parent c6520041a6
commit f941b26224
5 changed files with 210 additions and 104 deletions

BIN
assets/product.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

54
lib/components/card.dart Normal file
View File

@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
class ProductCard extends StatelessWidget {
final Image imagePath;
final String name;
final int price;
final VoidCallback onTap;
const ProductCard({
super.key,
required this.imagePath,
required this.name,
required this.price,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: ConstrainedBox(
constraints: const BoxConstraints(minHeight: 200),
child: Card(
elevation: 3,
color: const Color(0xFFF2F3F9),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
imagePath,
const SizedBox(height: 16),
Text(name, style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 8),
Text('\$$price', style: Theme.of(context).textTheme.titleSmall),
],
),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// imagePath,
// const SizedBox(height: 16),
// Text(name, style: Theme.of(context).textTheme.titleLarge),
// const SizedBox(height: 8),
// Text('\$$price', style: Theme.of(context).textTheme.titleSmall),
// ],
// ),
),
),
);
}
}

View File

@@ -3,6 +3,8 @@ import 'dart:js_interop' as js;
import 'dart:js_interop_unsafe' as js_util; import 'dart:js_interop_unsafe' as js_util;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_application_1/components/card.dart';
import 'package:flutter_application_1/theme.dart';
void main() { void main() {
runApp(const MyApp()); runApp(const MyApp());
@@ -42,9 +44,7 @@ class _MyAppState extends State<MyApp> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: 'GymLink Module', title: 'GymLink Module',
theme: ThemeData( theme: myTheme,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
home: gymLinkScreenRouter(_currentGymLinkScreen), home: gymLinkScreenRouter(_currentGymLinkScreen),
); );
@@ -110,120 +110,145 @@ class _MainPageState extends State<MainPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: widget.isLoading appBar: widget.isLoading
? null ? null
: AppBar( : AppBar(
title: Row( backgroundColor: Colors.white,
mainAxisAlignment: MainAxisAlignment.spaceBetween, elevation: 0,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(right: 8),
child: Image.asset('logo.png', width: 24, height: 24),
),
Align(
alignment: Alignment.centerRight,
child: Text(
'Powered by GymLink',
style: Theme.of(context).textTheme.titleSmall,
),
),
],
),
toolbarHeight: 30,
),
body: widget.isLoading
? const Center(child: CircularProgressIndicator())
: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
Padding( Expanded(
padding: const EdgeInsets.only(right: 8), child: TextField(
child: Image.asset('logo.png', width: 24, height: 24), decoration: InputDecoration(
), hintText: 'Search',
Align( border: OutlineInputBorder(
alignment: Alignment.centerRight, borderRadius: BorderRadius.circular(10),
child: Text('Powered by GymLink', ),
style: Theme.of(context).textTheme.titleSmall), suffixIcon: Padding(
), padding: const EdgeInsets.only(right: 8),
])), child: ElevatedButton(
body: widget.isLoading onPressed: () {
? const Center(child: CircularProgressIndicator()) debugPrint('search button pressed');
: Column( },
mainAxisAlignment: MainAxisAlignment.start, style: ElevatedButton.styleFrom(
children: <Widget>[ padding: const EdgeInsets.symmetric(
Row( vertical: 8, horizontal: 0),
children: [ minimumSize:
Expanded( const Size(50, kMinInteractiveDimension),
child: TextField( backgroundColor:
decoration: InputDecoration( Theme.of(context).primaryColor,
hintText: 'Search', shape: const CircleBorder(),
border: OutlineInputBorder( ),
borderRadius: BorderRadius.circular(10), child: const Icon(
), Icons.search,
suffixIcon: Padding( color: Colors.white,
padding: const EdgeInsets.only(right: 8), size: 24,
child: ElevatedButton(
onPressed: () {
debugPrint('search button pressed');
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 0),
minimumSize: const Size(
50, kMinInteractiveDimension),
backgroundColor: Colors.blue,
shape: const CircleBorder(),
),
child: const Icon(
Icons.search,
color: Colors.white,
size: 24,
),
), ),
), ),
), ),
), ),
), ),
const SizedBox(width: 8), ),
ElevatedButton( const SizedBox(width: 8),
onPressed: () { ElevatedButton(
setState(() { onPressed: () {
widget.changeGymLinkScreenTo('basket'); setState(() {
}); widget.changeGymLinkScreenTo('basket');
}, });
style: ElevatedButton.styleFrom( },
padding: const EdgeInsets.all(0), style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue, padding: const EdgeInsets.all(0),
shape: const CircleBorder( minimumSize: const Size(40, kMinInteractiveDimension),
side: BorderSide( backgroundColor: Theme.of(context).primaryColor,
color: Colors.black, shape: const CircleBorder(
width: 1, side: BorderSide(
), color: Colors.black,
width: 1,
), ),
), ),
child: const Icon(
Icons.shopping_basket,
color: Colors.white,
size: 24,
),
), ),
const SizedBox(width: 8), child: const Icon(
ElevatedButton( Icons.shopping_basket,
onPressed: () { color: Colors.white,
setState(() { size: 24,
widget.changeGymLinkScreenTo('history'); ),
}); ),
}, const SizedBox(width: 8),
style: ElevatedButton.styleFrom( ElevatedButton(
padding: const EdgeInsets.all(0), onPressed: () {
backgroundColor: Colors.blue, setState(() {
shape: const CircleBorder( widget.changeGymLinkScreenTo('history');
side: BorderSide( });
color: Colors.black, },
width: 1, style: ElevatedButton.styleFrom(
), padding: const EdgeInsets.all(0),
minimumSize: const Size(40, kMinInteractiveDimension),
backgroundColor: Theme.of(context).primaryColor,
shape: const CircleBorder(
side: BorderSide(
color: Colors.black,
width: 1,
), ),
), ),
child: const Icon(
Icons.history,
color: Colors.white,
size: 24,
),
), ),
], child: const Icon(
Icons.history,
color: Colors.white,
size: 24,
),
),
],
),
),
Expanded(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
), ),
]) itemCount: 10,
// : const Center( itemBuilder: (context, index) {
// child: Column( return ProductCard(
// mainAxisAlignment: MainAxisAlignment.center, imagePath: Image.asset(
// children: <Widget>[ 'product.png',
// Text( width: 100,
// 'Здесь будут товары', ),
// ), name: 'Product $index',
// ], price: 100,
// ), onTap: () => debugPrint('product $index pressed'),
// ), );
); },
),
),
],
),
);
} }
} }

26
lib/theme.dart Normal file
View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
final ThemeData myTheme = ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: getMaterialColor(const Color(0x007d85ff))));
MaterialColor getMaterialColor(Color color) {
final int red = color.red;
final int green = color.green;
final int blue = color.blue;
final Map<int, Color> shades = {
50: Color.fromRGBO(red, green, blue, .1),
100: Color.fromRGBO(red, green, blue, .2),
200: Color.fromRGBO(red, green, blue, .3),
300: Color.fromRGBO(red, green, blue, .4),
400: Color.fromRGBO(red, green, blue, .5),
500: Color.fromRGBO(red, green, blue, .6),
600: Color.fromRGBO(red, green, blue, .7),
700: Color.fromRGBO(red, green, blue, .8),
800: Color.fromRGBO(red, green, blue, .9),
900: Color.fromRGBO(red, green, blue, 1),
};
return MaterialColor(color.value, shades);
}

View File

@@ -59,6 +59,7 @@ flutter:
uses-material-design: true uses-material-design: true
assets: assets:
- assets/logo.png - assets/logo.png
- assets/product.png
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
# assets: # assets: