proxibuy/lib/presentation/ui/screens/home/home_screen.dart

699 lines
28 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:proxibuy/core/gen/assets.gen.dart';
import 'package:proxibuy/core/routes/app_router.dart';
import 'package:proxibuy/core/utils/empty_space.dart';
import 'package:proxibuy/presentation/providers/cubit/them_mode_cubit.dart';
import 'package:proxibuy/presentation/ui/theme/colors.dart';
import 'package:proxibuy/presentation/ui/theme/responsive.dart';
import 'package:proxibuy/presentation/ui/widgets/carousel/carousel_slider_widget.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Responsive(context)
.builder(mobile: mobile(context), desktop: desktop(context));
}
Scaffold desktop(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 1600),
child: Column(
children: [
12.h,
titleDivider(context, title: 'what\'s on your mind?', top: 16),
SizedBox(
width: double.infinity,
height: 40,
child: ListView.builder(
itemCount: 20,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 10),
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return Container(
width: 200,
height: 40,
margin: EdgeInsets.symmetric(horizontal: 6),
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Theme.of(context).colorScheme.surface,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.car_crash),
8.w,
Text('Category')
],
),
);
},
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
titleDivider(context,
title: 'Top 10 Discount & Offers'),
CarouselSliderWidget<String>(
items: ['1', '2', '3', '4'],
height: 320,
viewportFraction: 0.9,
onPageBuilder: (context, item) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
'https://pixcap.com/cdn/library/templates/f1ee999f-4f9e-4b5d-83b5-51d04681a999/thumbnail/9158b87d-1079-4973-9514-ee4ada0adf54_transparent_1422_800.webp',
fit: BoxFit.cover,
width: double.infinity,
),
);
},
),
],
),
),
12.w,
Expanded(
child: flashSales(context),
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: seasonalDiscounts(context)),
12.w,
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
titleDivider(context, title: 'special discount'),
CarouselSliderWidget<String>(
items: ['1', '2', '3', '4'],
height: 280,
viewportFraction: 0.9,
onPageBuilder: (context, item) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
'https://pixcap.com/cdn/library/templates/f1ee999f-4f9e-4b5d-83b5-51d04681a999/thumbnail/9158b87d-1079-4973-9514-ee4ada0adf54_transparent_1422_800.webp',
fit: BoxFit.cover,
width: double.infinity,
),
);
},
),
],
)),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
titleDivider(context, title: 'special discount'),
CarouselSliderWidget<String>(
items: ['1', '2', '3', '4'],
height: 280,
viewportFraction: 0.9,
onPageBuilder: (context, item) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
'https://pixcap.com/cdn/library/templates/f1ee999f-4f9e-4b5d-83b5-51d04681a999/thumbnail/9158b87d-1079-4973-9514-ee4ada0adf54_transparent_1422_800.webp',
fit: BoxFit.cover,
width: double.infinity,
),
);
},
),
],
)),
12.w,
Expanded(child: firstPurchaseDiscount(context)),
],
),
64.h
],
),
),
),
),
);
}
Scaffold mobile(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Padding(
padding: const EdgeInsets.only(left: 2.0),
child: SelectableText(
"Proxibuy",
style: Theme.of(context).textTheme.headlineSmall,
),
),
actions: [
IconButton(
icon: Assets.icon.outline.notificationBing
.svg(color: Theme.of(context).colorScheme.onSurface),
onPressed: () {},
),
12.w,
IconButton(
icon: Icon(Icons.brightness_6),
onPressed: () {
context.read<ThemModeCubit>().changeTheme();
},
),
10.w
],
),
body: SingleChildScrollView(
physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
searchBar(context),
categories(context),
titleDivider(context, title: 'Top 10 Discount & Offers'),
CarouselSliderWidget<String>(
items: ['1', '2', '3', '4'],
height: 180,
viewportFraction: 0.8,
onPageBuilder: (context, item) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
'https://pixcap.com/cdn/library/templates/f1ee999f-4f9e-4b5d-83b5-51d04681a999/thumbnail/9158b87d-1079-4973-9514-ee4ada0adf54_transparent_1422_800.webp',
fit: BoxFit.cover,
width: double.infinity,
),
);
},
),
flashSales(context, top: 12),
titleDivider(context, title: 'special discount'),
CarouselSliderWidget<String>(
items: ['1', '2', '3', '4'],
height: 180,
viewportFraction: 0.8,
onPageBuilder: (context, item) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
'https://pixcap.com/cdn/library/templates/f1ee999f-4f9e-4b5d-83b5-51d04681a999/thumbnail/9158b87d-1079-4973-9514-ee4ada0adf54_transparent_1422_800.webp',
fit: BoxFit.cover,
width: double.infinity,
),
);
},
),
seasonalDiscounts(context, top: 12),
titleDivider(context, title: 'Crafting something for you'),
CarouselSliderWidget<String>(
items: ['1', '2', '3', '4'],
height: 180,
viewportFraction: 0.8,
onPageBuilder: (context, item) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
'https://pixcap.com/cdn/library/templates/f1ee999f-4f9e-4b5d-83b5-51d04681a999/thumbnail/9158b87d-1079-4973-9514-ee4ada0adf54_transparent_1422_800.webp',
fit: BoxFit.cover,
width: double.infinity,
),
);
},
),
firstPurchaseDiscount(context),
12.h
],
),
),
);
}
Column firstPurchaseDiscount(BuildContext context) {
return Column(
children: [
titleDivider(context, title: 'First Purchase Discount'),
SizedBox(
width: double.infinity,
height: 280,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 20,
padding: EdgeInsets.symmetric(horizontal: 16),
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return Container(
width: 180,
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.only(
topLeft: index == 0 ? Radius.circular(16) : Radius.zero,
bottomLeft:
index == 0 ? Radius.circular(16) : Radius.zero,
topRight:
index == 20 - 1 ? Radius.circular(16) : Radius.zero,
bottomRight: index == 20 - 1
? Radius.circular(16)
: Radius.zero)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
'https://s3-alpha-sig.figma.com/img/6ec2/c17a/beca4d2eb02da53e80d47f73d5f6b56d?Expires=1740960000&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=VvgWny6Sfh-HI0Yp2stzKejafivtWKDI9I5FKuSAQ8VqNLgiT4c5zB5m-PX174NFrSDvkocDlUIZ33gM~hrAafD8UreEvYfs30sB0ZrIPR7kSPcms~d9ArYJRsXSQ7w8-cv~RHWruGfbw462CrOdvJadQ3ZReRkK9CJsPCg2EcU9mr~hlcyx84QxGx0rw~FdBvHt99pzX0gDMWpr0kC9Om-eM45Fylmcb91d5AGh2sxtf0NXyNwt83jjfKC-VOZHt5wbjbZq3NQNGmrwWTwzLOauhjtgOsC32EbsPim3O~8CrKJAQ-TVOSXN4B15ygiFxZ1WX2z6l-LnjFghzv9Z3w__',
width: double.infinity,
height: 120,
fit: BoxFit.cover,
),
),
),
12.h,
SelectableText(
'McDonald\'s',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
12.h,
SelectableText('Fast food',
maxLines: 1,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
overflow: TextOverflow.ellipsis,
)),
8.h,
SelectableText('Up to 20% Off',
maxLines: 1,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
overflow: TextOverflow.ellipsis,
)),
8.h,
Row(
children: [
Icon(
Icons.star_border_outlined,
color: semanticGreen,
),
4.w,
Text('4.5'),
],
)
],
),
);
},
),
),
],
);
}
Column seasonalDiscounts(BuildContext context, {final double top = 32}) {
return Column(
children: [
titleDivider(context, title: 'Seasonal Discount', top: top),
SizedBox(
width: double.infinity,
height: 100 * 2 + 12,
child: GridView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 16),
physics: BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 16,
crossAxisSpacing: 12,
childAspectRatio: 0.3,
crossAxisCount: 2),
itemBuilder: (context, index) {
return InkWell(
onTap: () {
context.go(AppRouter.product);
},
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface),
child: Row(
children: [
Image.network(
'https://s3-alpha-sig.figma.com/img/55dd/f119/e880815733401c0400dc01734b64e83a?Expires=1740960000&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=HtKhelOfFUI1gplOzBHtfDP4ljCPECuypXWNc88VVBfYaQ2knCk0qPFwd4mjcH7Trru2W8S4hpDUeo-ztViRi~83USuULrSE0558MtBC~3TjS5S~Jm7eaDQO3YtvnsRtPK2xDamOJU80Xnkq0YPPkB~EVb8jVKF-b8JF2jdjEwon6fcltZDb7jTFJU8L9pYQQAhFxRV1QC8dOwnTT1zknm9iDNRDVGSj~VKwPpQX7daYzAf7b6DuLF4sk7DmX2fDdgF54pcYZjc1UOoubraM-sf-RKnh2JD8Vl~XK9-drzg8~t9CT99dxxHYp6udCLlya~dHNhIYjd5R4anoDQQLPg__',
width: 100,
height: 100,
fit: BoxFit.cover,
),
8.w,
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText(
'boots',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(overflow: TextOverflow.ellipsis),
maxLines: 1,
),
12.h,
Row(
children: [
Icon(
Icons.shopping_bag_outlined,
size: 16,
),
8.w,
Expanded(
child: SelectableText(
'Columbia Sportswear',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
),
],
),
8.h,
Row(
children: [
Icon(
CupertinoIcons.ticket,
size: 16,
),
8.w,
Expanded(
child: SelectableText(
'22 - 35% off',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(
color: semanticRed,
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
),
],
)
],
),
))
],
),
),
),
);
},
),
),
],
);
}
Column flashSales(BuildContext context, {double top = 32}) {
return Column(
children: [
titleDivider(context, title: 'Flash Sale', top: top),
SizedBox(
width: double.infinity,
height: 348,
child: ListView.builder(
itemCount: 20,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 10),
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return InkWell(
onTap: () {
context.go(AppRouter.product);
},
child: Container(
width: 200,
margin: EdgeInsets.symmetric(horizontal: 6),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Theme.of(context).colorScheme.surface,
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Icon(
Icons.timer_outlined,
color: semanticRed,
size: 32,
),
12.w,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText(
'Limited time deal',
style:
Theme.of(context).textTheme.titleMedium,
),
SelectableText('08: 35”:48',
style: Theme.of(context)
.textTheme
.titleSmall
?.copyWith(color: semanticRed))
],
)
],
),
),
AspectRatio(
aspectRatio: 16 / 9,
child: Image.network(
'https://s3-alpha-sig.figma.com/img/7919/da3d/6e638d21e4b8cec7cda36bd4fdec2012?Expires=1740960000&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=OiH30jVJjAo~EZTdnnGakp0gZzdPFWPHrthl4iSPv8X7d-pGh35sycz42ZvNekboa2Hyp22O4mx8YUOn~SUVHuIKsxmRblfb-vlGfCwqg9xZL16R8pQV6V~v8FpAvFIQL1id6EgfuL4VcnADASZ7m2XjJ6CDNd~c~-k5N4MwcKUxvFNBFt7OhLNdB9bXYuAT~sfiQAai3B~JDaikS0SD48irIGaXeBi4KNAtLlFGrrGDK3KLbyfetvXwRF5ml7G0RBzEbR26WvwkgdX39B7GjCxjQzBvExI6V-JM76oc2YZiSbQIE89Qpvu2ErP77Kc6dW4aOTPGQ5RJXxPzj2vWDA__',
width: double.infinity,
height: 100,
fit: BoxFit.cover,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText(
'Amul Cheese Slices',
style: Theme.of(context)
.textTheme
.titleLarge
?.copyWith(
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
12.h,
Row(
children: [
Icon(Icons.location_on_outlined),
8.w,
Expanded(
child: SelectableText(
'Fresno (750m away)',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
))
],
),
8.h,
Row(
children: [
Icon(Icons.monetization_on_outlined),
8.w,
Expanded(
child: SelectableText(
'70 \$ - 53 \$ (13% off)',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
))
],
),
8.h,
Center(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: semanticGreen,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(16))),
onPressed: () {},
child: Text(
'Reservation',
)),
)
],
),
)
],
)),
);
},
),
),
],
);
}
Column categories(BuildContext context) {
return Column(
children: [
titleDivider(context, title: 'what\'s on your mind?', top: 16),
SizedBox(
width: double.infinity,
height: 64,
child: ListView.builder(
itemCount: 20,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 10),
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return Container(
width: 64,
height: 64,
margin: EdgeInsets.symmetric(horizontal: 6),
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Theme.of(context).colorScheme.surface,
),
child: Center(
child: Icon(Icons.abc),
),
);
},
),
),
],
);
}
Widget searchBar(
BuildContext context,
) {
final defaultBorder = OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide:
BorderSide(color: Theme.of(context).colorScheme.surface, width: 2));
return Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Flexible(
child: Container(
constraints: BoxConstraints(maxWidth: 800),
child: TextField(
textInputAction: TextInputAction.search,
onSubmitted: (value) {
print(value);
},
decoration: InputDecoration(
hintText: 'what are you looking for?',
suffixIcon: Padding(
padding: const EdgeInsets.all(12.0),
child: Assets.icon.outline.search.svg(
color: Theme.of(context).colorScheme.onSurface,
width: 16,
height: 16),
),
enabledBorder: defaultBorder,
border: defaultBorder),
),
)),
],
),
);
}
Column titleDivider(BuildContext context,
{required final String title,
final double top = 32,
final double bottom = 16}) {
return Column(
children: [
top.h,
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
SelectableText(
title,
style: Theme.of(context).textTheme.titleMedium,
),
12.w,
Expanded(
child: Divider(
color: Theme.of(context).colorScheme.onSurface,
)),
],
),
),
bottom.h,
],
);
}
}