import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'controls/apiClient.dart'; import 'controls/databaseClient.dart'; import 'models/dog.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( primarySwatch: Colors.cyan, ), home: DogPage(), ); } } class DogPage extends StatefulWidget { @override _DogPageState createState() => _DogPageState(); } class _DogPageState extends State { final GlobalKey _formStateKey = GlobalKey(); final _scaffoldKey = GlobalKey(); Future> dogs; List dogsFromApi; List dogsFromDb; String _dogId; String _dogName; int _dogAge; bool isUpdate = false; String dogIdForUpdate; DatabaseClient db; ApiClient api; final _dogIdController = TextEditingController(); final _dogNameController = TextEditingController(); final _dogAgeController = TextEditingController(); @override void initState() { super.initState(); db = DatabaseClient(); api = ApiClient(); openDatabase(); } openDatabase() async { await db.open(); await refreshDogList(); } refreshDogList() { setState(() { dogs = db.getDogs(); }); } Future uploadOnApi(dog) async { try { Dog newDog = await api.insertDog(dog); final snackBar = SnackBar( content: Text('Dados enviados com sucesso para a API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.green, ); _scaffoldKey.currentState.showSnackBar(snackBar); return newDog; } catch (error) { final snackBar = SnackBar( content: Text('Erro ao enviar dado para a API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); return null; } } uploadOnDb(dog) async { try { await db.insertDog(dog); final snackBar = SnackBar( content: Text('Dados enviados com sucesso para a BD!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.green, ); _scaffoldKey.currentState.showSnackBar(snackBar); } catch (error) { final snackBar = SnackBar( content: Text('Erro ao enviar dado para o BD!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); } } deleteOnApi(Dog dog) async { try { await api.deleteDog(dog.id); final snackBar = SnackBar( content: Text('Dado removido com sucesso da API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.green, ); _scaffoldKey.currentState.showSnackBar(snackBar); } catch (error) { final snackBar = SnackBar( content: Text('Erro ao remover dado da API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); } } deleteOnDb(Dog dog) async { try { await db.deleteDog(dog.id); final snackBar = SnackBar( content: Text('Dado removido com sucesso do BD!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.green, ); _scaffoldKey.currentState.showSnackBar(snackBar); } catch (error) { final snackBar = SnackBar( content: Text('Erro ao remover dado do BD!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); } } Future updateOnApi(Dog dog) async { try { Dog newDog = await api.updateDog(dog); final snackBar = SnackBar( content: Text('Dado atualizado com sucesso da API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.green, ); _scaffoldKey.currentState.showSnackBar(snackBar); return newDog; } catch (error) { final snackBar = SnackBar( content: Text('Erro ao atualizar dado na API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); return null; } } updateOnDb(Dog dog) async { try { await db.updateDog(dog); final snackBar = SnackBar( content: Text('Dado atualizado com sucesso do BD!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.green, ); _scaffoldKey.currentState.showSnackBar(snackBar); } catch (error) { final snackBar = SnackBar( content: Text('Erro ao atualizar dado no BD!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); } } downloadFromApi() async { var errorDownload = false; try { dogsFromApi = await api.getDogs(); final snackBar = SnackBar( content: Text('Dados lidos com sucesso na API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.green, ); _scaffoldKey.currentState.showSnackBar(snackBar); } catch (erro) { errorDownload = true; final snackBar = SnackBar( content: Text('Erro ao comunicar com a API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); } if (errorDownload == false) { await db.deleteAllDogs(); await db.insertDogs(dogsFromApi); refreshDogList(); final snackBar = SnackBar( content: Text('Dados armazenados com sucesso no BD!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.green, ); _scaffoldKey.currentState.showSnackBar(snackBar); } } @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: AppBar(title: Text('App Dog'), actions: [ Padding( padding: EdgeInsets.only(right: 20.0), child: GestureDetector( onTap: () { downloadFromApi(); }, child: Icon(Icons.cloud_download), )), ]), body: Column( children: [ Form( key: _formStateKey, autovalidate: true, child: Column( children: [ Padding( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), child: TextFormField( enabled: false, onSaved: (value) { _dogId = value; }, controller: _dogIdController, keyboardType: TextInputType.number, decoration: InputDecoration( disabledBorder: new UnderlineInputBorder( borderSide: new BorderSide( color: Colors.grey, width: 2, style: BorderStyle.solid)), labelText: "Id do cachorro", icon: Icon( Icons.vpn_key, color: Colors.grey, ), fillColor: Colors.white, labelStyle: TextStyle( color: Colors.grey, )), ), ), Padding( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), child: TextFormField( validator: (value) { if (value.isEmpty) { return 'Por favor insira o nome do cachorro'; } if (value.trim() == "") return "Somente espaço não é válido!"; return null; }, onSaved: (value) { _dogName = value; }, controller: _dogNameController, decoration: InputDecoration( focusedBorder: new UnderlineInputBorder( borderSide: new BorderSide( color: Colors.cyan, width: 2, style: BorderStyle.solid)), labelText: "Nome do cachorro", icon: Icon( Icons.pets, color: Colors.cyan, ), fillColor: Colors.white, labelStyle: TextStyle( color: Colors.cyan, )), ), ), Padding( padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), child: TextFormField( validator: (value) { if (value.isEmpty) { return 'Por favor insira a idade do cachorro'; } if (value.trim() == "") return "Somente espaço não é válido!"; return null; }, onSaved: (value) { _dogAge = int.parse(value); }, controller: _dogAgeController, keyboardType: TextInputType.number, decoration: InputDecoration( focusedBorder: new UnderlineInputBorder( borderSide: new BorderSide( color: Colors.cyan, width: 2, style: BorderStyle.solid)), labelText: "Idade do cachorro", icon: Icon( Icons.calendar_today, color: Colors.cyan, ), fillColor: Colors.white, labelStyle: TextStyle( color: Colors.cyan, )), ), ), ], ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ RaisedButton( color: Colors.cyan, child: Text( (isUpdate ? 'ATUALIZAR' : 'ADICIONAR'), style: TextStyle(color: Colors.white), ), onPressed: () async { FocusScope.of(context).requestFocus(new FocusNode()); if (isUpdate) { if (_formStateKey.currentState.validate()) { _formStateKey.currentState.save(); try { Dog dog = Dog( id: dogIdForUpdate, name: _dogName, age: _dogAge); await updateOnDb(await updateOnApi(dog)); refreshDogList(); setState(() { isUpdate = false; }); } catch (error) { print(error); final snackBar = SnackBar( content: Text('Erro ao comunicar com a API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); } } } else { if (_formStateKey.currentState.validate()) { _formStateKey.currentState.save(); try { Dog dog = Dog(id: _dogId, name: _dogName, age: _dogAge); await uploadOnDb(await uploadOnApi(dog)); refreshDogList(); } catch (error) { final snackBar = SnackBar( content: Text('Erro ao comunicar com a API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); } } } _dogIdController.text = ''; _dogNameController.text = ''; _dogAgeController.text = ''; }, ), Padding( padding: EdgeInsets.all(10), ), RaisedButton( color: Colors.red, child: Text( (isUpdate ? 'CANCELAR ATUALIZAÇÃO' : 'LIMPAR'), style: TextStyle(color: Colors.white), ), onPressed: () { _dogIdController.text = ''; _dogNameController.text = ''; _dogAgeController.text = ''; setState(() { isUpdate = false; dogIdForUpdate = null; }); }, ), ], ), const Divider( height: 20.0, ), Expanded( child: FutureBuilder( future: dogs, builder: (context, snapshot) { print(snapshot.connectionState); if (snapshot.data == null || snapshot.data.length == 0) { return Text('Sem dados para exibir'); } else if (snapshot.hasData) { return generateList(snapshot.data); } return CircularProgressIndicator(); }, ), ), ], ), ); } SingleChildScrollView generateList(List dogs) { return SingleChildScrollView( scrollDirection: Axis.vertical, child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( columns: [ DataColumn( label: Text('ID', style: TextStyle(fontStyle: FontStyle.italic)), ), DataColumn( label: Text('NOME', style: TextStyle(fontStyle: FontStyle.italic)), ), DataColumn( label: Text('IDADE', style: TextStyle(fontStyle: FontStyle.italic)), ), DataColumn( label: Text('DELETAR', style: TextStyle(fontStyle: FontStyle.italic)), ) ], rows: dogs .map( (dog) => DataRow( cells: [ DataCell( Text(dog.id.toString()), onTap: () { setState(() { isUpdate = true; dogIdForUpdate = dog.id; }); _dogIdController.text = dog.id.toString(); _dogNameController.text = dog.name; _dogAgeController.text = dog.age.toString(); }, ), DataCell( Text(dog.name), onTap: () { setState(() { isUpdate = true; dogIdForUpdate = dog.id; }); _dogIdController.text = dog.id.toString(); _dogNameController.text = dog.name; _dogAgeController.text = dog.age.toString(); }, ), DataCell( Text(dog.age.toString()), onTap: () { setState(() { isUpdate = true; dogIdForUpdate = dog.id; }); _dogIdController.text = dog.id.toString(); _dogNameController.text = dog.name; _dogAgeController.text = dog.age.toString(); }, ), DataCell( IconButton( icon: Icon(Icons.delete), onPressed: () { try { deleteOnApi(dog); deleteOnDb(dog); refreshDogList(); } catch (error) { final snackBar = SnackBar( content: Text('Erro ao comunicar com a API!'), duration: Duration(milliseconds: 500), backgroundColor: Colors.red, ); _scaffoldKey.currentState.showSnackBar(snackBar); } }, ), ), ], ), ) .toList(), ), ), ); } }