create product page for mobile.
This commit is contained in:
parent
a8c8fa88b9
commit
09d4553e73
|
|
@ -1,5 +1,6 @@
|
||||||
|
#Mon Feb 17 08:57:28 IRST 2025
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
|
|
||||||
|
|
|
||||||
|
|
@ -4,75 +4,102 @@ import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:proxibuy/presentation/providers/cubit/user_info_cubit.dart';
|
import 'package:proxibuy/presentation/providers/cubit/user_info_cubit.dart';
|
||||||
import 'package:proxibuy/presentation/ui/screens/auth/auth_page.dart';
|
import 'package:proxibuy/presentation/ui/screens/auth/auth_page.dart';
|
||||||
|
import 'package:proxibuy/presentation/ui/screens/home/explore_screen.dart';
|
||||||
import 'package:proxibuy/presentation/ui/screens/home/home_page.dart';
|
import 'package:proxibuy/presentation/ui/screens/home/home_page.dart';
|
||||||
|
import 'package:proxibuy/presentation/ui/screens/home/home_screen.dart';
|
||||||
|
import 'package:proxibuy/presentation/ui/screens/home/setting_screen.dart';
|
||||||
|
import 'package:proxibuy/presentation/ui/screens/product/product_page.dart';
|
||||||
|
|
||||||
class AppRouter {
|
class AppRouter {
|
||||||
static final initial = '/';
|
static final initial = '/';
|
||||||
static final home = '/home';
|
|
||||||
static final explore = '/explore';
|
static final explore = '/explore';
|
||||||
static final setting = '/settings';
|
static final setting = '/settings';
|
||||||
|
static final product = '/product';
|
||||||
|
|
||||||
|
static List<String> home = [initial, explore, setting];
|
||||||
|
|
||||||
static final GlobalKey<NavigatorState> navigatorKey =
|
static final GlobalKey<NavigatorState> navigatorKey =
|
||||||
GlobalKey<NavigatorState>();
|
GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
GoRouter createRouter = GoRouter(
|
static GoRouter createRouter = GoRouter(
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
initialLocation: home,
|
initialLocation: initial,
|
||||||
|
routes: [
|
||||||
|
// GoRoute(
|
||||||
|
// path: initial,
|
||||||
|
// builder: (BuildContext context, GoRouterState state) {
|
||||||
|
// return BlocConsumer<UserInfoCubit, UserInfoState>(
|
||||||
|
// listener: (context, state) {
|
||||||
|
// if (state is UserInfoSuccess || state is UserInfoFail) {
|
||||||
|
// FlutterNativeSplash.remove();
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// builder: (context, state) {
|
||||||
|
// if (state is UserInfoSuccess) {
|
||||||
|
// return const HomePage();
|
||||||
|
// } else {
|
||||||
|
// return const AuthPage();
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// routes: <RouteBase>[
|
||||||
|
// GoRoute(
|
||||||
|
// path: product,
|
||||||
|
// builder: (BuildContext context, GoRouterState state) {
|
||||||
|
// return ProductPage();
|
||||||
|
// },
|
||||||
|
// routes: <RouteBase>[],
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
|
||||||
|
StatefulShellRoute.indexedStack(
|
||||||
|
builder: (context, state, navigationShell) =>
|
||||||
|
BlocBuilder<UserInfoCubit, UserInfoState>(
|
||||||
|
builder: (context, userState) {
|
||||||
|
if (userState is UserInfoSuccess) {
|
||||||
|
if (home.contains(state.fullPath)) {
|
||||||
|
return HomePage(child: navigationShell);
|
||||||
|
} else {
|
||||||
|
return navigationShell;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return AuthPage();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
branches: [
|
||||||
|
StatefulShellBranch(routes: [
|
||||||
|
GoRoute(
|
||||||
|
path: initial,
|
||||||
|
builder: (context, state) {
|
||||||
|
return HomeScreen();
|
||||||
|
},
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: home,
|
path: product,
|
||||||
builder: (BuildContext context, GoRouterState state) {
|
builder: (BuildContext context, GoRouterState state) {
|
||||||
return BlocConsumer<UserInfoCubit, UserInfoState>(
|
return ProductPage();
|
||||||
listener: (context, state) {
|
|
||||||
if (state is UserInfoSuccess || state is UserInfoFail) {
|
|
||||||
FlutterNativeSplash.remove();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
builder: (context, state) {
|
|
||||||
if (state is UserInfoSuccess) {
|
|
||||||
return const HomePage();
|
|
||||||
} else {
|
|
||||||
return const AuthPage();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
routes: <RouteBase>[],
|
routes: <RouteBase>[],
|
||||||
),
|
),
|
||||||
// StatefulShellRoute.indexedStack(
|
]),
|
||||||
// builder: (context, state, navigationShell) =>
|
]),
|
||||||
// BlocBuilder<UserInfoCubit, UserInfoState>(
|
StatefulShellBranch(routes: [
|
||||||
// builder: (context, state) {
|
GoRoute(
|
||||||
// if (state is UserInfoSuccess) {
|
path: explore,
|
||||||
// return CustomBottomNav(child: navigationShell);
|
builder: (context, state) => ExploreScreen(),
|
||||||
// } else {
|
),
|
||||||
// return AuthPage();
|
]),
|
||||||
// }
|
StatefulShellBranch(routes: [
|
||||||
// },
|
GoRoute(
|
||||||
// ),
|
path: setting,
|
||||||
// branches: [
|
builder: (context, state) => SettingScreen(),
|
||||||
// StatefulShellBranch(routes: [
|
),
|
||||||
// GoRoute(
|
]),
|
||||||
// path: initial,
|
],
|
||||||
// builder: (context, state) {
|
),
|
||||||
// return HomeScreen();
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ]),
|
|
||||||
// StatefulShellBranch(routes: [
|
|
||||||
// GoRoute(
|
|
||||||
// path: explore,
|
|
||||||
// builder: (context, state) => ExploreScreen(),
|
|
||||||
// ),
|
|
||||||
// ]),
|
|
||||||
// StatefulShellBranch(routes: [
|
|
||||||
// GoRoute(
|
|
||||||
// path: setting,
|
|
||||||
// builder: (context, state) => SettingScreen(),
|
|
||||||
// ),
|
|
||||||
// ]),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class MyCustomScrollBehavior extends MaterialScrollBehavior {
|
||||||
|
// Override behavior methods and getters like dragDevices
|
||||||
|
@override
|
||||||
|
Set<PointerDeviceKind> get dragDevices => {
|
||||||
|
PointerDeviceKind.touch,
|
||||||
|
PointerDeviceKind.mouse,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||||
import 'package:proxibuy/core/routes/app_router.dart';
|
import 'package:proxibuy/core/routes/app_router.dart';
|
||||||
|
import 'package:proxibuy/core/utils/my_custom_scroll_behavior.dart';
|
||||||
import 'package:proxibuy/data/storage/shared_preferences_helper.dart';
|
import 'package:proxibuy/data/storage/shared_preferences_helper.dart';
|
||||||
import 'package:proxibuy/presentation/providers/cubit/them_mode_cubit.dart';
|
import 'package:proxibuy/presentation/providers/cubit/them_mode_cubit.dart';
|
||||||
import 'package:proxibuy/presentation/providers/cubit/user_info_cubit.dart';
|
import 'package:proxibuy/presentation/providers/cubit/user_info_cubit.dart';
|
||||||
|
|
@ -43,11 +44,13 @@ class _MyAppState extends State<MyApp> {
|
||||||
return BlocBuilder<ThemModeCubit, ThemeMode>(
|
return BlocBuilder<ThemModeCubit, ThemeMode>(
|
||||||
builder: (context, themeState) {
|
builder: (context, themeState) {
|
||||||
return MaterialApp.router(
|
return MaterialApp.router(
|
||||||
routerConfig: AppRouter().createRouter,
|
routerConfig: AppRouter.createRouter,
|
||||||
|
restorationScopeId: 'app',
|
||||||
title: 'Proxibuy',
|
title: 'Proxibuy',
|
||||||
theme: appTheme,
|
theme: appTheme,
|
||||||
darkTheme: darkTheme,
|
darkTheme: darkTheme,
|
||||||
themeMode: themeState,
|
themeMode: themeState,
|
||||||
|
scrollBehavior: MyCustomScrollBehavior(),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,10 @@ class _AuthPageState extends State<AuthPage> {
|
||||||
body: Responsive(context).builder(
|
body: Responsive(context).builder(
|
||||||
mobile: onBoarding
|
mobile: onBoarding
|
||||||
? carousle(
|
? carousle(
|
||||||
withNavs: true, autoPlay: false, enableInfiniteScroll: false)
|
withNavs: true,
|
||||||
|
autoPlay: false,
|
||||||
|
enableInfiniteScroll: false,
|
||||||
|
)
|
||||||
: auth(context),
|
: auth(context),
|
||||||
tablet: Row(
|
tablet: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -53,7 +56,7 @@ class _AuthPageState extends State<AuthPage> {
|
||||||
withNavs: false,
|
withNavs: false,
|
||||||
autoPlay: true,
|
autoPlay: true,
|
||||||
enableInfiniteScroll: true,
|
enableInfiniteScroll: true,
|
||||||
height: MediaQuery.sizeOf(context).height * 0.8),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
|
@ -71,7 +74,7 @@ class _AuthPageState extends State<AuthPage> {
|
||||||
withNavs: false,
|
withNavs: false,
|
||||||
autoPlay: true,
|
autoPlay: true,
|
||||||
enableInfiniteScroll: true,
|
enableInfiniteScroll: true,
|
||||||
height: MediaQuery.sizeOf(context).height * 0.8),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
|
@ -182,13 +185,13 @@ class _AuthPageState extends State<AuthPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
CarouselSliderWidget<OnboardingBannerModel> carousle(
|
CarouselSliderWidget<OnboardingBannerModel> carousle({
|
||||||
{required final bool withNavs,
|
required final bool withNavs,
|
||||||
required final bool autoPlay,
|
required final bool autoPlay,
|
||||||
required final bool enableInfiniteScroll,
|
required final bool enableInfiniteScroll,
|
||||||
double? height}) {
|
}) {
|
||||||
return CarouselSliderWidget<OnboardingBannerModel>(
|
return CarouselSliderWidget<OnboardingBannerModel>(
|
||||||
height: height ?? MediaQuery.sizeOf(context).height,
|
height: MediaQuery.sizeOf(context).height * 0.8,
|
||||||
items: [
|
items: [
|
||||||
OnboardingBannerModel(
|
OnboardingBannerModel(
|
||||||
image: Assets.image.onboarding.banner1,
|
image: Assets.image.onboarding.banner1,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import 'package:bottom_navy_bar/bottom_navy_bar.dart';
|
import 'package:bottom_navy_bar/bottom_navy_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/gen/assets.gen.dart';
|
||||||
|
import 'package:proxibuy/core/routes/app_router.dart';
|
||||||
import 'package:proxibuy/core/utils/empty_space.dart';
|
import 'package:proxibuy/core/utils/empty_space.dart';
|
||||||
import 'package:proxibuy/data/models/screen_model.dart';
|
import 'package:proxibuy/data/models/screen_model.dart';
|
||||||
import 'package:proxibuy/presentation/providers/cubit/them_mode_cubit.dart';
|
import 'package:proxibuy/presentation/providers/cubit/them_mode_cubit.dart';
|
||||||
|
|
@ -12,7 +14,9 @@ import 'package:proxibuy/presentation/ui/theme/responsive.dart';
|
||||||
import 'package:proxibuy/presentation/ui/theme/theme.dart';
|
import 'package:proxibuy/presentation/ui/theme/theme.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
const HomePage({super.key});
|
final Widget child;
|
||||||
|
|
||||||
|
const HomePage({super.key, required this.child});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<HomePage> createState() => _HomePageState();
|
State<HomePage> createState() => _HomePageState();
|
||||||
|
|
@ -25,6 +29,7 @@ class _HomePageState extends State<HomePage> {
|
||||||
ScreenModel(title: 'Explore', icon: Assets.icon.outline.map),
|
ScreenModel(title: 'Explore', icon: Assets.icon.outline.map),
|
||||||
ScreenModel(title: 'Settings', icon: Assets.icon.outline.setting),
|
ScreenModel(title: 'Settings', icon: Assets.icon.outline.setting),
|
||||||
];
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Responsive(context).builder(
|
return Responsive(context).builder(
|
||||||
|
|
@ -37,26 +42,6 @@ class _HomePageState extends State<HomePage> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
mobile: Scaffold(
|
mobile: Scaffold(
|
||||||
appBar: AppBar(
|
|
||||||
title: Text(
|
|
||||||
"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();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: body(),
|
body: body(),
|
||||||
bottomNavigationBar: bottomNavigationBar(context),
|
bottomNavigationBar: bottomNavigationBar(context),
|
||||||
),
|
),
|
||||||
|
|
@ -207,17 +192,24 @@ class _HomePageState extends State<HomePage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexedStack body() {
|
Widget body() {
|
||||||
return IndexedStack(
|
return widget.child;
|
||||||
sizing: StackFit.expand,
|
|
||||||
index: selectedIndex,
|
|
||||||
children: [HomeScreen(), ExploreScreen(), SettingScreen()],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onItemTapped(BuildContext context, int index) {
|
void _onItemTapped(BuildContext context, int index) {
|
||||||
setState(() {
|
setState(() {
|
||||||
selectedIndex = index;
|
selectedIndex = index;
|
||||||
});
|
});
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
context.go(AppRouter.initial);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
context.go(AppRouter.explore);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
context.go(AppRouter.setting);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,14 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.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/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/theme/responsive.dart';
|
||||||
|
import 'package:proxibuy/presentation/ui/widgets/carousel/carousel_slider_widget.dart';
|
||||||
|
|
||||||
class HomeScreen extends StatefulWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
const HomeScreen({super.key});
|
const HomeScreen({super.key});
|
||||||
|
|
@ -17,31 +25,623 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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(
|
final defaultBorder = OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
borderSide:
|
borderSide:
|
||||||
BorderSide(color: Theme.of(context).colorScheme.surface, width: 2));
|
BorderSide(color: Theme.of(context).colorScheme.surface, width: 2));
|
||||||
return Responsive(context).builder(
|
|
||||||
mobile: Scaffold(
|
return Padding(
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
children: [
|
||||||
children: <Widget>[
|
|
||||||
// ElevatedButton(
|
|
||||||
// onPressed: () async {
|
|
||||||
// final notifPer = await requestNotificationPermission();
|
|
||||||
|
|
||||||
// if (notifPer) {
|
|
||||||
// if (kIsWeb) {
|
|
||||||
// NotificationServiceWeb.showNotification();
|
|
||||||
// } else {
|
|
||||||
// await NotificationSrviceAndroid.showCustomNotification();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// child: Text('Show Notification')),
|
|
||||||
|
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: BoxConstraints(maxWidth: 800),
|
constraints: BoxConstraints(maxWidth: 800),
|
||||||
|
|
@ -65,10 +665,34 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
)),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
desktop: Scaffold(
|
bottom.h,
|
||||||
body: SizedBox(),
|
],
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,707 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:proxibuy/core/utils/empty_space.dart';
|
||||||
|
import 'package:proxibuy/presentation/ui/theme/colors.dart';
|
||||||
|
import 'package:proxibuy/presentation/ui/theme/responsive.dart';
|
||||||
|
|
||||||
|
class ProductPage extends StatelessWidget {
|
||||||
|
const ProductPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DefaultTabController(
|
||||||
|
length: 2,
|
||||||
|
child: Responsive(context).builder(
|
||||||
|
mobile: Scaffold(
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 46),
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 0.95,
|
||||||
|
child: Image.network(
|
||||||
|
'https://s3-alpha-sig.figma.com/img/4361/9bde/26f7810ea7f22d8aa59a907d378c16ff?Expires=1740960000&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=DIm2QGXae9cxWDNV2UoJd4JWpvvmL~qKmEefvrtVw9XwKTVHwcfgqR3-s-5s7jqsTiT0iWDsYY10MeuSf2d4xXx9uTra~QEj3LbO1x4cRv4DBDJ-wkLGxliV07HVWl~CMl1MhzXyfUvWkrR30QQ5x3IslvBpfulMj88AYU5l97XPaNMOcMT8YqErdCdpiqdXBM9L2vUpCUbZGH~SfKCQyl1QcNhuCBTPODPWcK6kGU1ell3qwXC0-4JcLiiR-Kdo9asKy495iVtQ584fyZAdeN1R4oJnVGnAlUyN2HRQh6j518FCrJIzr7O0JajvrmwZ7j48nXjWPtG0SGp8Lq4l6A__',
|
||||||
|
width: double.infinity,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
top: 32,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
context.pop();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.surface
|
||||||
|
.withAlpha(180),
|
||||||
|
borderRadius: BorderRadius.circular(8)),
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
child: Icon(Icons.arrow_back_ios_new_rounded),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
context.pop();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.surface
|
||||||
|
.withAlpha(180),
|
||||||
|
borderRadius: BorderRadius.circular(8)),
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
child: Icon(Icons.bookmark_add_rounded),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Positioned(
|
||||||
|
right: 0,
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
child: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 90,
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: 20,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
padding: EdgeInsets.all(4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.surface
|
||||||
|
.withAlpha(200),
|
||||||
|
borderRadius: BorderRadius.circular(8)),
|
||||||
|
child: Image.network(
|
||||||
|
'https://static.vecteezy.com/system/resources/previews/021/275/832/non_2x/running-shoes-illustration-with-fire-shape-yellow-and-red-isolated-on-transparan-background-free-png.png'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: TabBar(
|
||||||
|
tabs: [
|
||||||
|
Tab(text: 'Item'),
|
||||||
|
Tab(text: 'Shop'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 1500,
|
||||||
|
child: TabBarView(
|
||||||
|
children: [itemTab(context), shopTab(context)],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
desktop: Scaffold(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget itemTab(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'Philadelphia Honey Pecan Cream Cheese Spread, 7.5 oz Tub',
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall,
|
||||||
|
),
|
||||||
|
4.h,
|
||||||
|
SelectableText(
|
||||||
|
'Brand: Philadelphia',
|
||||||
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_half_rounded),
|
||||||
|
8.w,
|
||||||
|
Text(
|
||||||
|
'4.8',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
SelectableText(
|
||||||
|
'Currently available. 23 remain',
|
||||||
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
|
),
|
||||||
|
12.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.warning_amber_rounded),
|
||||||
|
8.w,
|
||||||
|
Text(
|
||||||
|
'Expire: 5 days',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
Divider(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
SelectableText(
|
||||||
|
'Nutrition summary',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
|
4.h,
|
||||||
|
SelectableText(
|
||||||
|
'7 servings per container | 2 Tbsp (33g)',
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: BorderRadius.circular(16)),
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||||
|
child: Flex(
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
flex: 1,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'80',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelLarge
|
||||||
|
?.copyWith(color: Theme.of(context).primaryColor),
|
||||||
|
),
|
||||||
|
SelectableText('Calories',
|
||||||
|
style: Theme.of(context).textTheme.labelLarge),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
flex: 1,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'100mg',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelLarge
|
||||||
|
?.copyWith(color: Theme.of(context).primaryColor),
|
||||||
|
),
|
||||||
|
SelectableText('Sodium',
|
||||||
|
style: Theme.of(context).textTheme.labelLarge),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
flex: 1,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'0g',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelLarge
|
||||||
|
?.copyWith(color: Theme.of(context).primaryColor),
|
||||||
|
),
|
||||||
|
SelectableText('Dietary Fiber',
|
||||||
|
style: Theme.of(context).textTheme.labelLarge),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
flex: 1,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'5g',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelLarge
|
||||||
|
?.copyWith(color: Theme.of(context).primaryColor),
|
||||||
|
),
|
||||||
|
SelectableText('Sugars',
|
||||||
|
style: Theme.of(context).textTheme.labelLarge),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Divider(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: semanticRed, borderRadius: BorderRadius.circular(8)),
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
child: Text(
|
||||||
|
'HOT',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleMedium
|
||||||
|
?.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
8.w,
|
||||||
|
SelectableText(
|
||||||
|
'(50%) 32.18 - 16.9 \$',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleMedium
|
||||||
|
?.copyWith(color: semanticRed),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
'Top reviews from the United States',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
)),
|
||||||
|
8.h,
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: 3,
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
title: SelectableText(
|
||||||
|
'Kristin Watson',
|
||||||
|
style: Theme.of(context).textTheme.labelLarge,
|
||||||
|
),
|
||||||
|
subtitle: SelectableText(
|
||||||
|
'Verified Buyer',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
),
|
||||||
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
SelectableText(
|
||||||
|
'This is 💯 one hundred percent the best !!! "Philadelphia cream cheese is absolutely amazing—so creamy and versatile, it elevates every recipe, from cheesecakes to simple bagels. A must-have in my kitchen!"😋😋😋',
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.thumb_up_alt_outlined),
|
||||||
|
8.w,
|
||||||
|
Text('Yes (2)'),
|
||||||
|
12.w,
|
||||||
|
Icon(Icons.thumb_down_alt_outlined),
|
||||||
|
8.w,
|
||||||
|
Text('No (0)'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Nov 09, 2024',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (index != 3 - 1)
|
||||||
|
Divider(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
12.h,
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'See all reviws',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleMedium
|
||||||
|
?.copyWith(color: semanticRed),
|
||||||
|
),
|
||||||
|
4.w,
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward,
|
||||||
|
color: semanticRed,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget shopTab(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'Heinen\'s Grocery',
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall,
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_rate_rounded),
|
||||||
|
Icon(Icons.star_half_rounded),
|
||||||
|
8.w,
|
||||||
|
Text(
|
||||||
|
'4.8',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.location_on_outlined),
|
||||||
|
8.w,
|
||||||
|
Text(
|
||||||
|
'Shop 1, Cleveland, Ohio, United States',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
4.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.access_time_rounded),
|
||||||
|
8.w,
|
||||||
|
Text(
|
||||||
|
'Open now | 10:00 AM - 12:00 PM',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'Facilities',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
8.w,
|
||||||
|
Expanded(
|
||||||
|
child: Divider(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.check_box_outlined),
|
||||||
|
8.w,
|
||||||
|
Text(
|
||||||
|
'Home Delivery',
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
SizedBox(
|
||||||
|
height: 46,
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surface),
|
||||||
|
onPressed: () {},
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.navigation_rounded),
|
||||||
|
4.w,
|
||||||
|
Text('Direction')
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: BorderRadius.circular(16)),
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'23 min (8.7 km)',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
|
12.h,
|
||||||
|
SizedBox(
|
||||||
|
height: 46,
|
||||||
|
width: double.infinity,
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: semanticGreen),
|
||||||
|
onPressed: () {},
|
||||||
|
child: Text('Reservation')),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'List of offers',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 150,
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
width: 300,
|
||||||
|
padding: EdgeInsets.all(12),
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: BorderRadius.circular(16)),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Image.network(
|
||||||
|
'https://s3-alpha-sig.figma.com/img/f773/0650/56608740ed0260647aa12c36f8b46534?Expires=1740960000&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=UxdqWfGI5Ix~S2728Qsiw0MHGST~we6M25cWRZ8YetaIGlC-ITXjDaX8LDssimYJt5XWmfyWqE0D4vRq1lP9Nmy3CfI~bLXaaBBSmQqAwdXDz1aVXFh7Q8ri5klxYoCjIF0HTp3nr4Scpf5d9PHU7L32s8JF0pz4dt8tyaCo-goeEOsjn8Q-LOBKNHVE6B8uRnW74GH12V7GNygxv1EV59dDD1vcXNcD7kS~2Ox7RejK159Ys7La1F-Evbt5sU7XFOMJuFbPVUgWA05wgrF1U1zdaz5b10Mu9~4PnErR~FjJTZPYcznatVYwuxWRWRAtpwjhjew2TL0DoOvlCKHbYw__',
|
||||||
|
width: 74,
|
||||||
|
height: 74,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
12.w,
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'Kellogg\'s Corn Flakes',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleMedium
|
||||||
|
?.copyWith(overflow: TextOverflow.ellipsis),
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
SelectableText(
|
||||||
|
'Classic cereal with a crispy texture an a mildly sweet flavor',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium
|
||||||
|
?.copyWith(overflow: TextOverflow.ellipsis),
|
||||||
|
maxLines: 2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
12.h,
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: semanticRed,
|
||||||
|
borderRadius: BorderRadius.circular(8)),
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
child: Text(
|
||||||
|
'HOT',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleSmall
|
||||||
|
?.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
8.w,
|
||||||
|
Text(
|
||||||
|
'(50%) / 16 - 8\$',
|
||||||
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: semanticGreen,
|
||||||
|
borderRadius: BorderRadius.circular(8)),
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
child: Text(
|
||||||
|
'Reservation',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleSmall
|
||||||
|
?.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SelectableText(
|
||||||
|
'Similar Business',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
16.h,
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 270,
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
width: 240,
|
||||||
|
padding: EdgeInsets.all(12),
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: BorderRadius.circular(16)),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 16 / 9,
|
||||||
|
child: Image.network(
|
||||||
|
'https://s3-alpha-sig.figma.com/img/c720/df1c/d8288c0392372fb3dd15824b84b9d563?Expires=1740960000&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=CMct6yvsv~g0YEUDRp-D3prnQve4nZc5mB~oJ4jbRsH63ltvM4yoCKbTYJLCm~ONwb9e7TNoFO1Q1pO8sPz3TBB-gAFIX9j53fz40ypp0VsRXSOK91G7LBj82V974E1Yqxol2fhAZ8icTAaOZVJgJH-47EG3wQqujGieHbcOYCCBZoCPP0a~jKG~LsE-EtLmP0RdXOuqE9-o2gMzEBH2TMXLtWJXYtA6dS~XHPBIeUXn4Sa7Hy4ca3pGb6wXN4owNt4SeanQuxeR-CEgDYJTI~tU6LkW1N2TSPOt6iGn5Jbb4XdkFjKA7dkwijG9mEU9F3wy16aMj7a1Z1yEwAvlwg__',
|
||||||
|
height: 100,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
SelectableText(
|
||||||
|
'Milam\'s Markets',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleMedium
|
||||||
|
?.copyWith(overflow: TextOverflow.ellipsis),
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.location_on_outlined),
|
||||||
|
8.w,
|
||||||
|
SelectableText(
|
||||||
|
'Miami Springs, Florida',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium
|
||||||
|
?.copyWith(overflow: TextOverflow.ellipsis),
|
||||||
|
maxLines: 1,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
8.h,
|
||||||
|
SizedBox(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {}, child: Text('See more about')),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -90,7 +90,7 @@ final ThemeData darkTheme = ThemeData(
|
||||||
CustomColors(
|
CustomColors(
|
||||||
primarySwatch: darkPrimarySwatch,
|
primarySwatch: darkPrimarySwatch,
|
||||||
secondrySwatch: darkSecondarySwatch,
|
secondrySwatch: darkSecondarySwatch,
|
||||||
primaryLightSurface: darkPrimarySwatch[900]!,
|
primaryLightSurface: darkPrimarySwatch[600]!,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ class CarouselSliderWidget<T> extends StatefulWidget {
|
||||||
) onPageBuilder;
|
) onPageBuilder;
|
||||||
final bool withNavs;
|
final bool withNavs;
|
||||||
final double height;
|
final double height;
|
||||||
|
final double viewportFraction;
|
||||||
final bool autoPlay;
|
final bool autoPlay;
|
||||||
final bool enableInfiniteScroll;
|
final bool enableInfiniteScroll;
|
||||||
final Function()? onLastClick;
|
final Function()? onLastClick;
|
||||||
|
|
@ -23,6 +24,7 @@ class CarouselSliderWidget<T> extends StatefulWidget {
|
||||||
this.autoPlay = true,
|
this.autoPlay = true,
|
||||||
this.enableInfiniteScroll = true,
|
this.enableInfiniteScroll = true,
|
||||||
this.height = 200,
|
this.height = 200,
|
||||||
|
this.viewportFraction = 0.9,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -46,11 +48,11 @@ class _CarouselSliderWidgetState<T> extends State<CarouselSliderWidget<T>> {
|
||||||
return widget.onPageBuilder(context, widget.items[index]);
|
return widget.onPageBuilder(context, widget.items[index]);
|
||||||
},
|
},
|
||||||
options: CarouselOptions(
|
options: CarouselOptions(
|
||||||
height: widget.height * 0.75,
|
height: widget.height,
|
||||||
autoPlay: widget.autoPlay,
|
autoPlay: widget.autoPlay,
|
||||||
enableInfiniteScroll: widget.enableInfiniteScroll,
|
enableInfiniteScroll: widget.enableInfiniteScroll,
|
||||||
enlargeCenterPage: true,
|
enlargeCenterPage: true,
|
||||||
viewportFraction: 0.9,
|
viewportFraction: widget.viewportFraction,
|
||||||
onPageChanged: (index, reason) =>
|
onPageChanged: (index, reason) =>
|
||||||
setState(() => activeIndex = index),
|
setState(() => activeIndex = index),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue