proxibuy/lib/presentation/pages/reserved_list_page.dart

187 lines
6.3 KiB
Dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:proxibuy/core/config/api_config.dart';
import 'package:proxibuy/core/gen/assets.gen.dart';
import 'package:proxibuy/data/models/offer_model.dart';
import 'package:proxibuy/presentation/widgets/reserved_list_item_card.dart';
class ReservedListPage extends StatefulWidget {
const ReservedListPage({super.key});
@override
State<ReservedListPage> createState() => _ReservedListPageState();
}
class _ReservedListPageState extends State<ReservedListPage> {
late Future<List<OfferModel>> _reservedOffersFuture;
@override
void initState() {
super.initState();
_reservedOffersFuture = _fetchReservedOffers();
}
Future<List<OfferModel>> _fetchReservedOffers() async {
try {
const storage = FlutterSecureStorage();
final token = await storage.read(key: 'accessToken');
if (token == null) {
throw Exception('شما وارد حساب کاربری خود نشده‌اید.');
}
final dio = Dio();
final response = await dio.get(
ApiConfig.baseUrl + ApiConfig.getReservations,
options: Options(headers: {'Authorization': 'Bearer $token'}),
);
if (response.statusCode == 200) {
final List<dynamic> reserves = response.data['reserves'];
return reserves.map((reserveData) {
final discountData = reserveData['Discount'] as Map<String, dynamic>;
final shopData = reserveData['Shop'] as Map<String, dynamic>;
final fullOfferData = {
...discountData,
'shopData': shopData,
'Distance': reserveData['Distance'],
};
return OfferModel.fromJson(fullOfferData);
}).toList();
} else {
throw Exception('خطا در دریافت اطلاعات از سرور');
}
} on DioException catch (e) {
final errorMessage = e.response?.data?['message'] ?? 'خطای شبکه';
throw Exception(errorMessage);
} catch (e) {
throw Exception('خطایی رخ داد: $e');
}
}
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
appBar: _buildCustomAppBar(context),
body: FutureBuilder<List<OfferModel>>(
future: _reservedOffersFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text('خطا: ${snapshot.error}', textAlign: TextAlign.center),
),
);
}
if (!snapshot.hasData || snapshot.data!.isEmpty) {
return const Center(
child: Text('هیچ آیتم رزرو شده‌ای یافت نشد.'),
);
}
final reservedOffers = snapshot.data!;
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemCount: reservedOffers.length,
itemBuilder: (context, index) {
final offer = reservedOffers[index];
return Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'تخفیف ${offer.discountType} رزرو شد!',
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
const SizedBox(height: 8),
const Divider(thickness: 1.5),
const SizedBox(height: 2),
ReservedListItemCard(offer: offer),
const SizedBox(height: 15),
],
),
).animate().fadeIn(delay: (100 * index).ms).slideY(
begin: 0.5,
duration: 500.ms,
curve: Curves.easeOutCubic,
);
},
);
},
),
),
);
}
PreferredSizeWidget _buildCustomAppBar(BuildContext context) {
return PreferredSize(
preferredSize: const Size.fromHeight(70.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(15),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
children: [
const Text(
'رزرو شده‌ها',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.normal,
fontSize: 16,
),
),
IconButton(
icon: SvgPicture.asset(Assets.icons.arrowLeft.path),
onPressed: () => Navigator.of(context).pop(),
),
],
),
],
),
],
),
),
),
),
);
}
}