Initial commit
This commit is contained in:
101
lib/features/home/presentation/pages/widgets/banners_widget.dart
Normal file
101
lib/features/home/presentation/pages/widgets/banners_widget.dart
Normal file
@@ -0,0 +1,101 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../../constants/constants.dart';
|
||||
import '../../../../../core/utils/app_utils.dart';
|
||||
import '../../../data/models/banner_response.dart';
|
||||
import '../../mixin/banner_mixin.dart';
|
||||
|
||||
class BannersWidget extends StatefulWidget {
|
||||
const BannersWidget({super.key, required this.banners});
|
||||
|
||||
final List<BannerResponse>? banners;
|
||||
|
||||
@override
|
||||
State<BannersWidget> createState() => _BannersWidgetState();
|
||||
}
|
||||
|
||||
class _BannersWidgetState extends State<BannersWidget> with BannerMixin {
|
||||
Timer? timer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
initController();
|
||||
if ((widget.banners?.length ?? 0) > 1) {
|
||||
animationTimer();
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant BannersWidget oldWidget) {
|
||||
if ((widget.banners?.length ?? 0) > 1) {
|
||||
animationTimer();
|
||||
} else if ((widget.banners?.length ?? 0) == 1) {
|
||||
if (timer?.isActive ?? false) {
|
||||
timer?.cancel();
|
||||
}
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
void animationTimer() {
|
||||
if (timer?.isActive ?? false) {
|
||||
timer?.cancel();
|
||||
}
|
||||
timer = Timer.periodic(const Duration(seconds: 4), (Timer timer) async {
|
||||
pageController.nextPage(
|
||||
duration: const Duration(milliseconds: 800),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
timer?.cancel();
|
||||
pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: SizedBox(
|
||||
height: 180,
|
||||
width: double.infinity,
|
||||
child: PageView.builder(
|
||||
controller: pageController,
|
||||
itemCount: (widget.banners?.length ?? 0) > 1
|
||||
? null
|
||||
: widget.banners?.length,
|
||||
scrollDirection: Axis.horizontal,
|
||||
physics: widget.banners?.length != 1
|
||||
? null
|
||||
: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (_, index) => GestureDetector(
|
||||
onTap: () {},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: ClipRRect(
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
|
||||
child: CachedNetworkImage(
|
||||
imageUrl:
|
||||
"${Constants.baseUrl}${widget.banners?[index % (widget.banners?.length ?? 1)].image}",
|
||||
height: 180,
|
||||
width: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import 'package:cargocalculaterapp/core/extension/build_context_extension.dart';
|
||||
import 'package:cargocalculaterapp/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import '../../../../../core/utils/app_utils.dart';
|
||||
|
||||
class EmptyOrderWidget extends StatelessWidget {
|
||||
const EmptyOrderWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliverToBoxAdapter(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 24),
|
||||
width: double.infinity,
|
||||
// padding: const EdgeInsets.symmetric(vertical: 42, horizontal: 32),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
color: context.color.statusBackground,
|
||||
border: Border.all(color: context.color.lightBorder),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: AppUtils.kBorderRadiusTop16,
|
||||
child: SvgPicture.asset(
|
||||
"assets/svg/ic_empty_box.svg",
|
||||
width: MediaQuery.sizeOf(context).width - 34,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
AppLocalization.current.no_order,
|
||||
style: context.text.titleBig,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
AppUtils.kBoxHeight12,
|
||||
Padding(
|
||||
padding: AppUtils.kPaddingHor24,
|
||||
child: Text(
|
||||
AppLocalization.current.no_order_desc,
|
||||
style: context.text.profileCategory.copyWith(
|
||||
color: context.color.lightSecondary,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
AppUtils.kBoxHeight48,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import 'package:cargocalculaterapp/core/extension/build_context_extension.dart';
|
||||
import 'package:cargocalculaterapp/core/widgets/shimmer/shimmer_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../../core/utils/app_utils.dart';
|
||||
|
||||
class OrderListShimmer extends StatelessWidget {
|
||||
const OrderListShimmer({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliverPadding(
|
||||
padding: AppUtils.kPaddingAll16,
|
||||
sliver: SliverList.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return Ink(
|
||||
padding: AppUtils.kPaddingAll16,
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius12,
|
||||
color: context.color.scaffoldBackgroundColor,
|
||||
),
|
||||
child: const Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ShimmerWidget(width: 60, height: 20),
|
||||
ShimmerWidget(width: 100, height: 20),
|
||||
],
|
||||
),
|
||||
AppUtils.kBoxHeight8,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ShimmerWidget(width: 40, height: 20),
|
||||
ShimmerWidget(width: 70, height: 20),
|
||||
],
|
||||
),
|
||||
AppUtils.kBoxHeight4,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ShimmerWidget(width: 100, height: 20),
|
||||
ShimmerWidget(width: 60, height: 20),
|
||||
],
|
||||
),
|
||||
AppUtils.kBoxHeight4,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ShimmerWidget(width: 80, height: 20),
|
||||
ShimmerWidget(width: 140, height: 20),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, __) => AppUtils.kBoxHeight12,
|
||||
itemCount: 6,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import 'package:cargocalculaterapp/core/extension/build_context_extension.dart';
|
||||
import 'package:cargocalculaterapp/core/utils/app_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OrderTextWidget extends StatelessWidget {
|
||||
const OrderTextWidget({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.name,
|
||||
this.crossAxisAlignment = CrossAxisAlignment.start,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String name;
|
||||
final CrossAxisAlignment crossAxisAlignment;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: crossAxisAlignment,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(title, style: context.text.orderListTitle),
|
||||
AppUtils.kBoxHeight6,
|
||||
Text(name, style: context.text.categoryName),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import 'package:cargocalculaterapp/core/extension/build_context_extension.dart';
|
||||
import 'package:cargocalculaterapp/core/utils/app_utils.dart';
|
||||
import 'package:cargocalculaterapp/features/home/presentation/pages/widgets/status_widget.dart';
|
||||
import 'package:cargocalculaterapp/generated/l10n.dart';
|
||||
import 'package:cargocalculaterapp/router/name_routes.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import '../../../data/models/orders_list_response.dart';
|
||||
import '../arguments/order_info_argument.dart';
|
||||
import 'order_text_widget.dart';
|
||||
|
||||
class OrdersListWidget extends StatelessWidget {
|
||||
const OrdersListWidget({super.key, required this.data});
|
||||
|
||||
final List<Data>? data;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliverPadding(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
||||
sliver: SliverList.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routes.orderInfo,
|
||||
arguments: OrderInfoArgument(
|
||||
orderId: data?[index].id ?? "",
|
||||
orderNumber: data?[index].orderNumber ?? "",
|
||||
),
|
||||
);
|
||||
},
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
child: Ink(
|
||||
padding: AppUtils.kPaddingAll16,
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
color: context.color.statusBackground,
|
||||
border: Border.all(color: context.color.lightBorder),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
OrderTextWidget(
|
||||
title: AppLocalization.current.order_number,
|
||||
name: data?[index].orderNumber ?? "",
|
||||
),
|
||||
StatusWidget(status: data?[index].status?.code ?? ""),
|
||||
],
|
||||
),
|
||||
AppUtils.kBoxHeight16,
|
||||
Row(
|
||||
children: [
|
||||
OrderTextWidget(
|
||||
title: AppLocalization.current.warehouse,
|
||||
name:
|
||||
Localizations.localeOf(context).languageCode == "uz"
|
||||
? (data?[index].wharehouseUz ?? "")
|
||||
: Localizations.localeOf(context).languageCode ==
|
||||
"ru"
|
||||
? (data?[index].wharehouseRu ?? "")
|
||||
: (data?[index].wharehouseZh ?? ""),
|
||||
),
|
||||
OrderTextWidget(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
title: AppLocalization.current.order_name,
|
||||
name:
|
||||
Localizations.localeOf(context).languageCode == "uz"
|
||||
? (data?[index].nameUz ?? "")
|
||||
: Localizations.localeOf(context).languageCode ==
|
||||
"ru"
|
||||
? (data?[index].nameRu ?? "")
|
||||
: (data?[index].nameZh ?? ""),
|
||||
),
|
||||
],
|
||||
),
|
||||
AppUtils.kBoxHeight16,
|
||||
Row(
|
||||
children: [
|
||||
OrderTextWidget(
|
||||
title: AppLocalization.current.delivery_price,
|
||||
name: (data?[index].deliveryPrice ?? ""),
|
||||
),
|
||||
OrderTextWidget(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
title: AppLocalization.current.delivery_time,
|
||||
name: DateFormat('dd-MM-yyyy').format(
|
||||
DateTime.tryParse(data?[index].arrivalDate ?? "") ??
|
||||
DateTime.now(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, __) => AppUtils.kBoxHeight12,
|
||||
itemCount: data?.length ?? 0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import 'package:cargocalculaterapp/constants/constants.dart';
|
||||
import 'package:cargocalculaterapp/core/extension/build_context_extension.dart';
|
||||
import 'package:cargocalculaterapp/core/functions/base_finctions.dart';
|
||||
import 'package:cargocalculaterapp/core/utils/app_utils.dart';
|
||||
import 'package:cargocalculaterapp/features/home/presentation/bloc/home_bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class StatusListWidget extends StatelessWidget {
|
||||
const StatusListWidget({super.key, required this.selectedStatus});
|
||||
|
||||
final String selectedStatus;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: _StatusHeaderDelegate(selectedStatus: selectedStatus),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _StatusHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||
final String selectedStatus;
|
||||
|
||||
_StatusHeaderDelegate({required this.selectedStatus});
|
||||
|
||||
@override
|
||||
double get minExtent => 72;
|
||||
|
||||
@override
|
||||
double get maxExtent => 72;
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context,
|
||||
double shrinkOffset,
|
||||
bool overlapsContent,
|
||||
) {
|
||||
return Material(
|
||||
color: context.color.grayBackground,
|
||||
child: SizedBox(
|
||||
height: 72,
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemBuilder: (context, index) {
|
||||
final key = AppConst.statusList.keys.toList()[index];
|
||||
return InkWell(
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
onTap: () {
|
||||
context.read<HomeBloc>().add(OrderStatusEvent(status: key));
|
||||
},
|
||||
child: Ink(
|
||||
padding: AppUtils.kPaddingHor16,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
color:
|
||||
key == selectedStatus
|
||||
? context.color.primaryColor
|
||||
: context.color.statusBackground,
|
||||
border: Border.all(
|
||||
color:
|
||||
key == selectedStatus
|
||||
? context.color.primaryColor
|
||||
: context.color.lightSecondary,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
Functions.getTranslatedItem(
|
||||
AppConst.statusList.values.toList()[index],
|
||||
context,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
style:
|
||||
key == selectedStatus
|
||||
? context.text.statusText
|
||||
: context.text.statusText.copyWith(
|
||||
color: context.color.textColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, __) => AppUtils.kBoxWidth16,
|
||||
itemCount: AppConst.statusList.length,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRebuild(covariant _StatusHeaderDelegate oldDelegate) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import 'package:cargocalculaterapp/core/functions/base_finctions.dart';
|
||||
import 'package:cargocalculaterapp/core/theme/app_text_styles.dart';
|
||||
import 'package:cargocalculaterapp/core/theme/colors/app_colors.dart';
|
||||
import 'package:cargocalculaterapp/core/utils/app_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../../constants/constants.dart';
|
||||
|
||||
class StatusWidget extends StatelessWidget {
|
||||
const StatusWidget({super.key, required this.status});
|
||||
|
||||
final String status;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
switch (status) {
|
||||
case AppConst.waiting:
|
||||
{
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius24,
|
||||
color: ThemeColors.warningSurface,
|
||||
),
|
||||
child: Text(
|
||||
Functions.getTranslatedItem(
|
||||
AppConst.statusList[AppConst.waiting],
|
||||
context,
|
||||
),
|
||||
style: AppTextStyles.status.copyWith(color: ThemeColors.warning),
|
||||
),
|
||||
);
|
||||
}
|
||||
case AppConst.shipped:
|
||||
{
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius24,
|
||||
color: ThemeColors.green173Light,
|
||||
),
|
||||
child: Text(
|
||||
Functions.getTranslatedItem(
|
||||
AppConst.statusList[AppConst.shipped],
|
||||
context,
|
||||
),
|
||||
style: AppTextStyles.status,
|
||||
),
|
||||
);
|
||||
}
|
||||
case AppConst.leftChine:
|
||||
{
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius24,
|
||||
color: ThemeColors.green191Light,
|
||||
),
|
||||
child: Text(
|
||||
Functions.getTranslatedItem(
|
||||
AppConst.statusList[AppConst.leftChine],
|
||||
context,
|
||||
),
|
||||
style: AppTextStyles.status.copyWith(
|
||||
color: ThemeColors.green191text,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
default:
|
||||
{
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius24,
|
||||
color: ThemeColors.green173Light,
|
||||
),
|
||||
child: Text(
|
||||
Functions.getTranslatedItem(
|
||||
AppConst.statusList[status],
|
||||
context,
|
||||
),
|
||||
style: AppTextStyles.status,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user