123 lines
4.2 KiB
Dart
123 lines
4.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../models/lesson.dart';
|
|
import '../services/lessons_api.dart';
|
|
import '../widgets/yogibook_background.dart';
|
|
import 'reschedule_page.dart';
|
|
|
|
/// Schermata "Programma lezioni": mostra i pacchetti con ticket residui.
|
|
/// Scelto un pacchetto, apre la selezione slot in modalità prenotazione.
|
|
class OrdersPage extends StatefulWidget {
|
|
final String token;
|
|
|
|
const OrdersPage({super.key, required this.token});
|
|
|
|
@override
|
|
State<OrdersPage> createState() => _OrdersPageState();
|
|
}
|
|
|
|
class _OrdersPageState extends State<OrdersPage> {
|
|
bool loading = true;
|
|
String error = '';
|
|
List<OrderPackage> orders = [];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_load();
|
|
}
|
|
|
|
Future<void> _load() async {
|
|
setState(() {
|
|
loading = true;
|
|
error = '';
|
|
});
|
|
try {
|
|
final data = await LessonsApi.fetchOrders(token: widget.token);
|
|
setState(() => orders = data);
|
|
} catch (e) {
|
|
setState(() => error = 'Errore: $e');
|
|
} finally {
|
|
setState(() => loading = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
const green = Color(0xFF10B981);
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
backgroundColor: Colors.transparent,
|
|
elevation: 0,
|
|
centerTitle: true,
|
|
title: const Text(
|
|
'Programma lezioni',
|
|
style: TextStyle(fontWeight: FontWeight.w800, fontSize: 18),
|
|
),
|
|
),
|
|
body: YogibookBackground(
|
|
child: SafeArea(
|
|
top: false,
|
|
child: loading
|
|
? const Center(child: CircularProgressIndicator())
|
|
: error.isNotEmpty
|
|
? Center(child: Text(error))
|
|
: orders.isEmpty
|
|
? const Center(child: Text('Nessun pacchetto disponibile'))
|
|
: ListView.builder(
|
|
padding: const EdgeInsets.all(16),
|
|
itemCount: orders.length,
|
|
itemBuilder: (_, i) {
|
|
final o = orders[i];
|
|
return Card(
|
|
margin: const EdgeInsets.only(bottom: 10),
|
|
child: ListTile(
|
|
title: Text(
|
|
o.serviceName.isEmpty
|
|
? 'Pacchetto #${o.orderId}'
|
|
: o.serviceName,
|
|
style: const TextStyle(fontWeight: FontWeight.w800),
|
|
),
|
|
subtitle: Text(
|
|
'Da prenotare: ${o.remaining} / ${o.tickets}'
|
|
'${o.expireOn != null ? "\nScadenza: ${o.expireOn}" : ""}'
|
|
'${o.isExpired ? " (scaduto)" : ""}',
|
|
),
|
|
isThreeLine: o.expireOn != null,
|
|
trailing: o.bookable
|
|
? ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: green,
|
|
),
|
|
onPressed: () async {
|
|
await Navigator.push(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (_) => ReschedulePage(
|
|
token: widget.token,
|
|
serviceId: o.serviceId,
|
|
className: o.serviceName,
|
|
orderId: o.orderId,
|
|
),
|
|
),
|
|
);
|
|
_load();
|
|
},
|
|
child: const Text('Prenota'),
|
|
)
|
|
: Text(
|
|
o.isExpired ? 'Scaduto' : 'Esaurito',
|
|
style: const TextStyle(
|
|
color: Colors.black38,
|
|
fontWeight: FontWeight.w700,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|