Skip to content

Commit

Permalink
Refactor ReportPage to use FutureBuilder for fetching pharmacies and …
Browse files Browse the repository at this point in the history
…remove unused form elements
Polabiel committed Nov 29, 2024
1 parent 1a793e8 commit 1e5375b
Showing 2 changed files with 201 additions and 55 deletions.
184 changes: 174 additions & 10 deletions lib/src/app/home/profile/report/generated_report_page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:flutter/material.dart';
import 'package:gohealth/api/models/pharmacy_model.dart';
import 'package:gohealth/api/models/product_models.dart';
import 'package:gohealth/api/repositories/pharmacy_repository.dart';
import 'package:gohealth/api/repositories/product_repository.dart';

class GeneratedReportPage extends StatefulWidget {
GeneratedReportPage({super.key, required this.pharmacy});
@@ -12,26 +15,187 @@ class GeneratedReportPage extends StatefulWidget {

class _GeneratedReportPageState extends State<GeneratedReportPage> {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Relatório'),
title: const Text('Relatório da Farmácia'),
centerTitle: true,
),
body: Center(
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('Relatório de vendas da farmácia ${widget.pharmacy.name}'),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Voltar'),
Card(
elevation: 4,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
if (widget.pharmacy.image != null)
CircleAvatar(
radius: 30,
backgroundImage:
NetworkImage(widget.pharmacy.image!),
),
const SizedBox(width: 12),
Flexible(
child: Text(
widget.pharmacy.name!,
style: Theme.of(context).textTheme.headlineSmall,
overflow: TextOverflow.ellipsis,
),
),
],
),
const SizedBox(height: 8),
const Divider(),
const SizedBox(height: 8),
Text(
'Informações de Contato',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text('Email: ${widget.pharmacy.email}'),
Text('Telefone: ${widget.pharmacy.phone}'),
const SizedBox(height: 16),
Text(
'Endereço',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(widget.pharmacy.geolocation!.address!),
Text('CEP: ${widget.pharmacy.geolocation!.cep!}'),
if (widget.pharmacy.geolocation!.additional!.isNotEmpty)
Text(
'Complemento: ${widget.pharmacy.geolocation!.additional!}'),
],
),
),
),
const SizedBox(height: 16),
// capturar o relatório de vendas e estoque
(widget.pharmacy.pharmacyProducts != null &&
widget.pharmacy.pharmacyProducts!.length > 0)
? Card(
elevation: 4,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Relatório de Vendas',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
FutureBuilder<List<Order>>(
future: PharmacyRepository()
.getOrdersAllByIdPharmacy(
id: widget.pharmacy.id!),
builder:
(context, AsyncSnapshot<List<Order>> snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
final orders = snapshot.data;
return ListView.builder(
shrinkWrap: true,
itemCount: orders!.length,
itemBuilder: (context, index) {
final order = orders[index];
return ListTile(
title: Text(
'Pedido: ${order.id.split('-')[0]}'),
subtitle:
Text('Quantidade: ${order.quantity}'),
trailing: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
'Data: ${order.createdAt.toString().split(' ')[0].split('-').reversed.join('/')}'),
Text(
'Hora: ${order.createdAt.toString().split(' ')[1].substring(0, 5)}'),
],
),
);
},
);
},
),
const SizedBox(height: 16),
Text(
'Relatório de Estoque',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
FutureBuilder<List<ProductModels>>(
future: ProductRepository().getAll(),
builder: (context,
AsyncSnapshot<List<ProductModels>> snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
final products = snapshot.data;
final productsInStock = widget
.pharmacy.pharmacyProducts!
.map((e) => e.productId)
.toList();
final productsInStockList = products!
.where((element) =>
productsInStock.contains(element.id))
.toList();
return ListView.builder(
shrinkWrap: true,
itemCount: productsInStockList.length,
itemBuilder: (context, index) {
final product = productsInStockList[index];
return ListTile(
title: Text(product.name!),
subtitle: Text(
'Quantidade: ${widget.pharmacy.pharmacyProducts!.firstWhere((element) => element.productId == product.id).quantity}'),
);
},
);
},
),
],
),
),
)
: const SizedBox.shrink(),
],
),
),
);
}
}
}
72 changes: 27 additions & 45 deletions lib/src/app/home/profile/report/report_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:gohealth/api/models/pharmacy_model.dart';
import 'package:gohealth/api/repositories/pharmacy_repository.dart';
import 'package:gohealth/api/repositories/product_repository.dart';
import 'package:gohealth/src/app/home/profile/report/generated_report_page.dart';

class ReportPage extends StatefulWidget {
@@ -12,9 +12,6 @@ class ReportPage extends StatefulWidget {

// Page de relatórios de vendas e estoque de acordo com a farmacia
class _ReportPageState extends State<ReportPage> {
final _formKey = GlobalKey<FormState>();
final _nameControllerPharmacyInput = TextEditingController();
final _repository = ProductRepository();

@override
Widget build(BuildContext context) {
@@ -23,55 +20,40 @@ class _ReportPageState extends State<ReportPage> {
title: const Text('Relatórios'),
),
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: [
const Text('Relatório de Vendas e Estoque',
style: TextStyle(fontSize: 20)),
TextFormField(
controller: _nameControllerPharmacyInput,
decoration:
const InputDecoration(labelText: 'Nome da Farmácia'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Nome da farmácia é obrigatório';
}
return null;
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
PharmacyRepository()
.getPharmacyByName(_nameControllerPharmacyInput.text)
.then((pharmacyList) {
if (pharmacyList.isNotEmpty) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => GeneratedReportPage(
pharmacy: pharmacyList.first),
),
const SizedBox(height: 20),
FutureBuilder(
future: PharmacyRepository().getAll(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
final pharmacies = snapshot.data as List<PharmacyModels>;
return ListView.builder(
shrinkWrap: true,
itemCount: pharmacies.length,
itemBuilder: (context, index) {
final pharmacy = pharmacies[index];
return ListTile(
title: Text(pharmacy.name!),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
GeneratedReportPage(pharmacy: pharmacy)));
},
);
} else {
// Handle the case where no pharmacy is found
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Nenhuma farmácia encontrada'),
backgroundColor: Colors.redAccent,
),
);
}
});
},
);
}
},
child: const Text('Gerar Relatório'),
},
),
],
),
),
),
)),
);
}
}

0 comments on commit 1e5375b

Please sign in to comment.