Create Home Screen and Add other Fiture
This commit is contained in:
parent
7b54413183
commit
8bab6bdb7d
25 changed files with 684 additions and 45 deletions
BIN
assets/Product_1.webp
Normal file
BIN
assets/Product_1.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 176 KiB |
BIN
assets/Product_2.webp
Normal file
BIN
assets/Product_2.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 139 KiB |
BIN
assets/Product_3.webp
Normal file
BIN
assets/Product_3.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 201 KiB |
BIN
assets/fonts/Gordita_Bold.otf
Normal file
BIN
assets/fonts/Gordita_Bold.otf
Normal file
Binary file not shown.
BIN
assets/fonts/Gordita_Light.otf
Normal file
BIN
assets/fonts/Gordita_Light.otf
Normal file
Binary file not shown.
BIN
assets/fonts/Gordita_Medium.otf
Normal file
BIN
assets/fonts/Gordita_Medium.otf
Normal file
Binary file not shown.
BIN
assets/fonts/Gordita_Regular.otf
Normal file
BIN
assets/fonts/Gordita_Regular.otf
Normal file
Binary file not shown.
BIN
assets/fonts/Gordita_Thin.otf
Normal file
BIN
assets/fonts/Gordita_Thin.otf
Normal file
Binary file not shown.
24
lib/components/Category.dart
Normal file
24
lib/components/Category.dart
Normal file
|
@ -0,0 +1,24 @@
|
|||
class Category {
|
||||
final String icon, title;
|
||||
|
||||
Category({required this.icon, required this.title});
|
||||
}
|
||||
|
||||
List<Category> demo_categories = [
|
||||
Category(
|
||||
icon: "assets/icons/dress.svg",
|
||||
title: "Dress",
|
||||
),
|
||||
Category(
|
||||
icon: "assets/icons/shirt.svg",
|
||||
title: "Shirt",
|
||||
),
|
||||
Category(
|
||||
icon: "assets/icons/pants.svg",
|
||||
title: "Pants",
|
||||
),
|
||||
Category(
|
||||
icon: "assets/icons/Tshirt.svg",
|
||||
title: "Tshirt",
|
||||
),
|
||||
];
|
67
lib/components/categories.dart
Normal file
67
lib/components/categories.dart
Normal file
|
@ -0,0 +1,67 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:nekoya_flutter/components/Category.dart';
|
||||
|
||||
import '../../../constants.dart';
|
||||
|
||||
class Categories extends StatelessWidget {
|
||||
const Categories({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 84,
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: demo_categories.length,
|
||||
itemBuilder: (context, index) => CategoryCard(
|
||||
icon: demo_categories[index].icon,
|
||||
title: demo_categories[index].title,
|
||||
press: () {},
|
||||
),
|
||||
separatorBuilder: (context, index) =>
|
||||
const SizedBox(width: defaultPadding),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryCard extends StatelessWidget {
|
||||
const CategoryCard({
|
||||
Key? key,
|
||||
required this.icon,
|
||||
required this.title,
|
||||
required this.press,
|
||||
}) : super(key: key);
|
||||
|
||||
final String icon, title;
|
||||
final VoidCallback press;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return OutlinedButton(
|
||||
onPressed: press,
|
||||
style: OutlinedButton.styleFrom(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(defaultBorderRadius)),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: defaultPadding / 2, horizontal: defaultPadding / 4),
|
||||
child: Column(
|
||||
children: [
|
||||
SvgPicture.asset(icon),
|
||||
const SizedBox(height: defaultPadding / 2),
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
29
lib/components/color_dot.dart
Normal file
29
lib/components/color_dot.dart
Normal file
|
@ -0,0 +1,29 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../constants.dart';
|
||||
|
||||
class ColorDot extends StatelessWidget {
|
||||
const ColorDot({
|
||||
Key? key,
|
||||
required this.color,
|
||||
required this.isActive,
|
||||
}) : super(key: key);
|
||||
|
||||
final Color color;
|
||||
final bool isActive;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(defaultPadding / 4),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: isActive ? primaryColor : Colors.transparent),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: CircleAvatar(
|
||||
radius: 10,
|
||||
backgroundColor: color,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
119
lib/components/details_screen.dart
Normal file
119
lib/components/details_screen.dart
Normal file
|
@ -0,0 +1,119 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:nekoya_flutter/constants.dart';
|
||||
import 'package:nekoya_flutter/screens/productcoba.dart';
|
||||
import 'package:nekoya_flutter/screens/products.dart';
|
||||
|
||||
import 'package:nekoya_flutter/components/color_dot.dart';
|
||||
|
||||
class DetailsScreen extends StatelessWidget {
|
||||
const DetailsScreen({Key? key, required this.product}) : super(key: key);
|
||||
|
||||
final Product product;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFEFEFF2),
|
||||
appBar: AppBar(
|
||||
leading: const BackButton(color: Colors.black),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: CircleAvatar(
|
||||
backgroundColor: Colors.white,
|
||||
child: SvgPicture.asset(
|
||||
"assets/icons/Heart.svg",
|
||||
height: 20,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
product.image,
|
||||
height: MediaQuery.of(context).size.height * 0.4,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
const SizedBox(height: defaultPadding * 1.5),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.fromLTRB(defaultPadding,
|
||||
defaultPadding * 2, defaultPadding, defaultPadding),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(defaultBorderRadius * 3),
|
||||
topRight: Radius.circular(defaultBorderRadius * 3),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
product.title,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: defaultPadding),
|
||||
Text(
|
||||
"\$" + product.price.toString(),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
],
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: defaultPadding),
|
||||
child: Text(
|
||||
"A Henley shirt is a collarless pullover shirt, by a round neckline and a placket about 3 to 5 inches (8 to 13 cm) long and usually having 2–5 buttons.",
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Colors",
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
),
|
||||
const SizedBox(height: defaultPadding / 2),
|
||||
Row(
|
||||
children: const [
|
||||
ColorDot(
|
||||
color: Color(0xFFBEE8EA),
|
||||
isActive: false,
|
||||
),
|
||||
ColorDot(
|
||||
color: Color(0xFF141B4A),
|
||||
isActive: true,
|
||||
),
|
||||
ColorDot(
|
||||
color: Color(0xFFF4E5C3),
|
||||
isActive: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: defaultPadding * 2),
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: 200,
|
||||
height: 48,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: primaryColor,
|
||||
shape: const StadiumBorder()),
|
||||
child: const Text("Add to Cart"),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import 'package:nekoya_flutter/screens/cart.dart';
|
|||
import 'package:nekoya_flutter/screens/register.dart';
|
||||
import 'package:nekoya_flutter/screens/sessions.dart';
|
||||
import 'package:nekoya_flutter/screens/transactions.dart';
|
||||
import 'package:nekoya_flutter/screens/home_screen.dart';
|
||||
|
||||
class Menu extends StatefulWidget {
|
||||
const Menu({Key? key, required this.initialScreen}) : super(key: key);
|
||||
|
@ -65,14 +66,15 @@ class _MenuState extends State<Menu> {
|
|||
if (index == 0) {
|
||||
checkSessionExist().then((isLoggedIn) {
|
||||
if (isLoggedIn) {
|
||||
_selectedWidget = const Sessions();
|
||||
_selectedWidget = const Sessions();
|
||||
} else {
|
||||
_selectedIndex = oldSelectedIndex;
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => const Login()));
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (context) => const Login()));
|
||||
}
|
||||
});
|
||||
} else if (index == 1) {
|
||||
_selectedWidget = const Payment();
|
||||
_selectedWidget = const HomeScreen();
|
||||
} else if (index == 2) {
|
||||
_selectedWidget = const Products();
|
||||
} else if (index == 3) {
|
||||
|
@ -80,13 +82,14 @@ class _MenuState extends State<Menu> {
|
|||
} else if (index == 4) {
|
||||
checkSessionExist().then((isLoggedIn) {
|
||||
if (isLoggedIn) {
|
||||
_selectedWidget = const Transactions();
|
||||
_selectedWidget = const Transactions();
|
||||
} else {
|
||||
_selectedIndex = oldSelectedIndex;
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => const Login()));
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (context) => const Login()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
55
lib/components/new_arrival_products.dart
Normal file
55
lib/components/new_arrival_products.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:nekoya_flutter/screens/productcoba.dart';
|
||||
import 'package:nekoya_flutter/components/details_screen.dart';
|
||||
|
||||
import '../../../constants.dart';
|
||||
import 'product_card.dart';
|
||||
import 'section_title.dart';
|
||||
|
||||
class NewArrivalProducts extends StatelessWidget {
|
||||
const NewArrivalProducts({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: defaultPadding),
|
||||
child: SectionTitle(
|
||||
title: "New Arrival",
|
||||
pressSeeAll: () {},
|
||||
),
|
||||
),
|
||||
SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(
|
||||
parent: AlwaysScrollableScrollPhysics()),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: List.generate(
|
||||
demo_product.length,
|
||||
(index) => Padding(
|
||||
padding: const EdgeInsets.only(right: defaultPadding),
|
||||
child: ProductCard(
|
||||
title: demo_product[index].title,
|
||||
image: demo_product[index].image,
|
||||
price: demo_product[index].price,
|
||||
bgColor: demo_product[index].bgColor,
|
||||
press: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
DetailsScreen(product: demo_product[index]),
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
47
lib/components/popular_products.dart
Normal file
47
lib/components/popular_products.dart
Normal file
|
@ -0,0 +1,47 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:nekoya_flutter/screens/productcoba.dart';
|
||||
|
||||
import '../../../constants.dart';
|
||||
import 'product_card.dart';
|
||||
import 'section_title.dart';
|
||||
|
||||
class PopularProducts extends StatelessWidget {
|
||||
const PopularProducts({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: defaultPadding),
|
||||
child: SectionTitle(
|
||||
title: "Popular",
|
||||
pressSeeAll: () {},
|
||||
),
|
||||
),
|
||||
SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(
|
||||
parent: AlwaysScrollableScrollPhysics()),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: List.generate(
|
||||
demo_product.length,
|
||||
(index) => Padding(
|
||||
padding: const EdgeInsets.only(right: defaultPadding),
|
||||
child: ProductCard(
|
||||
title: demo_product[index].title,
|
||||
image: demo_product[index].image,
|
||||
price: demo_product[index].price,
|
||||
bgColor: demo_product[index].bgColor,
|
||||
press: () {},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
65
lib/components/product_card.dart
Normal file
65
lib/components/product_card.dart
Normal file
|
@ -0,0 +1,65 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../constants.dart';
|
||||
|
||||
class ProductCard extends StatelessWidget {
|
||||
const ProductCard({
|
||||
Key? key,
|
||||
required this.image,
|
||||
required this.title,
|
||||
required this.price,
|
||||
required this.press,
|
||||
required this.bgColor,
|
||||
}) : super(key: key);
|
||||
final String image, title;
|
||||
final VoidCallback press;
|
||||
final int price;
|
||||
final Color bgColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: press,
|
||||
child: Container(
|
||||
width: 154,
|
||||
padding: const EdgeInsets.all(defaultPadding / 2),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(defaultBorderRadius)),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor,
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(defaultBorderRadius)),
|
||||
),
|
||||
child: Image.asset(
|
||||
image,
|
||||
height: 132,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: defaultPadding / 2),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: defaultPadding / 4),
|
||||
Text(
|
||||
"\$" + price.toString(),
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||
|
||||
import 'package:nekoya_flutter/api/api.dart';
|
||||
import 'package:nekoya_flutter/data/cart.dart';
|
||||
import 'package:nekoya_flutter/screens/productcoba.dart';
|
||||
import 'package:nekoya_flutter/utils/utils.dart';
|
||||
|
||||
Widget makeDismissible({required context, required Widget child}) =>
|
||||
|
|
55
lib/components/search_form.dart
Normal file
55
lib/components/search_form.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
import '../../../constants.dart';
|
||||
|
||||
const OutlineInputBorder outlineInputBorder = OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
borderSide: BorderSide.none,
|
||||
);
|
||||
|
||||
class SearchForm extends StatelessWidget {
|
||||
const SearchForm({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Form(
|
||||
child: TextFormField(
|
||||
onSaved: (value) {},
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
hintText: "Search items...",
|
||||
border: outlineInputBorder,
|
||||
enabledBorder: outlineInputBorder,
|
||||
focusedBorder: outlineInputBorder,
|
||||
errorBorder: outlineInputBorder,
|
||||
prefixIcon: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: SvgPicture.asset("assets/icons/Search.svg"),
|
||||
),
|
||||
suffixIcon: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: defaultPadding, vertical: defaultPadding / 2),
|
||||
child: SizedBox(
|
||||
width: 48,
|
||||
height: 48,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: primaryColor,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
),
|
||||
onPressed: () {},
|
||||
child: SvgPicture.asset("assets/icons/Filter.svg"),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
34
lib/components/section_title.dart
Normal file
34
lib/components/section_title.dart
Normal file
|
@ -0,0 +1,34 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class SectionTitle extends StatelessWidget {
|
||||
const SectionTitle({
|
||||
Key? key,
|
||||
required this.title,
|
||||
required this.pressSeeAll,
|
||||
}) : super(key: key);
|
||||
final String title;
|
||||
final VoidCallback pressSeeAll;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.subtitle1!.copyWith(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: pressSeeAll,
|
||||
child: const Text(
|
||||
"See All",
|
||||
style: TextStyle(color: Colors.black54),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
7
lib/constants.dart
Normal file
7
lib/constants.dart
Normal file
|
@ -0,0 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
const Color primaryColor = Color(0xFFF67952);
|
||||
const Color bgColor = Color(0xFFFBFBFD);
|
||||
|
||||
const double defaultPadding = 16.0;
|
||||
const double defaultBorderRadius = 12.0;
|
69
lib/screens/home_screen.dart
Normal file
69
lib/screens/home_screen.dart
Normal file
|
@ -0,0 +1,69 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:nekoya_flutter/constants.dart';
|
||||
|
||||
import 'package:nekoya_flutter/components/categories.dart';
|
||||
import 'package:nekoya_flutter/components/new_arrival_products.dart';
|
||||
import 'package:nekoya_flutter/components/popular_products.dart';
|
||||
import 'package:nekoya_flutter/components/search_form.dart';
|
||||
|
||||
class HomeScreen extends StatelessWidget {
|
||||
const HomeScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
onPressed: () {},
|
||||
icon: SvgPicture.asset("assets/icons/menu.svg"),
|
||||
),
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset("assets/icons/Location.svg"),
|
||||
const SizedBox(width: defaultPadding / 2),
|
||||
Text(
|
||||
"15/2 New Texas",
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: SvgPicture.asset("assets/icons/Notification.svg"),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(
|
||||
parent: AlwaysScrollableScrollPhysics()),
|
||||
padding: const EdgeInsets.all(defaultPadding),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Explore",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headline4!
|
||||
.copyWith(fontWeight: FontWeight.w500, color: Colors.black),
|
||||
),
|
||||
const Text(
|
||||
"best Outfits for you",
|
||||
style: TextStyle(fontSize: 18),
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: defaultPadding),
|
||||
child: SearchForm(),
|
||||
),
|
||||
const Categories(),
|
||||
const NewArrivalProducts(),
|
||||
const PopularProducts(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
40
lib/screens/productcoba.dart
Normal file
40
lib/screens/productcoba.dart
Normal file
|
@ -0,0 +1,40 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class Product {
|
||||
final String image, title;
|
||||
final int price;
|
||||
final Color bgColor;
|
||||
|
||||
Product({
|
||||
required this.image,
|
||||
required this.title,
|
||||
required this.price,
|
||||
this.bgColor = const Color(0xFFEFEFF2),
|
||||
});
|
||||
}
|
||||
|
||||
List<Product> demo_product = [
|
||||
Product(
|
||||
image: "assets/Product_2.webp",
|
||||
title: "Long Sleeve Shirts",
|
||||
price: 165,
|
||||
bgColor: const Color(0xFFFEFBF9),
|
||||
),
|
||||
Product(
|
||||
image: "assets/Product_1.webp",
|
||||
title: "Casual Henley Shirts",
|
||||
price: 99,
|
||||
),
|
||||
Product(
|
||||
image: "assets/Product_2.webp",
|
||||
title: "Curved Hem Shirts",
|
||||
price: 180,
|
||||
bgColor: const Color(0xFFF8FEFB),
|
||||
),
|
||||
Product(
|
||||
image: "assets/Product_3.webp",
|
||||
title: "Casual Nolin",
|
||||
price: 149,
|
||||
bgColor: const Color(0xFFEEEEED),
|
||||
),
|
||||
];
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:responsify/responsify.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
import 'package:nekoya_flutter/api/api.dart';
|
||||
import 'package:nekoya_flutter/components/product_box.dart';
|
||||
import 'package:nekoya_flutter/components/product_detail.dart';
|
||||
|
@ -24,41 +23,45 @@ class _ProductsState extends State<Products> {
|
|||
backgroundColor: const Color(0xff212226),
|
||||
),
|
||||
body: ResponsiveUiWidget(
|
||||
targetOlderComputers: true,
|
||||
builder: (context, deviceInformation) {
|
||||
return FutureBuilder<dynamic>(
|
||||
future: getProducts(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var data = snapshot.data;
|
||||
return GridView.count(
|
||||
crossAxisCount: deviceInformation.orientation == Orientation.portrait ? 2 : 5,
|
||||
children: List.generate(data!.length, (index) {
|
||||
return ProductBox(
|
||||
imageUrl: "https://nekoya.moe.team/img/${data[index]['IMAGE']}",
|
||||
targetOlderComputers: true,
|
||||
builder: (context, deviceInformation) {
|
||||
return FutureBuilder<dynamic>(
|
||||
future: getProducts(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var data = snapshot.data;
|
||||
return GridView.count(
|
||||
crossAxisCount:
|
||||
deviceInformation.orientation == Orientation.portrait
|
||||
? 2
|
||||
: 5,
|
||||
children: List.generate(data!.length, (index) {
|
||||
return ProductBox(
|
||||
imageUrl:
|
||||
"https://nekoya.moe.team/img/${data[index]['IMAGE']}",
|
||||
title: data[index]['TITLE'],
|
||||
callback: () {
|
||||
showModalBottomSheet(
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
context: context,
|
||||
builder: (context) => productDetail(context, data[index]['ID']),
|
||||
builder: (context) =>
|
||||
productDetail(context, data[index]['ID']),
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Color(0xff8B0000),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
),
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Color(0xff8B0000),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
21
pubspec.lock
21
pubspec.lock
|
@ -167,6 +167,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
flutter_svg:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -268,6 +275,20 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
path_drawing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_drawing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
path_parsing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_parsing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
path_provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
22
pubspec.yaml
22
pubspec.yaml
|
@ -40,6 +40,7 @@ dependencies:
|
|||
lottie: ^1.3.0
|
||||
responsify: ^1.0.0+5
|
||||
shared_preferences: ^2.0.13
|
||||
flutter_svg: ^1.0.3
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.1
|
||||
|
@ -75,17 +76,16 @@ flutter:
|
|||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
fonts:
|
||||
- family: Gordita
|
||||
fonts:
|
||||
- asset: assets/fonts/Gordita_Regular.otf
|
||||
- asset: assets/fonts/Gordita_Medium.otf
|
||||
weight: 500
|
||||
- asset: assets/fonts/Gordita_Bold.otf
|
||||
weight: 700
|
||||
- asset: assets/fonts/Gordita_Light.otf
|
||||
weight: 300
|
||||
#
|
||||
# For details regarding fonts from package dependencies,
|
||||
# see https://flutter.dev/custom-fonts/#from-packages
|
||||
|
|
Loading…
Reference in a new issue