Commit 1fee488a authored by Calebe Rocha's avatar Calebe Rocha
Browse files

Merge branch 'develop' into feat/apk_settings

parents ab43bf98 73391b2c
Showing with 1512 additions and 361 deletions
+1512 -361
......@@ -69,9 +69,11 @@ class _CartPageState extends State<CartScreen> {
@override
void initState() {
super.initState();
this._loadCart();
Provider.of<ActiveBarItemProvider>(context, listen: false)
.setActiveIndex(2);
Future.delayed(Duration.zero, () async {
this._loadCart();
Provider.of<ActiveBarItemProvider>(context, listen: false)
.setActiveIndex(2);
});
}
@override
......
import 'dart:math';
import 'package:apus_drones_mobile/models/CreatePartner.dart';
import 'package:apus_drones_mobile/screens/LoginScreen.dart';
import 'package:apus_drones_mobile/services/PartnerService.dart';
import 'package:flutter/material.dart';
class CreatePartnerScreen extends StatefulWidget {
const CreatePartnerScreen({Key? key}) : super(key: key);
@override
_CreatePartnerScreenState createState() => _CreatePartnerScreenState();
}
class _CreatePartnerScreenState extends State<CreatePartnerScreen> {
late CreatePartner Partner;
TextEditingController nameController = TextEditingController();
TextEditingController CPFController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController cepController = TextEditingController();
TextEditingController adressController = TextEditingController();
PartnerService service = new PartnerService();
savePartner() {
service.postPartner(Partner).then((data) => this.setState(() {}));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: BodyCriarCliente(),
);
}
Widget BodyCriarCliente() {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Padding(
padding: const EdgeInsets.only(top: 70, right: 25, left: 25),
child: Column(
children: [
Text("Cadastro do Parceiro",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
Expanded(
child: SingleChildScrollView(
child: getColumn(),
)),
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {
back();
},
child: Text('Cancelar'),
),
SizedBox(
width: 20,
),
ElevatedButton(
onPressed: () {
createCliente();
},
child: Text('Criar')),
],
),
],
),
),
);
}
Column getColumn() {
List<Widget> list = [];
list.add(SizedBox(
height: 30,
));
list.add(TextField(
controller: nameController,
decoration: InputDecoration(
labelText: 'Nome da empresa',
border: OutlineInputBorder(),
helperText: 'Este nome aparecerá para os parceiros',
),
));
list.add(SizedBox(
height: 30,
));
list.add(TextField(
controller: CPFController,
decoration: InputDecoration(
labelText: 'CNPJ',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number,
));
list.add(SizedBox(
height: 30,
));
list.add(TextField(
controller: passwordController,
decoration: InputDecoration(
labelText: 'Senha',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.visiblePassword,
));
list.add(SizedBox(
height: 30,
));
//Usar o FileUploadInputElement() talvez para fazer upload de imagem
list.add(TextField(
controller: emailController,
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.emailAddress,
));
list.add(SizedBox(
height: 30,
));
list.add(TextField(
controller: cepController,
decoration: InputDecoration(
labelText: 'Cep',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number));
list.add(SizedBox(
height: 30,
));
list.add(TextField(
controller: adressController,
decoration: InputDecoration(
labelText: 'Endereço',
border: OutlineInputBorder(),
),
));
return new Column(children: list);
}
void createCliente() {
var rng = new Random();
int n = rng.nextInt(300) + 1;
String url =
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/$n.png";
print('url: ' + url);
Partner = CreatePartner(url, CPFController.text, emailController.text,
nameController.text, passwordController.text);
savePartner();
print("Parceiro cadastrado!");
back();
}
void back() {
Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginScreen()));
}
}
import 'dart:math';
import 'package:apus_drones_mobile/constants/UserType.dart';
import 'package:apus_drones_mobile/models/AddressModel.dart';
import 'package:apus_drones_mobile/models/CreateCustomer.dart';
import 'package:apus_drones_mobile/models/CreatePartner.dart';
import 'package:apus_drones_mobile/screens/LoginScreen.dart';
import 'package:apus_drones_mobile/services/CustomerService.dart';
import 'package:apus_drones_mobile/services/LocationService.dart';
import 'package:apus_drones_mobile/services/PartnerService.dart';
import 'package:apus_drones_mobile/widgets/AddressAutocomplete.dart';
import 'package:flutter/material.dart';
class CreateCustomerScreen extends StatefulWidget {
const CreateCustomerScreen({Key? key}) : super(key: key);
import 'package:places_service/places_service.dart';
class CreateUserScreen extends StatefulWidget {
final UserType? role;
const CreateUserScreen({Key? key, this.role}) : super(key: key);
@override
_CreateCustomerScreenState createState() => _CreateCustomerScreenState();
_CreateUserScreenState createState() => _CreateUserScreenState();
}
class _CreateCustomerScreenState extends State<CreateCustomerScreen> {
class _CreateUserScreenState extends State<CreateUserScreen> {
late CreateCustomer customer;
late CreatePartner partner;
TextEditingController nameController = TextEditingController();
TextEditingController CPFController = TextEditingController();
TextEditingController cpfController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController cepController = TextEditingController();
TextEditingController adressController = TextEditingController();
CustomerService service = new CustomerService();
TextEditingController addressController = TextEditingController();
LocationService locationService = LocationService();
List<PlacesAutoCompleteResult> resultPlaces = [];
AddressModel? selectedAddress;
CustomerService customerService = new CustomerService();
PartnerService partnerService = new PartnerService();
String? addressErrorText;
ScrollController scrollController = ScrollController();
saveCustomer() {
service.postCustomer(customer).then((data) => this.setState(() {}));
customerService.postCustomer(customer).then((data) => this.setState(() {}));
}
_onAddressSelected(AddressModel address) {
this.selectedAddress = address;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: BodyCriarCliente(),
body: BodyCreateUser(),
);
}
Widget BodyCriarCliente() {
Widget BodyCreateUser() {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
......@@ -45,9 +64,11 @@ class _CreateCustomerScreenState extends State<CreateCustomerScreen> {
Text("Cadastro do Cliente",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
Expanded(
child: SingleChildScrollView(
child: getColumn(),
)),
child: SingleChildScrollView(
controller: scrollController,
child: getColumn(),
),
),
SizedBox(
height: 30,
),
......@@ -65,7 +86,7 @@ class _CreateCustomerScreenState extends State<CreateCustomerScreen> {
),
ElevatedButton(
onPressed: () {
createCliente();
createUser();
},
child: Text('Criar')),
],
......@@ -94,7 +115,7 @@ class _CreateCustomerScreenState extends State<CreateCustomerScreen> {
height: 30,
));
list.add(TextField(
controller: CPFController,
controller: cpfController,
decoration: InputDecoration(
labelText: 'CPF',
border: OutlineInputBorder(),
......@@ -127,28 +148,43 @@ class _CreateCustomerScreenState extends State<CreateCustomerScreen> {
list.add(SizedBox(
height: 30,
));
list.add(TextField(
controller: cepController,
decoration: InputDecoration(
labelText: 'Cep',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number));
list.add(SizedBox(
height: 30,
));
list.add(TextField(
controller: adressController,
decoration: InputDecoration(
labelText: 'Endereço',
border: OutlineInputBorder(),
list.add(
AddressAutocomplete(
placeholder: "Endereço",
onAddressSelected: _onAddressSelected,
errorText: this.addressErrorText,
scrollController: scrollController,
),
));
);
return new Column(children: list);
}
void createUser() {
if (this.selectedAddress?.number == -1) {
setState(() {
this.addressErrorText = "Informe o número do endereço.";
});
return;
} else {
this.addressErrorText = null;
}
switch (this.widget.role) {
case UserType.CUSTOMER:
this.createCliente();
break;
case UserType.PARTNER:
this.createPartner();
break;
case UserType.PILOT:
break;
default:
throw new ArgumentError.notNull("Papel do usuário não pode ser nulo.");
}
}
void createCliente() {
String address;
AddressModel address;
String avatarUrl;
String cpfCnpj;
String email;
......@@ -158,13 +194,31 @@ class _CreateCustomerScreenState extends State<CreateCustomerScreen> {
int n = rng.nextInt(300) + 1;
String url =
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/$n.png";
customer = CreateCustomer(adressController.text, url, CPFController.text,
customer = CreateCustomer(selectedAddress!, url, cpfController.text,
emailController.text, nameController.text, passwordController.text);
saveCustomer();
back();
}
void createPartner() {
var rng = new Random();
int n = rng.nextInt(300) + 1;
String url =
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/$n.png";
print('url: ' + url);
partner = CreatePartner(url, cpfController.text, emailController.text,
nameController.text, passwordController.text);
savePartner();
print("Parceiro cadastrado!");
back();
}
savePartner() {
partnerService.postPartner(partner).then((data) => this.setState(() {}));
}
void back() {
Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginScreen()));
......
import 'package:apus_drones_mobile/constants/Constants.dart';
import 'package:apus_drones_mobile/models/AddressModel.dart';
import 'package:apus_drones_mobile/models/CustomerModel.dart';
import 'package:apus_drones_mobile/services/CustomerService.dart';
import 'package:apus_drones_mobile/services/ProfileService.dart';
import 'package:flutter/material.dart';
class CustomerEditProfileScreen extends StatefulWidget {
final CustomerModel? customer;
CustomerEditProfileScreen({Key? key, required this.customer})
: super(key: key);
@override
_CustomerEditProfileScreenState createState() =>
_CustomerEditProfileScreenState();
}
class _CustomerEditProfileScreenState extends State<CustomerEditProfileScreen> {
TextEditingController nameController = TextEditingController();
TextEditingController cpfController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController emailController = TextEditingController();
// TextEditingController cepController = TextEditingController();
// TextEditingController addressController = TextEditingController();
late bool passwordVisibility;
//CUSTOMER
CustomerModel? _customer;
CustomerService customerService = CustomerService();
ProfileService profileService = ProfileService();
@override
void initState() {
super.initState();
final _currentCustomer = widget.customer;
this.setState(() {
_customer = _currentCustomer;
if (_currentCustomer != null) {
nameController.value = TextEditingValue(text: _currentCustomer.name);
cpfController.value = TextEditingValue(text: _currentCustomer.cpfCnpj);
emailController.value = TextEditingValue(text: _currentCustomer.email);
// addressController.value = TextEditingValue(
// text: _currentCustomer.addresses?[0].toString() ?? '');
// cepController.value = TextEditingValue(
// text: _currentCustomer.addresses?[0].zipCode ?? '');
}
passwordVisibility = false;
});
}
void updateCustomer() async {
final _currentCustomer = _customer;
if (_currentCustomer == null) {
return;
}
CustomerModel newCustomer = CustomerModel(
id: _currentCustomer.id,
name: nameController.text,
email: emailController.text,
cpfCnpj: cpfController.text,
avatarUrl: _currentCustomer.avatarUrl,
);
try {
await profileService.updateCustomerProfile(newCustomer);
Navigator.pop(context);
} catch (error) {
print(error);
}
}
void updateCustomerProfilePhoto() {
//customer?.avatarUrl =
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () async {
Navigator.of(context).pushNamed('LoginScreen');
},
icon: Icon(
Icons.arrow_back_rounded,
color: Colors.black,
size: 24,
)),
title: Text('Editar Perfil'),
),
body: SingleChildScrollView(
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Padding(
padding: EdgeInsets.only(top: 15),
child: Column(
children: [
fotoPerfil(),
Column(
mainAxisSize: MainAxisSize.max,
children: [
inputUsuarioTxt(
"Nome", "Ex: João da Silva", nameController),
inputUsuarioNumber(
"CPF", "Ex: 123.456.789-00", cpfController),
inputUsuarioTxt(
"Email", "Ex: exemplo@gmail.com", emailController),
// inputUsuarioTxt("Endereço", "Ex: Rua Assis Brasil, 123",
// addressController),
// inputUsuarioNumber("CEP", "Ex: 12345-678", cepController),
inputUsuarioSenha("Senha", passwordController),
botoesRodape(),
],
)
],
),
),
),
),
);
}
fotoPerfil() {
return Center(
child: Stack(
children: [
Container(
width: 130,
height: 130,
decoration: BoxDecoration(
border: Border.all(
width: 4, color: Theme.of(context).scaffoldBackgroundColor),
boxShadow: [
BoxShadow(
spreadRadius: 2,
blurRadius: 8,
color: Colors.black.withOpacity(0.1),
)
],
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage(_customer?.avatarUrl ?? IMG_NO_PHOTO),
),
),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
border: Border.all(
width: 4,
color: Theme.of(context).scaffoldBackgroundColor)),
child: IconButton(
padding: EdgeInsets.all(0),
onPressed: () {
print('Button Pressed');
//Se usuário logado for cliente
updateCustomerProfilePhoto();
//Se usuário logado for parceiro
//updatePartnerProfilePhoto();
},
icon: Icon(
Icons.edit,
color: Colors.white,
),
),
),
)
],
),
);
}
inputUsuarioTxt(
String labelText, String hintText, TextEditingController controller) {
return Padding(
padding: EdgeInsets.only(left: 20, top: 25, right: 20, bottom: 0),
child: TextFormField(
controller: controller,
obscureText: false,
decoration: InputDecoration(
labelText: labelText,
labelStyle: TextStyle(
fontFamily: 'Poppins',
),
hintText: hintText,
hintStyle: TextStyle(
fontFamily: 'Poppins',
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
filled: true,
),
style: TextStyle(
fontFamily: 'Poppins',
),
keyboardType: TextInputType.name,
),
);
}
inputUsuarioNumber(
String labelText, String hintText, TextEditingController controller) {
return Padding(
padding: EdgeInsets.only(left: 20, top: 25, right: 20, bottom: 0),
child: TextFormField(
controller: controller,
obscureText: false,
decoration: InputDecoration(
labelText: labelText,
labelStyle: TextStyle(
fontFamily: 'Poppins',
),
hintText: hintText,
hintStyle: TextStyle(
fontFamily: 'Poppins',
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
filled: true,
),
style: TextStyle(
fontFamily: 'Poppins',
),
keyboardType: TextInputType.number,
),
);
}
inputUsuarioSenha(String labelText, TextEditingController controller) {
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(20, 15, 20, 0),
child: TextFormField(
controller: controller,
obscureText: !passwordVisibility,
decoration: InputDecoration(
labelText: labelText,
labelStyle: TextStyle(
fontFamily: 'Poppins',
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
filled: true,
suffixIcon: InkWell(
onTap: () => setState(
() => passwordVisibility = !passwordVisibility,
),
child: Icon(
passwordVisibility
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
color: Color(0xFF757575),
size: 22,
),
),
),
style: TextStyle(
fontFamily: 'Poppins',
),
keyboardType: TextInputType.visiblePassword,
),
);
}
botoesRodape() {
return Padding(
padding: EdgeInsets.only(top: 50),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
ElevatedButton(
onPressed: () {
print('Button pressed ...');
Navigator.pop(context);
},
child: Text(
'CANCELAR',
style: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFFFB0808),
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.white,
fixedSize: Size(150, 40),
elevation: 3,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
),
),
ElevatedButton(
onPressed: () {
print('Button pressed ...');
updateCustomer();
},
child: Text(
'SALVAR',
style: TextStyle(
fontFamily: 'Poppins',
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xFFFB0808),
fixedSize: Size(150, 40),
elevation: 3,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
),
),
]),
);
}
}
import 'package:apus_drones_mobile/constants/Constants.dart';
import 'package:apus_drones_mobile/models/CustomerModel.dart';
import 'package:apus_drones_mobile/screens/Appbar.dart';
import 'package:apus_drones_mobile/screens/CustomerEditProfileScreen.dart';
import 'package:apus_drones_mobile/services/CustomerService.dart';
import 'package:apus_drones_mobile/widgets/UserDisplayedProperty.dart';
import 'package:flutter/material.dart';
......@@ -33,73 +34,87 @@ class _CustomerProfileState extends State<CustomerProfile> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: Appbar(
title: "Cliente - ${this.customer?.name ?? ''}",
),
body: Column(
children: [
Padding(
padding: EdgeInsets.all(20),
child:
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
width: 140.0,
height: 140.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(width: 3.0, color: Colors.grey),
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
customer?.avatarUrl ?? IMG_NO_PHOTO))),
),
]),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${customer?.name}",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
)
],
appBar: Appbar(
title: "Cliente - ${this.customer?.name ?? ''}",
),
body: Column(
children: [
Padding(
padding: EdgeInsets.all(20),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
width: 140.0,
height: 140.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(width: 3.0, color: Colors.grey),
image: DecorationImage(
fit: BoxFit.fill,
image:
NetworkImage(customer?.avatarUrl ?? IMG_NO_PHOTO))),
),
]),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${customer?.name}",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${customer?.email}",
style: TextStyle(fontSize: 16),
)
],
),
Padding(
padding: EdgeInsets.all(16),
child: Padding(
padding: EdgeInsets.only(top: 24),
child: Column(
children: [
Padding(
padding: EdgeInsets.all(8),
child: UserDisplayedProperty<String?>(
name: "CPF / CNPJ",
value: customer?.cpfCnpj,
),
),
Padding(
padding: EdgeInsets.all(8),
child: UserDisplayedProperty<String?>(
name: "Endereço",
value: (customer?.addresses?.isEmpty ?? true
? null
: customer?.addresses?.first.toString()) ??
"Endereço não cadastrado",
),
)
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${customer?.email}",
style: TextStyle(fontSize: 16),
)
],
),
],
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
print('Button pressed ...');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CustomerEditProfileScreen(customer: customer),
),
Padding(
padding: EdgeInsets.all(16),
child: Padding(
padding: EdgeInsets.only(top: 24),
child: Column(
children: [
Padding(
padding: EdgeInsets.all(8),
child: UserDisplayedProperty<String?>(
name: "CPF / CNPJ",
value: customer?.cpfCnpj,
),
),
Padding(
padding: EdgeInsets.all(8),
child: UserDisplayedProperty<String?>(
name: "Endereço",
value: (customer?.addresses?.isEmpty ?? true
? null
: customer?.addresses?.first.toString()) ??
"Endereço não cadastrado",
),
)
],
),
))
],
));
);
},
label: Icon(Icons.edit),
shape: CircleBorder(),
),
);
}
}
import 'package:apus_drones_mobile/constants/UserType.dart';
import 'package:apus_drones_mobile/screens/CustomerProfile.dart';
import 'package:apus_drones_mobile/providers/AuthProvider.dart';
import 'package:apus_drones_mobile/screens/LoginScreen.dart';
import 'package:apus_drones_mobile/screens/CreateCustomerScreen.dart';
import 'package:apus_drones_mobile/screens/CreateUserScreen.dart';
import 'package:apus_drones_mobile/screens/PartnerOrdersScreen.dart';
import 'package:apus_drones_mobile/screens/PartnerProfile.dart';
import 'package:apus_drones_mobile/screens/clients/ListOfPartners.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'CreatePartnerScreen.dart';
class HomePage extends StatelessWidget {
static final String routeName = 'Home';
static final int botNavItemIndex = 0;
......@@ -66,14 +65,18 @@ class HomePage extends StatelessWidget {
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CreateCustomerScreen())),
builder: (context) => CreateUserScreen(
role: UserType.CUSTOMER,
))),
child: Text('Criar cliente'),
),
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CreatePartnerScreen())),
builder: (context) => CreateUserScreen(
role: UserType.PARTNER,
))),
child: Text('Criar parceiro'),
),
],
......
import 'dart:io';
import 'package:apus_drones_mobile/constants/UserType.dart';
import 'package:apus_drones_mobile/models/AuthLoginModel.dart';
import 'package:apus_drones_mobile/providers/AuthProvider.dart';
import 'package:apus_drones_mobile/screens/CreateCustomerScreen.dart';
import 'package:apus_drones_mobile/screens/CreatePartnerScreen.dart';
import 'package:apus_drones_mobile/screens/CreateUserScreen.dart';
import 'package:apus_drones_mobile/screens/PartnerOrdersScreen.dart';
import 'package:apus_drones_mobile/screens/PilotOrderDetailScreen.dart';
import 'package:apus_drones_mobile/screens/clients/ListOfPartners.dart';
import 'package:apus_drones_mobile/services/AuthService.dart';
import 'package:apus_drones_mobile/controllers/SnackbarController.dart';
import 'package:apus_drones_mobile/widgets/SignupChooseProfileDialog.dart';
import 'package:apus_drones_mobile/screens/AdminScreen.dart';
import 'package:flutter/material.dart';
......@@ -24,6 +27,7 @@ class _LoginScreenState extends State<LoginScreen> {
String password = '';
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
SnackbarController snackbar = SnackbarController();
final _formKey = GlobalKey<FormState>();
@override
......@@ -53,7 +57,8 @@ class _LoginScreenState extends State<LoginScreen> {
case UserType.ADMIN:
return AdminScreen();
case UserType.PILOT:
throw new Exception('Não há telas para o piloto ainda');
// TODO: alterar para listagem de pedidos
return new PilotOrderDetailsScreen(id: 1);
default:
throw new Exception('Tipo de usuário desconhecido');
}
......@@ -61,8 +66,15 @@ class _LoginScreenState extends State<LoginScreen> {
_doLogin() async {
final login = AuthLoginModel(email: email, password: password);
await service.login(login);
_goHome();
final result = await service.login(login);
if (result['success']) {
_goHome();
} else {
int? status = result['status'];
if (status == HttpStatus.forbidden) {
snackbar.open("Usuário ou senha incorretos.", context);
}
}
}
_goHome() {
......@@ -172,10 +184,14 @@ class _LoginScreenState extends State<LoginScreen> {
builder: (context) => SignupChooseProfileDialog(
options: {
'Sou cliente': MaterialPageRoute(
builder: (context) => CreateCustomerScreen(),
builder: (context) => CreateUserScreen(
role: UserType.CUSTOMER,
),
),
'Sou parceiro': MaterialPageRoute(
builder: (context) => CreatePartnerScreen(),
builder: (context) => CreateUserScreen(
role: UserType.PARTNER,
),
),
},
),
......
import 'package:apus_drones_mobile/constants/PartnerStatusEnum.dart';
import 'package:apus_drones_mobile/constants/UserType.dart';
import 'package:apus_drones_mobile/models/OrderModel.dart';
import 'package:apus_drones_mobile/models/PartnerModel.dart';
import 'package:apus_drones_mobile/models/PartnerStatus.dart';
import 'package:apus_drones_mobile/services/PartnerService.dart';
import 'package:apus_drones_mobile/widgets/BotNavBar.dart';
import 'package:apus_drones_mobile/widgets/Fee.dart';
import 'package:apus_drones_mobile/widgets/PartnerOrderDetailsHeader.dart';
import 'package:apus_drones_mobile/widgets/StatusButton.dart';
import 'package:flutter/material.dart';
import 'Appbar.dart';
class PartnerDetailScreen extends StatefulWidget {
final PartnerModel partner;
const PartnerDetailScreen(this.partner);
@override
_PartnerDetailScreenState createState() => _PartnerDetailScreenState();
}
class _PartnerDetailScreenState extends State<PartnerDetailScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: Appbar(title: 'Detalhes do parceiro'),
bottomNavigationBar: BotNavBar(role: UserType.PARTNER),
body: BodyCriarCliente());
}
Widget BodyCriarCliente() {
return Container(
height: MediaQuery.of(context).size.height * 0.9,
child: Center(
child: Column(children: [
Padding(
padding: EdgeInsets.all(20),
child: Container(
width: 140.0,
height: 140.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.black26),
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(widget.partner.avatarUrl)),
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 20),
child: Text(
"${widget.partner.name}",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
),
Expanded(
child: SingleChildScrollView(
child: getColumn(),
)),
showButtons(),
ElevatedButton(
onPressed: () => {Navigator.pop(context)},
child: Text(
"Voltar",
style: TextStyle(fontSize: 20),
),
style: ElevatedButton.styleFrom(
primary: Colors.purple, minimumSize: Size(92, 36)))
]),
),
);
}
Column getColumn() {
List<Widget> list = [];
list.add(Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Text('Email: ${widget.partner.email}',
style: TextStyle(fontSize: 16)),
));
list.add(Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Text('CPF/CNPJ: ${widget.partner.cpfCnpj}',
style: TextStyle(fontSize: 16)),
));
list.add(Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Text('Endereço: ${widget.partner.addresses}',
style: TextStyle(fontSize: 16)),
));
list.add(Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Text('Status: ${widget.partner.status?.label}',
style: TextStyle(fontSize: 16)),
));
/*
final String? cpfCnpj;
final List<AddressModel>? addresses;
*/
return new Column(children: list);
}
Row showButtons() {
if (widget.partner.status == PartnerStatusEnum.PENDING) {
return Row(
children: [
Padding(
padding: EdgeInsets.fromLTRB(100, 0, 0, 20),
),
ElevatedButton(
onPressed: () => {changeStatus(false)},
child: Text(
"Rejeitar",
style: TextStyle(fontSize: 20),
),
style: ElevatedButton.styleFrom(
primary: Colors.red, minimumSize: Size(92, 36))),
Padding(
padding: EdgeInsets.fromLTRB(10, 0, 0, 20),
),
ElevatedButton(
onPressed: () => {changeStatus(true)},
child: Text(
"Aceitar",
style: TextStyle(fontSize: 20),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue, minimumSize: Size(92, 36)))
],
);
} else if (widget.partner.status == PartnerStatusEnum.REJECTED) {
return Row(
children: [
Padding(
padding: EdgeInsets.fromLTRB(100, 0, 0, 20),
),
Padding(
padding: EdgeInsets.fromLTRB(57, 0, 0, 20),
),
ElevatedButton(
onPressed: () => {changeStatus(true)},
child: Text(
"Aceitar",
style: TextStyle(fontSize: 20),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue, minimumSize: Size(92, 36)))
],
);
} else {
return Row(
children: [
Padding(
padding: EdgeInsets.fromLTRB(154, 0, 0, 20),
),
ElevatedButton(
onPressed: () => {changeStatus(false)},
child: Text(
"Rejeitar",
style: TextStyle(fontSize: 20),
),
style: ElevatedButton.styleFrom(
primary: Colors.red, minimumSize: Size(92, 36))),
],
);
}
}
changeStatus(bool status) async {
if (status) {
await PartnerService()
.patchPartnerStatus(PartnerStatus(true), widget.partner.id);
} else {
await PartnerService()
.patchPartnerStatus(PartnerStatus(false), widget.partner.id);
}
Navigator.pop(context);
}
}
import 'package:apus_drones_mobile/constants/Constants.dart';
import 'package:apus_drones_mobile/models/PartnerModel.dart';
import 'package:apus_drones_mobile/services/PartnerService.dart';
import 'package:apus_drones_mobile/services/ProfileService.dart';
import 'package:flutter/material.dart';
class PartnerEditProfileScreen extends StatefulWidget {
final PartnerModel? partner;
PartnerEditProfileScreen({Key? key, required this.partner}) : super(key: key);
@override
_PartnerEditProfileScreenState createState() =>
_PartnerEditProfileScreenState();
}
class _PartnerEditProfileScreenState extends State<PartnerEditProfileScreen> {
TextEditingController nameController = TextEditingController();
TextEditingController cpfController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController emailController = TextEditingController();
// TextEditingController cepController = TextEditingController();
// TextEditingController addressController = TextEditingController();
late bool passwordVisibility;
//Partner
PartnerModel? _partner;
PartnerService partnerService = PartnerService();
ProfileService profileService = ProfileService();
@override
void initState() {
super.initState();
final _currentPartner = widget.partner;
this.setState(() {
_partner = _currentPartner;
if (_currentPartner != null) {
nameController.value = TextEditingValue(text: _currentPartner.name);
cpfController.value =
TextEditingValue(text: _currentPartner.cpfCnpj ?? '');
emailController.value =
TextEditingValue(text: _currentPartner.email ?? '');
// addressController.value = TextEditingValue(
// text: _currentPartner.addresses?[0].toString() ?? '');
// cepController.value =
// TextEditingValue(text: _currentPartner.addresses?[0].zipCode ?? '');
}
passwordVisibility = false;
});
}
void updatePartner() async {
final _currentPartner = _partner;
if (_currentPartner == null) {
return;
}
PartnerModel newPartner = PartnerModel(
id: _currentPartner.id,
name: nameController.text,
email: emailController.text,
cpfCnpj: cpfController.text,
avatarUrl: _currentPartner.avatarUrl,
status: _currentPartner.status);
try {
await profileService.updatePartnerProfile(newPartner);
Navigator.pop(context);
} catch (error) {
print(error);
}
}
void updateCustomerProfilePhoto() {
//customer?.avatarUrl =
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () async {
Navigator.of(context).pushNamed('LoginScreen');
},
icon: Icon(
Icons.arrow_back_rounded,
color: Colors.black,
size: 24,
)),
title: Text('Editar Perfil'),
),
body: SingleChildScrollView(
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Padding(
padding: EdgeInsets.only(top: 15),
child: Column(
children: [
fotoPerfil(),
Column(
mainAxisSize: MainAxisSize.max,
children: [
inputUsuarioTxt(
"Nome", "Ex: João da Silva", nameController),
inputUsuarioNumber(
"CPF", "Ex: 123.456.789-00", cpfController),
inputUsuarioTxt(
"Email", "Ex: exemplo@gmail.com", emailController),
// inputUsuarioTxt("Endereço", "Ex: Rua Assis Brasil, 123",
// addressController),
// inputUsuarioNumber("CEP", "Ex: 12345-678", cepController),
inputUsuarioSenha("Senha", passwordController),
botoesRodape(),
],
)
],
),
),
),
),
);
}
fotoPerfil() {
return Center(
child: Stack(
children: [
Container(
width: 130,
height: 130,
decoration: BoxDecoration(
border: Border.all(
width: 4, color: Theme.of(context).scaffoldBackgroundColor),
boxShadow: [
BoxShadow(
spreadRadius: 2,
blurRadius: 8,
color: Colors.black.withOpacity(0.1),
)
],
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage(_partner?.avatarUrl ?? IMG_NO_PHOTO),
),
),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
border: Border.all(
width: 4,
color: Theme.of(context).scaffoldBackgroundColor)),
child: IconButton(
padding: EdgeInsets.all(0),
onPressed: () {
print('Button Pressed');
//Se usuário logado for cliente
updateCustomerProfilePhoto();
//Se usuário logado for parceiro
//updatePartnerProfilePhoto();
},
icon: Icon(
Icons.edit,
color: Colors.white,
),
),
),
)
],
),
);
}
inputUsuarioTxt(
String labelText, String hintText, TextEditingController controller) {
return Padding(
padding: EdgeInsets.only(left: 20, top: 25, right: 20, bottom: 0),
child: TextFormField(
controller: controller,
obscureText: false,
decoration: InputDecoration(
labelText: labelText,
labelStyle: TextStyle(
fontFamily: 'Poppins',
),
hintText: hintText,
hintStyle: TextStyle(
fontFamily: 'Poppins',
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
filled: true,
),
style: TextStyle(
fontFamily: 'Poppins',
),
keyboardType: TextInputType.name,
),
);
}
inputUsuarioNumber(
String labelText, String hintText, TextEditingController controller) {
return Padding(
padding: EdgeInsets.only(left: 20, top: 25, right: 20, bottom: 0),
child: TextFormField(
controller: controller,
obscureText: false,
decoration: InputDecoration(
labelText: labelText,
labelStyle: TextStyle(
fontFamily: 'Poppins',
),
hintText: hintText,
hintStyle: TextStyle(
fontFamily: 'Poppins',
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
filled: true,
),
style: TextStyle(
fontFamily: 'Poppins',
),
keyboardType: TextInputType.number,
),
);
}
inputUsuarioSenha(String labelText, TextEditingController controller) {
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(20, 15, 20, 0),
child: TextFormField(
controller: controller,
obscureText: !passwordVisibility,
decoration: InputDecoration(
labelText: labelText,
labelStyle: TextStyle(
fontFamily: 'Poppins',
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
filled: true,
suffixIcon: InkWell(
onTap: () => setState(
() => passwordVisibility = !passwordVisibility,
),
child: Icon(
passwordVisibility
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
color: Color(0xFF757575),
size: 22,
),
),
),
style: TextStyle(
fontFamily: 'Poppins',
),
keyboardType: TextInputType.visiblePassword,
),
);
}
botoesRodape() {
return Padding(
padding: EdgeInsets.only(top: 50),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
ElevatedButton(
onPressed: () {
print('Button pressed ...');
Navigator.pop(context);
},
child: Text(
'CANCELAR',
style: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFFFB0808),
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.white,
fixedSize: Size(150, 40),
elevation: 3,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
),
),
ElevatedButton(
onPressed: () {
print('Button pressed ...');
updatePartner();
},
child: Text(
'SALVAR',
style: TextStyle(
fontFamily: 'Poppins',
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xFFFB0808),
fixedSize: Size(150, 40),
elevation: 3,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
),
),
]),
);
}
}
......@@ -7,6 +7,7 @@ import 'package:apus_drones_mobile/screens/Appbar.dart';
import 'package:apus_drones_mobile/services/LocalNotification.dart';
import 'package:apus_drones_mobile/services/PartnerService.dart';
import 'package:apus_drones_mobile/widgets/BotNavBar.dart';
import 'package:apus_drones_mobile/widgets/FilterOrderStatusMenu.dart';
import 'package:apus_drones_mobile/widgets/PartnerOrderCard.dart';
import 'package:apus_drones_mobile/widgets/PartnerOrderModal.dart';
import 'package:flutter/material.dart';
......@@ -93,6 +94,16 @@ class _PartnerOrdersScreenState extends State<PartnerOrdersScreen> {
}));
}
_changeStatus(OrderStatus status) {
String filter = status.value;
if (status == OrderStatus.ALL) {
filter = '';
}
service.getAllOrders(filter).then((orders) => this.setState(() {
orderList = orders;
}));
}
void changeModalOpenToFalse() {
modalOpen = false;
}
......@@ -135,6 +146,13 @@ class _PartnerOrdersScreenState extends State<PartnerOrdersScreen> {
style: TextStyle(fontSize: 12, fontStyle: FontStyle.italic),
),
)),
Container(
child: Padding(
padding: EdgeInsets.all(12),
child: FilterOrderStatusMenu(
startingStatus: OrderStatus.ALL,
changeStatusCallback: this._changeStatus)),
),
Expanded(
child: ListView.builder(
itemBuilder: (ctx, index) => PartnerOrderCard(
......
import 'package:apus_drones_mobile/constants/Constants.dart';
import 'package:apus_drones_mobile/models/PartnerModel.dart';
import 'package:apus_drones_mobile/screens/Appbar.dart';
import 'package:apus_drones_mobile/screens/PartnerEditProfileScreen.dart';
import 'package:apus_drones_mobile/services/PartnerService.dart';
import 'package:apus_drones_mobile/widgets/UserDisplayedProperty.dart';
import 'package:flutter/material.dart';
......@@ -33,73 +34,86 @@ class _PartnerProfileState extends State<PartnerProfile> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: Appbar(
title: "Parceiro - ${this.partner?.name ?? ''}",
),
body: Column(
children: [
Padding(
padding: EdgeInsets.all(20),
child:
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
width: 140.0,
height: 140.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(width: 3.0, color: Colors.grey),
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
partner?.avatarUrl ?? IMG_NO_PHOTO))),
),
]),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${partner?.name}",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
)
],
appBar: Appbar(
title: "Parceiro - ${this.partner?.name ?? ''}",
),
body: Column(
children: [
Padding(
padding: EdgeInsets.all(20),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
width: 140.0,
height: 140.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(width: 3.0, color: Colors.grey),
image: DecorationImage(
fit: BoxFit.fill,
image:
NetworkImage(partner?.avatarUrl ?? IMG_NO_PHOTO))),
),
]),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${partner?.name}",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${partner?.email}",
style: TextStyle(fontSize: 16),
)
],
),
Padding(
padding: EdgeInsets.all(16),
child: Padding(
padding: EdgeInsets.only(top: 24),
child: Column(
children: [
Padding(
padding: EdgeInsets.all(8),
child: UserDisplayedProperty<String?>(
name: "CPF / CNPJ",
value: partner?.cpfCnpj,
),
),
Padding(
padding: EdgeInsets.all(8),
child: UserDisplayedProperty<String?>(
name: "Endereço",
value: (partner?.addresses?.isEmpty ?? true
? null
: partner?.addresses?.first.toString()) ??
"Endereço não cadastrado",
),
)
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${partner?.email}",
style: TextStyle(fontSize: 16),
)
],
),
],
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PartnerEditProfileScreen(partner: partner),
),
Padding(
padding: EdgeInsets.all(16),
child: Padding(
padding: EdgeInsets.only(top: 24),
child: Column(
children: [
Padding(
padding: EdgeInsets.all(8),
child: UserDisplayedProperty<String?>(
name: "CPF / CNPJ",
value: partner?.cpfCnpj,
),
),
Padding(
padding: EdgeInsets.all(8),
child: UserDisplayedProperty<String?>(
name: "Endereço",
value: (partner?.addresses?.isEmpty ?? true
? null
: partner?.addresses?.first.toString()) ??
"Endereço não cadastrado",
),
)
],
),
))
],
));
);
},
label: Icon(Icons.edit),
shape: CircleBorder(),
),
);
}
}
import 'package:apus_drones_mobile/constants/OrderStatus.dart';
import 'package:apus_drones_mobile/constants/UserType.dart';
import 'package:apus_drones_mobile/models/PartnerOrderModel.dart';
import 'package:apus_drones_mobile/screens/Appbar.dart';
import 'package:apus_drones_mobile/services/OrderService.dart';
import 'package:apus_drones_mobile/services/PartnerService.dart';
import 'package:apus_drones_mobile/widgets/BotNavBar.dart';
import 'package:apus_drones_mobile/widgets/Fee.dart';
import 'package:apus_drones_mobile/screens/PartnerOrdersScreen.dart';
import 'package:apus_drones_mobile/widgets/PartnerOrderDetailsHeader.dart';
import 'package:apus_drones_mobile/widgets/ProductCard.dart';
import 'package:apus_drones_mobile/widgets/StatusButton.dart';
import 'package:flutter/material.dart';
class PilotOrderDetailsScreen extends StatefulWidget {
final int id;
PilotOrderDetailsScreen({Key? key, required this.id}) : super(key: key);
@override
_PilotOrderDetailsState createState() => _PilotOrderDetailsState();
}
class _PilotOrderDetailsState extends State<PilotOrderDetailsScreen> {
late PartnerOrderModel order;
PartnerService partnerService = new PartnerService();
OrderService orderService = new OrderService();
bool orderReceived = false;
_fetchOrder() {
partnerService.getOrder(widget.id).then((o) => this.setState(() {
order = o;
orderReceived = true;
}));
}
@override
void initState() {
super.initState();
orderReceived = false;
this._fetchOrder();
}
@override
Widget build(BuildContext context) {
return render();
}
Scaffold render() {
if (orderReceived) {
return Scaffold(
appBar: Appbar(title: 'Pedido ${order.id}'),
bottomNavigationBar: BotNavBar(role: UserType.PARTNER),
body: Container(
margin: EdgeInsets.symmetric(horizontal: 12.0),
child: Column(
children: [
Padding(
padding: EdgeInsets.all(16),
child: Container(
child: StatusButton(status: this.order.status),
),
),
PartnerOrderDetailsHeader(order: this.order),
Container(
alignment: Alignment.centerLeft,
margin: EdgeInsets.only(left: 12.0),
child: Text(
'Produtos:',
style: TextStyle(fontSize: 20),
)),
Expanded(child: _generateItems()),
Container(
margin: EdgeInsets.only(
top: 25.0,
),
child: Column(
children: _buildFooter(context),
),
),
],
),
));
}
return Scaffold();
}
ListView _generateItems() {
List<ProductCard> products = this
.order
.items
.map((item) => ProductCard(
product: item.product,
quantity: item.quantity,
))
.toList();
return ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) => Column(
children: products,
),
itemCount: products.length,
);
}
List<Widget> _buildFooter(BuildContext context) {
List<Widget> footernWidgets = [
Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Fee(
productsSumPrice: this.order.orderPrice,
deliveryFee: this.order.deliveryPrice,
totalPrice: _totalPrice(this.order)),
)
];
if (this.order.status == OrderStatus.PICKING_UP) {
footernWidgets
.add(_buildButton(context, "Coletar", OrderStatus.IN_FLIGHT));
} else if (this.order.status == OrderStatus.IN_FLIGHT) {
footernWidgets
.add(_buildButton(context, "Entregue", OrderStatus.DELIVERED));
}
return footernWidgets;
}
Widget _buildButton(
BuildContext context, String buttonMessage, OrderStatus toStatus) {
return Padding(
padding: const EdgeInsets.only(bottom: 15.0),
child: Align(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
onPressed: () {
_updateOrderStatus(toStatus).then((_) => {
// TODO: redirect to pilot screen
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => PilotOrdersScreen()))
});
},
style: ElevatedButton.styleFrom(
padding:
EdgeInsets.only(top: 12, left: 60, right: 60, bottom: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)))),
child: Text(buttonMessage,
style: TextStyle(
fontSize: 16,
color: Colors.white,
)))),
);
}
Future<PartnerOrderModel?> _updateOrderStatus(OrderStatus toStatus) {
this.order.status = toStatus;
return orderService.updateOrder(this.order);
}
}
double _totalPrice(PartnerOrderModel order) =>
order.orderPrice + order.deliveryPrice;
......@@ -15,6 +15,7 @@ import 'package:flutter/scheduler.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import '../Appbar.dart';
import '../PartnerDetailScreen.dart';
import 'ListOfProducts.dart';
class ListOfPartners extends StatefulWidget {
......@@ -79,7 +80,7 @@ class _ListOfPartnersState extends State<ListOfPartners> {
}
void callNewOrders() async {
String filter = 'PICKING_UP';
String filter = 'IN_FLIGHT';
final orders = await orderService.myOrders(filtro: filter);
final _orderList = orderList;
......@@ -146,6 +147,7 @@ class _ListOfPartnersState extends State<ListOfPartners> {
backgroundColor: Colors.white,
body: Column(
children: [
Padding(padding: EdgeInsets.fromLTRB(10, 0, 2, 0.0)),
Searchbar(),
Expanded(
child: SingleChildScrollView(
......
import 'package:apus_drones_mobile/constants/PartnerStatusEnum.dart';
import 'package:apus_drones_mobile/constants/UserType.dart';
import 'package:apus_drones_mobile/constants/Constants.dart';
import 'package:apus_drones_mobile/models/PartnerModel.dart';
......@@ -21,7 +22,8 @@ class ListOfProducts extends StatefulWidget {
}
class _ListOfProductsState extends State<ListOfProducts> {
PartnerModel partner = new PartnerModel(id: 0, name: "", avatarUrl: "");
PartnerModel partner = new PartnerModel(
id: 0, name: "", avatarUrl: "", status: PartnerStatusEnum.PENDING);
List<ProductModel> products = [];
ProductService service = new ProductService();
......
import 'dart:convert';
import 'dart:io';
import 'package:apus_drones_mobile/assets/config.dart';
import 'package:apus_drones_mobile/constants/UserType.dart';
......@@ -14,20 +15,38 @@ class AuthService {
headers: {"Content-Type": "application/json"},
body: json.encode(loginInfo.toJson()),
);
Map<String, dynamic> rsBody = json.decode(response.body);
final status = response.statusCode;
switch (status) {
case HttpStatus.ok:
return this._loginSuccess(response);
case HttpStatus.forbidden:
return this._loginForbidden();
default:
return {};
}
}
Future<Map<String, dynamic>> _loginSuccess(http.Response response) async {
Map<String, dynamic> rsBody = json.decode(response.body);
final token = rsBody["jwtToken"];
if (token == null) {
return {};
}
Map<String, dynamic> tokenData = JwtDecoder.decode(token);
final provider = AuthProvider();
await provider.setToken(token);
UserType role = UserType.from[tokenData["Role"]];
return {
'success': true,
'status': HttpStatus.ok,
'accessToken': token,
'role': role
};
}
return {"accessToken": token, "role": role};
Map<String, dynamic> _loginForbidden() {
return {'success': false, 'status': HttpStatus.forbidden};
}
}
import 'package:apus_drones_mobile/assets/config.dart';
import 'package:places_service/places_service.dart';
class LocationService {
final _placesService = PlacesService();
LocationService() {
_placesService.initialize(
apiKey: Config.GOOGLE_API_KEY,
);
}
Future<PlacesDetails?> getPlaceDetails(String placeId) async {
if (placeId.isEmpty) {
return Future.value(null);
}
return await _placesService.getPlaceDetails(placeId);
}
Future<List<PlacesAutoCompleteResult>> getPlaces(String searchTerm) async {
if (searchTerm.length < 5) {
return [];
}
try {
final autoCompleteSuggestions =
await _placesService.getAutoComplete(searchTerm);
return autoCompleteSuggestions;
} catch (error) {
return [];
}
}
}
......@@ -4,6 +4,7 @@ import 'package:apus_drones_mobile/assets/config.dart';
import 'package:apus_drones_mobile/models/CreatePartner.dart';
import 'package:apus_drones_mobile/models/PartnerModel.dart';
import 'package:apus_drones_mobile/models/PartnerOrderModel.dart';
import 'package:apus_drones_mobile/models/PartnerStatus.dart';
import 'package:apus_drones_mobile/models/ProductModel.dart';
import 'package:apus_drones_mobile/providers/AuthProvider.dart';
import 'package:apus_drones_mobile/utils/httpHeaders.dart';
......@@ -64,11 +65,26 @@ class PartnerService {
Uri.parse('${Config.apiURL}/partners'),
headers: await getHttpHeaders(),
);
List<dynamic> rsBody = json.decode(response.body);
List<PartnerModel> partners =
rsBody.map((product) => PartnerModel.fromJson(product)).toList();
return partners;
try {
List<dynamic> rsBody = json.decode(response.body);
List<PartnerModel> partners =
rsBody.map((product) => PartnerModel.fromJson(product)).toList();
return partners;
} catch (error) {
return [];
}
}
Future<PartnerModel> getPartner(int id) async {
http.Response response = await http.get(
Uri.parse('${Config.apiURL}/partners/$id'),
headers: await getHttpHeaders(),
);
var rsBody = json.decode(response.body);
PartnerModel partner = PartnerModel.fromJson(rsBody);
return partner;
}
Future<PartnerModel> getProfile() async {
......@@ -94,4 +110,18 @@ class PartnerService {
print(error);
}
}
Future<void> patchPartnerStatus(PartnerStatus status, int id) async {
print(json.encode(status.toJson()));
try {
http.Response response = await http.patch(
Uri.parse('${Config.apiURL}/partners/$id/approve'),
headers: await getHttpHeaders(),
body: json.encode(status.toJson()));
print('response: ${response.statusCode} - ${response.body}');
} catch (error) {
print(error);
}
}
}
import 'dart:convert';
import 'package:apus_drones_mobile/assets/config.dart';
import 'package:apus_drones_mobile/models/CustomerModel.dart';
import 'package:apus_drones_mobile/models/PartnerModel.dart';
import 'package:apus_drones_mobile/utils/httpHeaders.dart';
import 'package:http/http.dart' as http;
class ProfileService {
Future<void> updateCustomerProfile(CustomerModel customer) async {
print(json.encode(customer.toJson()));
http.Response response = await http.post(
Uri.parse('${Config.apiURL}/customers'),
headers: await getHttpHeaders(),
body: json.encode(customer.toJson()));
if (response.statusCode != 200) {
throw '${response.statusCode}: ${response.body}';
}
print('response: ${response.statusCode} - ${response.body}');
}
Future<void> updatePartnerProfile(PartnerModel partner) async {
print(json.encode(partner.toJson()));
http.Response response = await http.post(
Uri.parse('${Config.apiURL}/partners'),
headers: await getHttpHeaders(),
body: json.encode(partner.toJson()));
if (response.statusCode != 200) {
throw '${response.statusCode}: ${response.body}';
}
print('response: ${response.statusCode} - ${response.body}');
}
}
import 'package:apus_drones_mobile/constants/UserType.dart';
import 'package:apus_drones_mobile/screens/PartnerOrdersScreen.dart';
import 'package:apus_drones_mobile/screens/PilotOrderDetailScreen.dart';
import 'package:apus_drones_mobile/screens/clients/ListOfPartners.dart';
import 'package:flutter/material.dart';
......@@ -10,7 +11,8 @@ Widget getRoleHomeScreen(UserType role) {
case UserType.PARTNER:
return PartnerOrdersScreen();
case UserType.PILOT:
throw new Exception('Não há telas para o piloto ainda');
// TODO: alterar para listagem de pedidos
return new PilotOrderDetailsScreen(id: 1);
default:
throw new Exception('Tipo de usuário desconhecido');
}
......
import 'package:apus_drones_mobile/constants/UserType.dart';
import 'package:apus_drones_mobile/screens/CustomerProfile.dart';
import 'package:apus_drones_mobile/screens/PartnerProfile.dart';
import 'package:apus_drones_mobile/screens/PilotOrderDetailScreen.dart';
import 'package:flutter/material.dart';
Widget getRoleProfileScreen(UserType role) {
......@@ -10,7 +11,8 @@ Widget getRoleProfileScreen(UserType role) {
case UserType.PARTNER:
return PartnerProfile();
case UserType.PILOT:
throw new Exception('Não há telas para o piloto ainda');
// TODO: alterar para listagem de pedidos
return new PilotOrderDetailsScreen(id: 1);
default:
throw new Exception('Tipo de usuário desconhecido');
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment