sapaly_store/lib/features/screens/home/home_screen.dart

288 lines
12 KiB
Dart

import 'package:adaptix/adaptix.dart';
import 'package:buttons_tabbar/buttons_tabbar.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:sapaly_shop/models/settings_model.dart';
import 'package:sapaly_shop/models/sliders_model.dart';
import 'package:sapaly_shop/models/subcategory_model.dart';
import 'package:sapaly_shop/features/screens/drawer/sapaly_drawer.dart';
import 'package:sapaly_shop/features/screens/home/product.dart';
import 'package:sapaly_shop/features/screens/home/search.dart';
import 'package:sapaly_shop/features/services/requests.dart';
import '../../widgets/sapaly_app_bar.dart';
import '../../../constants/global_variables.dart';
import '../../../themes/app_theme.dart';
class HomeScreen extends StatefulWidget {
static const String routeName = '/home';
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
final GlobalKey<ScaffoldState> _key = GlobalKey();
int currentPage = 0;
int categoryId = 0;
bool hasError = false;
TabController? tabController;
List<SubcategoryModel> categories = [];
List<SlidersModel> sliders = [];
Future<void> getSliders() async {
try {
var list = await API().getSliders();
if (mounted) {
setState(() {
sliders = list;
});
}
} catch (e) {
debugPrint(e.toString());
}
}
Future<void> getSubCategories() async {
try {
var list = await API().getSubCategories();
if (mounted) {
setState(() {
categories = list;
hasError = false;
});
}
tabController = TabController(length: categories.length, vsync: this);
} catch (e) {
setState(() {
hasError = true;
});
debugPrint(e.toString());
}
}
@override
void initState() {
getSliders();
getSubCategories();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppTheme.lightBackgroundColor,
key: _key,
drawer: SapalyDrawer(),
appBar: SapalyAppBar(
hasActionButton: true,
title: '',
badge: '2',
leadingButton: SvgPicture.asset('assets/icons/menu.svg'),
actionButton: SvgPicture.asset('assets/icons/cart.svg'),
leadingOnTap: () {
_key.currentState?.openDrawer();
},
actionOnTap: () {},
),
body: Padding(
padding: EdgeInsets.symmetric(
vertical: GlobalVariables.verticalPadding(context) / 2,
horizontal: GlobalVariables.horizontalPadding(context),
),
child: NestedScrollView(
physics: const BouncingScrollPhysics(),
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverToBoxAdapter(
child: Column(
children: [
Container(
height: 50.adaptedPx(),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: AppTheme.whiteColor,
borderRadius: BorderRadius.circular(30.adaptedPx()),
),
child: TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SearchScreen(),
),
);
},
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(30.adaptedPx()),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.symmetric(
horizontal: 15.adaptedPx()),
child: SvgPicture.asset(
'assets/icons/search.svg'),
),
Text(
'searchHint'.translation,
style: GoogleFonts.poppins(
textStyle: Theme.of(context)
.primaryTextTheme
.bodyMedium
?.copyWith(
fontSize: 16.adaptedPx(),
color: AppTheme.lightTextColor,
),
),
),
],
),
),
),
CarouselSlider(
items: (sliders != null)
? [
for (int i = 0; i < sliders.length; i++)
CachedNetworkImage(
imageUrl: sliders[i].img,
width:
GlobalVariables.deviceWidth(context),
fit: BoxFit.contain,
progressIndicatorBuilder:
(context, url, progress) =>
const Center(
child: CircularProgressIndicator(),
),
),
]
: [
const Center(
child: CircularProgressIndicator()),
],
options: CarouselOptions(
initialPage: 0,
padEnds: true,
scrollPhysics: const BouncingScrollPhysics(),
viewportFraction: 1,
autoPlay: true,
onPageChanged: (index, reason) {
setState(() {
currentPage = index;
});
},
autoPlayAnimationDuration:
const Duration(seconds: 2),
autoPlayInterval: const Duration(seconds: 5),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
sliders.length,
(index) => buildDot(
index: index,
),
),
),
Padding(
padding: EdgeInsets.only(
top: 20.adaptedPx(), bottom: 10.adaptedPx()),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'categories'.translation,
style: Theme.of(context)
.primaryTextTheme
.bodyMedium
?.copyWith(
color: AppTheme.blackColor,
fontSize: 18.adaptedPx(),
fontWeight: FontWeight.w600,
),
),
),
),
categories.isEmpty
? Padding(
padding: EdgeInsets.symmetric(
vertical: 10.adaptedPx()),
child: const Center(
child: CircularProgressIndicator()),
)
: Padding(
padding: EdgeInsets.symmetric(
vertical: 10.adaptedPx()),
child: ButtonsTabBar(
controller: tabController,
contentPadding: EdgeInsets.symmetric(
horizontal: 20.adaptedPx()),
splashColor: AppTheme.lightPrimaryColor,
radius: 10.adaptedPx(),
backgroundColor: AppTheme.lightPrimaryColor,
buttonMargin: EdgeInsets.only(
left: 0,
right: 15.adaptedPx(),
),
onTap: (value) {
setState(() {
categoryId = categories[value].id;
debugPrint(categoryId.toString());
});
},
unselectedBackgroundColor:
AppTheme.whiteColor,
physics: const BouncingScrollPhysics(),
tabs: [
for (var category in categories)
Tab(text: category.name)
],
),
),
SizedBox(height: 15.adaptedPx()),
],
),
),
],
body: tabController != null
? TabBarView(
controller: tabController,
children: categories.isNotEmpty
? categories
.map(
(category) => Products(
id: category.id,
),
)
.toList()
: [],
)
: Container()),
),
);
}
Widget buildDot({int? index}) {
return AnimatedContainer(
duration: const Duration(milliseconds: 350),
margin: EdgeInsets.only(right: 5.adaptedPx()),
height: 8.adaptedPx(),
width: currentPage == index ? 25.adaptedPx() : 8.adaptedPx(),
decoration: BoxDecoration(
color: currentPage == index
? AppTheme.lightPrimaryColor
: AppTheme.lightTextColor.withOpacity(0.3),
borderRadius: BorderRadius.circular(30.adaptedPx()),
),
);
}
}