WIP
This commit is contained in:
parent
56f16d2934
commit
1dc611004a
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "flutter-freaccesss-hub",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"args": [
|
||||||
|
"--no-enable-impeller"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "flutter-freaccesss-hub (profile mode)",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "profile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "flutter-freaccesss-hub (release mode)",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "release"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -101,6 +101,7 @@ class _CardItemTemplateComponentWidgetState
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _generateImage() {
|
Widget _generateImage() {
|
||||||
|
print('img: ${widget.imagePath ?? ''}');
|
||||||
// CachedNetworkImage.evictFromCache(widget.imagePath ?? '');
|
// CachedNetworkImage.evictFromCache(widget.imagePath ?? '');
|
||||||
return ClipRRect(
|
return ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
|
|
@ -5,11 +5,14 @@ import 'dart:convert';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:hub/features/documents/index.dart' as doc;
|
||||||
import 'package:hub/features/notification/index.dart';
|
import 'package:hub/features/notification/index.dart';
|
||||||
import 'package:hub/features/storage/index.dart';
|
import 'package:hub/features/storage/index.dart';
|
||||||
|
import 'package:hub/shared/extensions/index.dart';
|
||||||
|
|
||||||
import 'package:hub/shared/utils/log_util.dart';
|
import 'package:hub/shared/utils/log_util.dart';
|
||||||
import 'package:hub/shared/utils/validator_util.dart';
|
import 'package:hub/shared/utils/validator_util.dart';
|
||||||
|
import 'package:hub/shared/widgets/widgets.dart';
|
||||||
|
|
||||||
import '/flutter_flow/flutter_flow_util.dart';
|
import '/flutter_flow/flutter_flow_util.dart';
|
||||||
import 'api_manager.dart';
|
import 'api_manager.dart';
|
||||||
|
@ -24,7 +27,7 @@ abstract class Api {
|
||||||
GetLicense getLicense = GetLicense();
|
GetLicense getLicense = GetLicense();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Endpoint {}
|
abstract interface class Endpoint {}
|
||||||
|
|
||||||
class FreAccessWSGlobal extends Api {
|
class FreAccessWSGlobal extends Api {
|
||||||
static String getBaseUrl() => 'https://freaccess.com.br/freaccess';
|
static String getBaseUrl() => 'https://freaccess.com.br/freaccess';
|
||||||
|
@ -70,6 +73,7 @@ class FreAccessWSGlobal extends Api {
|
||||||
static GetResidentsByProperty getResidentsByProperty =
|
static GetResidentsByProperty getResidentsByProperty =
|
||||||
GetResidentsByProperty();
|
GetResidentsByProperty();
|
||||||
static GetOpenedVisits getOpenedVisits = GetOpenedVisits();
|
static GetOpenedVisits getOpenedVisits = GetOpenedVisits();
|
||||||
|
@override
|
||||||
GetLicense getLicense = GetLicense();
|
GetLicense getLicense = GetLicense();
|
||||||
static GetProvSchedules getProvSchedules = GetProvSchedules();
|
static GetProvSchedules getProvSchedules = GetProvSchedules();
|
||||||
static GetCategories getCategories = GetCategories();
|
static GetCategories getCategories = GetCategories();
|
||||||
|
@ -77,6 +81,7 @@ class FreAccessWSGlobal extends Api {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetCategories extends Endpoint {
|
class GetCategories extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -113,7 +118,11 @@ class GetCategories extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetDocuments extends Endpoint {
|
class GetDocuments extends Endpoint {
|
||||||
Future<ApiCallResponse> call(final String page) async {
|
@override
|
||||||
|
Future<ApiCallResponse> call(
|
||||||
|
final dynamic page,
|
||||||
|
final Query query,
|
||||||
|
) async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||||
|
@ -124,6 +133,8 @@ class GetDocuments extends Endpoint {
|
||||||
const String atividade = 'listaDocumentos';
|
const String atividade = 'listaDocumentos';
|
||||||
const String pageSize = '10';
|
const String pageSize = '10';
|
||||||
// final bool isFiltered = filter != '' && filter != '.*';
|
// final bool isFiltered = filter != '' && filter != '.*';
|
||||||
|
// final isCategory = !category;
|
||||||
|
// final isDescription = !desc.isNullOrEmpty;
|
||||||
return await ApiManager.instance.makeApiCall(
|
return await ApiManager.instance.makeApiCall(
|
||||||
callName: 'listaDocumentos',
|
callName: 'listaDocumentos',
|
||||||
apiUrl: '$baseUrl/processRequest.php',
|
apiUrl: '$baseUrl/processRequest.php',
|
||||||
|
@ -131,12 +142,15 @@ class GetDocuments extends Endpoint {
|
||||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||||
params: {
|
params: {
|
||||||
// if (isFiltered) 'filter': filter,
|
// if (isFiltered) 'filter': filter,
|
||||||
|
|
||||||
'devUUID': devUUID,
|
'devUUID': devUUID,
|
||||||
'userUUID': userUUID,
|
'userUUID': userUUID,
|
||||||
'cliID': cliID,
|
'cliID': cliID,
|
||||||
'atividade': atividade,
|
'atividade': atividade,
|
||||||
'page': page,
|
'page': page.toString(),
|
||||||
'pageSize': pageSize,
|
'pageSize': pageSize,
|
||||||
|
if (query is doc.Category) 'categoryId': query.id,
|
||||||
|
if (query is doc.Document) 'searh': query.description,
|
||||||
},
|
},
|
||||||
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||||
returnBody: true,
|
returnBody: true,
|
||||||
|
@ -150,6 +164,7 @@ class GetDocuments extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetProvSchedules extends Endpoint {
|
class GetProvSchedules extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call(final String page, final String status) async {
|
Future<ApiCallResponse> call(final String page, final String status) async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -188,6 +203,7 @@ class GetProvSchedules extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetOpenedVisits extends Endpoint {
|
class GetOpenedVisits extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call(final String page) async {
|
Future<ApiCallResponse> call(final String page) async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -223,6 +239,7 @@ class GetOpenedVisits extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetResidentsByProperty extends Endpoint {
|
class GetResidentsByProperty extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call(final String page) async {
|
Future<ApiCallResponse> call(final String page) async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -257,6 +274,7 @@ class GetResidentsByProperty extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetVehiclesByProperty extends Endpoint {
|
class GetVehiclesByProperty extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call(final String page) async {
|
Future<ApiCallResponse> call(final String page) async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -293,6 +311,7 @@ class GetVehiclesByProperty extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetLicense extends Endpoint {
|
class GetLicense extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -327,6 +346,7 @@ class GetLicense extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnregisterDevice extends Endpoint {
|
class UnregisterDevice extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -357,6 +377,7 @@ class UnregisterDevice extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeletePet extends Endpoint {
|
class DeletePet extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({final int? petID = 0}) async {
|
Future<ApiCallResponse> call({final int? petID = 0}) async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -393,6 +414,7 @@ class DeletePet extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdatePet extends Endpoint {
|
class UpdatePet extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final int? petID,
|
final int? petID,
|
||||||
final String? image,
|
final String? image,
|
||||||
|
@ -452,6 +474,7 @@ class UpdatePet extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetPets extends Endpoint {
|
class GetPets extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final int? page,
|
final int? page,
|
||||||
final int? pageSize,
|
final int? pageSize,
|
||||||
|
@ -492,6 +515,7 @@ class GetPets extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetPetPhoto extends Endpoint {
|
class GetPetPhoto extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({final int? petId}) async {
|
Future<ApiCallResponse> call({final int? petId}) async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
|
|
||||||
|
@ -528,6 +552,7 @@ class GetPetPhoto extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegisterPet extends Endpoint {
|
class RegisterPet extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? image,
|
final String? image,
|
||||||
final String? name,
|
final String? name,
|
||||||
|
@ -585,6 +610,7 @@ class RegisterPet extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuscaEnconcomendas extends Endpoint {
|
class BuscaEnconcomendas extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? page,
|
final String? page,
|
||||||
final String? pageSize,
|
final String? pageSize,
|
||||||
|
@ -629,6 +655,7 @@ class BuscaEnconcomendas extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CancelaVisita extends Endpoint {
|
class CancelaVisita extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final int? idDestino,
|
final int? idDestino,
|
||||||
final int? idVisita,
|
final int? idVisita,
|
||||||
|
@ -674,6 +701,7 @@ class CancelaVisita extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeleteAccount extends Endpoint {
|
class DeleteAccount extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||||
|
@ -704,6 +732,7 @@ class DeleteAccount extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChangePanic extends Endpoint {
|
class ChangePanic extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? newSenhaPanico,
|
final String? newSenhaPanico,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -743,6 +772,7 @@ class ChangePanic extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChangePass extends Endpoint {
|
class ChangePass extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? newSenha,
|
final String? newSenha,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -782,6 +812,7 @@ class ChangePass extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class RespondeVinculo extends Endpoint {
|
class RespondeVinculo extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? tarefa,
|
final String? tarefa,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -819,6 +850,7 @@ class RespondeVinculo extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChangeNotifica extends Endpoint {
|
class ChangeNotifica extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? notifica,
|
final String? notifica,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -858,6 +890,7 @@ class ChangeNotifica extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdateIDE extends Endpoint {
|
class UpdateIDE extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
|
|
||||||
|
@ -897,6 +930,7 @@ class UpdateIDE extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdToken extends Endpoint {
|
class UpdToken extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
|
|
||||||
|
@ -930,6 +964,7 @@ class UpdToken extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginCall extends Endpoint {
|
class LoginCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final String devUUID =
|
final String devUUID =
|
||||||
|
@ -980,6 +1015,7 @@ class LoginCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegisterCall extends Endpoint {
|
class RegisterCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
required final String name,
|
required final String name,
|
||||||
required final String email,
|
required final String email,
|
||||||
|
@ -1019,6 +1055,7 @@ class RegisterCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChangePasswordCall extends Endpoint {
|
class ChangePasswordCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
required final String email,
|
required final String email,
|
||||||
required final String token,
|
required final String token,
|
||||||
|
@ -1059,6 +1096,7 @@ class ChangePasswordCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ForgotPasswordCall extends Endpoint {
|
class ForgotPasswordCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? email,
|
final String? email,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -1086,6 +1124,7 @@ class ForgotPasswordCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetLocalsCall extends Endpoint {
|
class GetLocalsCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
|
|
||||||
|
@ -1125,6 +1164,7 @@ class GetLocalsCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostScheduleVisitorCall extends Endpoint {
|
class PostScheduleVisitorCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
required final String documento,
|
required final String documento,
|
||||||
required final String nome,
|
required final String nome,
|
||||||
|
@ -1179,6 +1219,7 @@ class PostScheduleVisitorCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostScheduleVisitCall extends Endpoint {
|
class PostScheduleVisitCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? devDesc,
|
final String? devDesc,
|
||||||
final String? idVisitante,
|
final String? idVisitante,
|
||||||
|
@ -1241,6 +1282,7 @@ class PostScheduleVisitCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetScheduleVisitCall extends Endpoint {
|
class GetScheduleVisitCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final int? pageSize,
|
final int? pageSize,
|
||||||
final int? pageNumber,
|
final int? pageNumber,
|
||||||
|
@ -1522,6 +1564,7 @@ class GetScheduleVisitCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetDadosCall extends Endpoint {
|
class GetDadosCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
|
|
||||||
|
@ -1768,6 +1811,7 @@ class GetDadosCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetVisitorByDocCall extends Endpoint {
|
class GetVisitorByDocCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? documento,
|
final String? documento,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -1824,6 +1868,7 @@ class GetVisitorByDocCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetFotoVisitanteCall extends Endpoint {
|
class GetFotoVisitanteCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? documento,
|
final String? documento,
|
||||||
final String? tipo,
|
final String? tipo,
|
||||||
|
@ -1864,6 +1909,7 @@ class GetFotoVisitanteCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostProvVisitSchedulingCall extends Endpoint {
|
class PostProvVisitSchedulingCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? data,
|
final String? data,
|
||||||
final String? motivo,
|
final String? motivo,
|
||||||
|
@ -1918,6 +1964,7 @@ class PostProvVisitSchedulingCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetVisitsCall extends Endpoint {
|
class GetVisitsCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final int? pageSize,
|
final int? pageSize,
|
||||||
final int? pageNumber,
|
final int? pageNumber,
|
||||||
|
@ -2185,6 +2232,7 @@ class GetVisitsCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeleteVisitCall extends Endpoint {
|
class DeleteVisitCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? idVisita,
|
final String? idVisita,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -2233,6 +2281,7 @@ class DeleteVisitCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetPessoasLocalCall extends Endpoint {
|
class GetPessoasLocalCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call() async {
|
Future<ApiCallResponse> call() async {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
|
|
||||||
|
@ -2298,6 +2347,7 @@ class GetPessoasLocalCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class RespondeSolicitacaoCall extends Endpoint {
|
class RespondeSolicitacaoCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? referencia,
|
final String? referencia,
|
||||||
final String? tarefa,
|
final String? tarefa,
|
||||||
|
@ -2352,6 +2402,7 @@ class RespondeSolicitacaoCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetAccessCall extends Endpoint {
|
class GetAccessCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? pageSize,
|
final String? pageSize,
|
||||||
final String? pageNumber,
|
final String? pageNumber,
|
||||||
|
@ -2606,6 +2657,7 @@ class GetAccessCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetLiberationsCall extends Endpoint {
|
class GetLiberationsCall extends Endpoint {
|
||||||
|
@override
|
||||||
Stream<ApiCallResponse> call() {
|
Stream<ApiCallResponse> call() {
|
||||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||||
final StreamController<ApiCallResponse> controller = StreamController();
|
final StreamController<ApiCallResponse> controller = StreamController();
|
||||||
|
@ -2799,6 +2851,7 @@ class GetLiberationsCall extends Endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetMessagesCall extends Endpoint {
|
class GetMessagesCall extends Endpoint {
|
||||||
|
@override
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
final String? pageSize,
|
final String? pageSize,
|
||||||
final String? pageNumber,
|
final String? pageNumber,
|
||||||
|
|
|
@ -1,31 +1,60 @@
|
||||||
part of 'index.dart';
|
part of 'index.dart';
|
||||||
|
|
||||||
interface class Category extends Entity {
|
abstract interface class DocumentEntity extends Entity {}
|
||||||
|
|
||||||
|
interface class Category extends DocumentEntity {
|
||||||
|
final int id;
|
||||||
final Color color;
|
final Color color;
|
||||||
final String title;
|
final String title;
|
||||||
|
|
||||||
Category({
|
Category({
|
||||||
|
required this.id,
|
||||||
required this.color,
|
required this.color,
|
||||||
required this.title,
|
required this.title,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
factory Category.fromDesc(String desc) {
|
||||||
|
return Category(
|
||||||
|
id: 0,
|
||||||
|
color: Colors.transparent,
|
||||||
|
title: desc,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color isSelected() => Colors.black;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface class Document extends Entity {
|
interface class Document extends DocumentEntity {
|
||||||
final String title;
|
final int id;
|
||||||
|
final String description;
|
||||||
|
final String type;
|
||||||
final Category category;
|
final Category category;
|
||||||
final String to;
|
final String person;
|
||||||
final String from;
|
final String property;
|
||||||
final String createdAt;
|
String createdAt;
|
||||||
final String updatedAt;
|
String updatedAt;
|
||||||
|
|
||||||
Document({
|
Document({
|
||||||
|
required this.id,
|
||||||
|
required this.description,
|
||||||
|
required this.type,
|
||||||
|
required this.category,
|
||||||
|
required this.person,
|
||||||
|
required this.property,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
required this.category,
|
|
||||||
required this.to,
|
|
||||||
required this.from,
|
|
||||||
required this.title,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
factory Document.fromDesc(String desc) => Document(
|
||||||
|
id: 0,
|
||||||
|
description: desc,
|
||||||
|
type: '',
|
||||||
|
category: Category.fromDesc(''),
|
||||||
|
person: '',
|
||||||
|
property: '',
|
||||||
|
createdAt: '',
|
||||||
|
updatedAt: '',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DocumentItem extends StatelessWidget {
|
class DocumentItem extends StatelessWidget {
|
||||||
|
@ -77,6 +106,16 @@ class DocumentItem extends StatelessWidget {
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
);
|
);
|
||||||
|
final Map<String, dynamic> extra = <String, dynamic>{
|
||||||
|
'document': document,
|
||||||
|
kTransitionInfoKey: const TransitionInfo(
|
||||||
|
hasTransition: true,
|
||||||
|
transitionType: PageTransitionType.rightToLeft,
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
Future<Object?> onTap() =>
|
||||||
|
context.push('/documentViewerScreen', extra: extra);
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
|
@ -87,9 +126,9 @@ class DocumentItem extends StatelessWidget {
|
||||||
: MediaQuery.of(context).size.height * 2;
|
: MediaQuery.of(context).size.height * 2;
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () => print('Click'),
|
onTap: onTap,
|
||||||
enableFeedback: true,
|
enableFeedback: true,
|
||||||
overlayColor: MaterialStateProperty.all<Color>(primaryColor),
|
overlayColor: WidgetStateProperty.all<Color>(primaryColor),
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: boxHeight,
|
height: boxHeight,
|
||||||
|
@ -105,15 +144,16 @@ class DocumentItem extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: document.title,
|
message: document.description,
|
||||||
child: AutoText(
|
child: AutoText(
|
||||||
document.title,
|
document.description,
|
||||||
style: textStyleMajor,
|
style: textStyleMajor,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
AutoText(
|
AutoText(
|
||||||
document.updatedAt,
|
ValidatorUtil.toLocalDateTime(
|
||||||
|
'yyyy-MM-dd', document.updatedAt),
|
||||||
style: textStyleMinor,
|
style: textStyleMinor,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,102 +1,27 @@
|
||||||
part of 'index.dart';
|
part of 'index.dart';
|
||||||
|
|
||||||
class DocumentManagerScreen extends StatelessScreen {
|
class DocumentManagerScreen extends StatelessScreen {
|
||||||
DocumentManagerScreen({
|
final DocumentPageModel model;
|
||||||
super.key,
|
|
||||||
required this.documents,
|
|
||||||
required this.categories,
|
|
||||||
});
|
|
||||||
|
|
||||||
List<Document> documents;
|
const DocumentManagerScreen({
|
||||||
final List<Category> categories;
|
super.key,
|
||||||
|
required this.model,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final GlobalKey<LocalSearchViewState> _listViewKey =
|
|
||||||
GlobalKey<LocalSearchViewState>();
|
|
||||||
|
|
||||||
bool filter(document, query) {
|
|
||||||
final lowerQuery = query.toLowerCase();
|
|
||||||
return document.title.toLowerCase().contains(lowerQuery) ||
|
|
||||||
document.description.toLowerCase().contains(lowerQuery) ||
|
|
||||||
document.category.title.toLowerCase().contains(lowerQuery) ||
|
|
||||||
document.to.toLowerCase().contains(lowerQuery) ||
|
|
||||||
document.from.toLowerCase().contains(lowerQuery) ||
|
|
||||||
document.createdAt.toLowerCase().contains(lowerQuery) ||
|
|
||||||
document.updatedAt.toLowerCase().contains(lowerQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
DocumentItem itemBuilder(dynamic item) {
|
|
||||||
log('item: $item');
|
|
||||||
|
|
||||||
final doc = Document(
|
|
||||||
createdAt: '00/00/00',
|
|
||||||
updatedAt: '00/00/00',
|
|
||||||
category: Category(color: Colors.black, title: item['category']),
|
|
||||||
to: item['person'],
|
|
||||||
from: '',
|
|
||||||
title: item['description'],
|
|
||||||
);
|
|
||||||
final docItem = DocumentItem(document: doc);
|
|
||||||
return docItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
void filterByCategory(Category query) {
|
|
||||||
print('Test');
|
|
||||||
final state = _listViewKey.currentState;
|
|
||||||
|
|
||||||
if (state != null) {
|
|
||||||
state.safeSetState(() {
|
|
||||||
state.filteredItems = documents
|
|
||||||
.where((documents) => filter(documents, query.title))
|
|
||||||
.toList();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void unfilter(Category) {
|
|
||||||
final state = _listViewKey.currentState;
|
|
||||||
if (state != null) {
|
|
||||||
state.safeSetState(() {
|
|
||||||
state.filteredItems = documents;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final header = Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(15, 0, 50, 0),
|
|
||||||
child: Text('Últimos Documentos'),
|
|
||||||
),
|
|
||||||
CategoryCarousel(
|
|
||||||
categories: categories,
|
|
||||||
onSelect: filterByCategory,
|
|
||||||
onUnselect: unfilter,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
List<Document> filterByString(String query) {
|
|
||||||
return documents.where((documents) => filter(documents, query)).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
final SizedBox space = SizedBox(height: 30);
|
final SizedBox space = SizedBox(height: 30);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RemoteSearchListView<dynamic>(
|
child: RemoteSearchView<Document>(
|
||||||
key: _listViewKey,
|
key: model.searchKey,
|
||||||
header: header,
|
pagingController: model._pagingController,
|
||||||
onSearch: filterByString,
|
headerBuilder: model.listHeaderBuilder,
|
||||||
list: documents,
|
bodyBuilder: model.listBodyBuilder,
|
||||||
itemBuilder: itemBuilder,
|
dataProvider: model.generateDocuments,
|
||||||
filter: filter,
|
onFetchError: model.onFetchError,
|
||||||
title: '',
|
|
||||||
// fetchItems: (String ) { },,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
] //
|
] //
|
||||||
|
|
|
@ -1 +1,156 @@
|
||||||
part of 'index.dart';
|
part of 'index.dart';
|
||||||
|
|
||||||
|
class DocumentPageModel extends FlutterFlowModel<DocumentPage> {
|
||||||
|
@override
|
||||||
|
void dispose() {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState(BuildContext context) {}
|
||||||
|
|
||||||
|
final SearchKey searchKey = SearchKey();
|
||||||
|
final DocumentKey docKey = DocumentKey();
|
||||||
|
|
||||||
|
final PagingController<int, Document> _pagingController =
|
||||||
|
PagingController<int, Document>(firstPageKey: 1);
|
||||||
|
int count = 0;
|
||||||
|
final dynamic page = 1;
|
||||||
|
|
||||||
|
Query query = Document.fromDesc('');
|
||||||
|
|
||||||
|
late Document currentDocument;
|
||||||
|
bool isCategorySelected = false;
|
||||||
|
late Category currentCategory;
|
||||||
|
|
||||||
|
List<Document?> documents = [];
|
||||||
|
List<Category?> categories = [];
|
||||||
|
|
||||||
|
/// [listBodyBuilder]
|
||||||
|
Widget listBodyBuilder<T>(BuildContext context, Document item, int index) {
|
||||||
|
return DocumentItem(document: item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [listHeaderBuilder]
|
||||||
|
Widget listHeaderBuilder(BuildContext context) => Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(15, 0, 50, 0),
|
||||||
|
child: Text(
|
||||||
|
'Últimos Documentos',
|
||||||
|
style: TextStyle(
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: LimitedFontSizeUtil.getHeaderFontSize(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CategoryCarousel<Category>(
|
||||||
|
categories: categories,
|
||||||
|
filter: filterByCategory,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
/// [generateDocuments]
|
||||||
|
Future<(bool, List<Document?>)> generateDocuments(
|
||||||
|
pageKey, Query query) async {
|
||||||
|
final List<Document?> error = [null];
|
||||||
|
print('Query: ${query is Document}');
|
||||||
|
final GetDocuments getDocuments = FreAccessWSGlobal.getDocuments;
|
||||||
|
final ApiCallResponse newItems = await getDocuments.call(pageKey, query);
|
||||||
|
|
||||||
|
if (newItems.jsonBody == null) return (false, error);
|
||||||
|
if (newItems.jsonBody['error'] == true) return (false, error);
|
||||||
|
|
||||||
|
final List<dynamic> list = newItems.jsonBody['value']['list'];
|
||||||
|
|
||||||
|
late final List<Document> docs = [];
|
||||||
|
|
||||||
|
for (var item in list) {
|
||||||
|
log('-> generateDocuments: $item');
|
||||||
|
final String description = item['description'];
|
||||||
|
final String type = item['type'];
|
||||||
|
final String category = item['category']['description'];
|
||||||
|
final String color = item['category']['color'];
|
||||||
|
final String person = item['person'] ?? '';
|
||||||
|
final String property = item['property'] ?? '';
|
||||||
|
final String createdAt = item['createdAt'];
|
||||||
|
final String updatedAt = item['updatedAt'];
|
||||||
|
final int categoryId = item['category']['id'];
|
||||||
|
final int documentId = item['id'];
|
||||||
|
|
||||||
|
final doc = Document(
|
||||||
|
id: documentId,
|
||||||
|
description: description,
|
||||||
|
type: type,
|
||||||
|
category: Category(
|
||||||
|
id: categoryId,
|
||||||
|
color: color.toColor(),
|
||||||
|
title: category,
|
||||||
|
),
|
||||||
|
person: person,
|
||||||
|
property: property,
|
||||||
|
createdAt: createdAt,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
);
|
||||||
|
|
||||||
|
docs.add(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true, docs);
|
||||||
|
// listViewKey.currentState!.count = newItems.jsonBody['value']['count'] ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [generateCategories]
|
||||||
|
Future<List<Category?>> generateCategories(List<Document?> documents) async {
|
||||||
|
final List<Category?> error = [null];
|
||||||
|
if (documents == []) return error;
|
||||||
|
|
||||||
|
final GetCategories getCategories = FreAccessWSGlobal.getCategories;
|
||||||
|
final ApiCallResponse newItems = await getCategories.call();
|
||||||
|
|
||||||
|
if (newItems.jsonBody['error'] == true) return error;
|
||||||
|
if (newItems.jsonBody == null) return error;
|
||||||
|
final list = newItems.jsonBody['value'] as List<dynamic>;
|
||||||
|
late final List<Category> cats = [];
|
||||||
|
for (var item in list) {
|
||||||
|
final String color = item['color'];
|
||||||
|
final String title = item['description'];
|
||||||
|
final int id = item['id'];
|
||||||
|
|
||||||
|
final cat = Category(
|
||||||
|
id: id,
|
||||||
|
color: color.toColor(),
|
||||||
|
title: title,
|
||||||
|
);
|
||||||
|
cats.add(cat);
|
||||||
|
}
|
||||||
|
log('cats: $cats');
|
||||||
|
return cats;
|
||||||
|
}
|
||||||
|
|
||||||
|
void filterByCategory(Category query) {
|
||||||
|
final state = searchKey.currentState;
|
||||||
|
|
||||||
|
if (state != null) {
|
||||||
|
log('filterByCategories: ');
|
||||||
|
|
||||||
|
state.safeSetState(() {
|
||||||
|
if (isCategorySelected) {
|
||||||
|
state.filter(null);
|
||||||
|
isCategorySelected = false;
|
||||||
|
} else {
|
||||||
|
state.filter(query);
|
||||||
|
isCategorySelected = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onFetchError(Object e, StackTrace s) {
|
||||||
|
DialogUtil.errorDefault(docKey.currentContext!);
|
||||||
|
LogUtil.requestAPIFailed(
|
||||||
|
"proccessRequest.php", "", "Consulta de Veículo", e, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,69 +1,54 @@
|
||||||
part of 'index.dart';
|
part of 'index.dart';
|
||||||
|
|
||||||
List<Document> generateDocuments(int count) {
|
typedef DocumentKey = GlobalKey<FREDocumentPageState>;
|
||||||
String str() => randomString(8, 8, true, true, true);
|
|
||||||
Color color() => randomColor();
|
|
||||||
|
|
||||||
return List<Document>.generate(
|
class DocumentPage extends StatefulPage {
|
||||||
count,
|
const DocumentPage({super.key});
|
||||||
(index) => Document(
|
|
||||||
title: 'Lorem Ipsum et Cetera $index',
|
|
||||||
category: Category(color: color(), title: str()),
|
|
||||||
to: str(),
|
|
||||||
from: str(),
|
|
||||||
createdAt: '00/00/0000',
|
|
||||||
updatedAt: '00/00/0000',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Category> generateCategories(List<Document> documents) {
|
|
||||||
final Map<String, Category> categoryMap = {};
|
|
||||||
|
|
||||||
for (var document in documents) {
|
|
||||||
final category = document.category;
|
|
||||||
if (!categoryMap.containsKey(category.title)) {
|
|
||||||
categoryMap[category.title] = category;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return categoryMap.values.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
class FREDocumentPage extends StatefulPage {
|
|
||||||
const FREDocumentPage({super.key});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<FREDocumentPage> createState() => _FREDocumentPageState();
|
State<DocumentPage> createState() => FREDocumentPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FREDocumentPageState extends PageState<FREDocumentPage> {
|
class FREDocumentPageState<T extends DocumentPage>
|
||||||
|
extends PageState<DocumentPage> {
|
||||||
|
DocumentPageModel model = DocumentPageModel();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final String title = FFLocalizations.of(context)
|
final String title = FFLocalizations.of(context).getVariableText(
|
||||||
.getVariableText(enText: 'Documents', ptText: 'Documentos');
|
enText: 'Documents',
|
||||||
|
ptText: 'Documentos',
|
||||||
|
);
|
||||||
|
final theme = FlutterFlowTheme.of(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
backgroundColor: theme.primaryBackground,
|
||||||
appBar: buildAppBar(title, context),
|
appBar: buildAppBar(title, context),
|
||||||
body: buildBody(context),
|
body: buildBody(context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late List<Document> documents;
|
|
||||||
late List<Category> categories;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
documents = generateDocuments(20);
|
|
||||||
categories = generateCategories(documents);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildBody(BuildContext context) {
|
Widget buildBody(BuildContext context) {
|
||||||
return DocumentManagerScreen(
|
return FutureBuilder<void>(
|
||||||
documents: documents,
|
future: initAsync(),
|
||||||
categories: categories,
|
builder: (context, snapshot) {
|
||||||
|
return DocumentManagerScreen(model: model);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
// return DocumentViewScreen(document: documents.first);
|
// return DocumentViewScreen(document: documents.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> initAsync() async {
|
||||||
|
final documents = await model.generateDocuments(model.page, model.query);
|
||||||
|
final categories = await model.generateCategories(model.documents);
|
||||||
|
model.documents = documents.$2;
|
||||||
|
model.categories = categories;
|
||||||
|
log('-> generateDocuments: $documents');
|
||||||
|
log('-> generateCategories: $categories');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,33 +13,45 @@ class DocumentViewScreen extends StatefulScreen {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DocumentViewScreenState extends State<DocumentViewScreen> {
|
class _DocumentViewScreenState extends State<DocumentViewScreen> {
|
||||||
final PDFViewerState _viewerKey = PDFViewerState();
|
final PDFViewerKey _viewerKey = PDFViewerKey();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final Uri url = Uri.parse(
|
||||||
|
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf');
|
||||||
|
|
||||||
|
void onPressed() async {
|
||||||
|
final response = await http.get(url);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final XFile xfile = XFile.fromData(response.bodyBytes,
|
||||||
|
name:
|
||||||
|
'${widget.document.description}_${widget.document.category.title}.pdf',
|
||||||
|
mimeType: 'application/pdf');
|
||||||
|
await Share.shareXFiles([xfile], text: 'Confira este PDF!');
|
||||||
|
} else {
|
||||||
|
print('Erro ao baixar o arquivo: ${response.statusCode}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
child: FREViewerPDF(
|
child: FREViewerPDF(
|
||||||
key: _viewerKey,
|
search: _viewerKey,
|
||||||
url:
|
src: url.toString(),
|
||||||
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 10,
|
bottom: 10,
|
||||||
right: 10,
|
right: 10,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: Icon(Icons.share, color: Colors.black),
|
icon: Icon(
|
||||||
|
Icons.share,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
onPressed: () {
|
),
|
||||||
_viewerKey.currentState?.openBookmarkView();
|
color: Colors.black,
|
||||||
// Share.share(FFLocalizations.of(context).getVariableText(
|
onPressed: onPressed,
|
||||||
// ptText: '',
|
|
||||||
// enText: '',
|
|
||||||
// ));
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:hub/features/backend/index.dart';
|
||||||
import 'package:hub/flutter_flow/index.dart';
|
import 'package:hub/flutter_flow/index.dart';
|
||||||
|
import 'package:hub/shared/extensions/index.dart';
|
||||||
|
import 'package:hub/shared/mixins/pegeable_mixin.dart';
|
||||||
import 'package:hub/shared/utils/index.dart';
|
import 'package:hub/shared/utils/index.dart';
|
||||||
import 'package:hub/shared/widgets/widgets.dart';
|
import 'package:hub/shared/widgets/widgets.dart';
|
||||||
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
|
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
part 'document_manager_screen.dart';
|
part 'document_manager_screen.dart';
|
||||||
part 'document_page_widget.dart';
|
part 'document_page_widget.dart';
|
||||||
|
|
|
@ -158,7 +158,7 @@ class LightModeTheme extends FlutterFlowTheme {
|
||||||
|
|
||||||
late Color primary = const Color(0xFF1AAB5F);
|
late Color primary = const Color(0xFF1AAB5F);
|
||||||
late Color secondary = const Color(0xFFB59E9E);
|
late Color secondary = const Color(0xFFB59E9E);
|
||||||
late Color tertiary = const Color(0xFF984BB6);
|
late Color tertiary = const Color(0xFF000000);
|
||||||
late Color alternate = const Color(0xFFF2F2F2);
|
late Color alternate = const Color(0xFFF2F2F2);
|
||||||
late Color alternate2 = const Color(0xFF232323);
|
late Color alternate2 = const Color(0xFF232323);
|
||||||
late Color primaryText = const Color(0xFF000000);
|
late Color primaryText = const Color(0xFF000000);
|
||||||
|
@ -192,7 +192,7 @@ class DarkModeTheme extends FlutterFlowTheme {
|
||||||
|
|
||||||
late Color primary = const Color(0xFF1AAB5F);
|
late Color primary = const Color(0xFF1AAB5F);
|
||||||
late Color secondary = const Color(0xFF18AA99);
|
late Color secondary = const Color(0xFF18AA99);
|
||||||
late Color tertiary = const Color(0xFF984BB6);
|
late Color tertiary = const Color(0xFF000000);
|
||||||
late Color alternate = const Color(0xFF232323);
|
late Color alternate = const Color(0xFF232323);
|
||||||
late Color alternate2 = const Color(0xFF171717);
|
late Color alternate2 = const Color(0xFF171717);
|
||||||
late Color primaryText = const Color(0xFFFFFFFF);
|
late Color primaryText = const Color(0xFFFFFFFF);
|
||||||
|
|
|
@ -303,7 +303,19 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
||||||
name: 'documentPage',
|
name: 'documentPage',
|
||||||
path: '/documentPage',
|
path: '/documentPage',
|
||||||
builder: (context, params) {
|
builder: (context, params) {
|
||||||
return FREDocumentPage();
|
return DocumentPage();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FFRoute(
|
||||||
|
name: 'documentViewerScreen',
|
||||||
|
path: '/documentViewerScreen',
|
||||||
|
builder: (context, params) {
|
||||||
|
final Document document =
|
||||||
|
params.getParam('document', ParamType.Function);
|
||||||
|
return DocumentViewScreen(
|
||||||
|
key: UniqueKey(),
|
||||||
|
document: document,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
// FFRoute(name: 'settingsPage', path: '/settingsPage', builder: (context, params) => params.isEmpty ? const NavBarPage(initialPage: 'settingsPage') : const SettingsPageWidget())
|
// FFRoute(name: 'settingsPage', path: '/settingsPage', builder: (context, params) => params.isEmpty ? const NavBarPage(initialPage: 'settingsPage') : const SettingsPageWidget())
|
||||||
|
|
|
@ -74,38 +74,6 @@ class _AppState extends State<App> {
|
||||||
late GoRouter _router;
|
late GoRouter _router;
|
||||||
bool displaySplashImage = true;
|
bool displaySplashImage = true;
|
||||||
|
|
||||||
final ThemeData _darkTheme = ThemeData(
|
|
||||||
brightness: Brightness.dark,
|
|
||||||
scrollbarTheme: ScrollbarThemeData(
|
|
||||||
thumbVisibility: WidgetStateProperty.all(false),
|
|
||||||
interactive: false,
|
|
||||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
|
||||||
if (states.contains(WidgetState.dragged)) {
|
|
||||||
return const Color(0xff1aab5f);
|
|
||||||
}
|
|
||||||
if (states.contains(WidgetState.hovered)) {
|
|
||||||
return const Color(0xff1aab5f);
|
|
||||||
}
|
|
||||||
return const Color(0xff1aab5f);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final ThemeData _theme = ThemeData(
|
|
||||||
brightness: Brightness.light,
|
|
||||||
scrollbarTheme: ScrollbarThemeData(
|
|
||||||
thumbVisibility: WidgetStateProperty.all(false),
|
|
||||||
interactive: false,
|
|
||||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
|
||||||
if (states.contains(WidgetState.dragged)) {
|
|
||||||
return const Color(0xff1aab5f);
|
|
||||||
}
|
|
||||||
if (states.contains(WidgetState.hovered)) {
|
|
||||||
return const Color(0xff1aab5f);
|
|
||||||
}
|
|
||||||
return const Color(0xff1aab5f);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates =
|
final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates =
|
||||||
const [
|
const [
|
||||||
FFLocalizationsDelegate(),
|
FFLocalizationsDelegate(),
|
||||||
|
@ -201,6 +169,39 @@ class _AppState extends State<App> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final themeSchema = FlutterFlowTheme.of(context);
|
||||||
|
|
||||||
|
final ThemeData darkTheme = ThemeData(
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
scrollbarTheme: ScrollbarThemeData(
|
||||||
|
thumbVisibility: WidgetStateProperty.all(false),
|
||||||
|
interactive: false,
|
||||||
|
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||||
|
if (states.contains(WidgetState.dragged)) return themeSchema.primary;
|
||||||
|
if (states.contains(WidgetState.hovered)) return themeSchema.primary;
|
||||||
|
return themeSchema.primary;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final ThemeData lightTheme = ThemeData(
|
||||||
|
brightness: Brightness.light,
|
||||||
|
textSelectionTheme: TextSelectionThemeData(
|
||||||
|
cursorColor: themeSchema.primaryText, // Cor do cursor
|
||||||
|
selectionColor: themeSchema.accent2, // Cor da seleção de texto
|
||||||
|
selectionHandleColor:
|
||||||
|
themeSchema.primaryText, // Cor do manipulador de seleção
|
||||||
|
),
|
||||||
|
scrollbarTheme: ScrollbarThemeData(
|
||||||
|
thumbVisibility: WidgetStateProperty.all(false),
|
||||||
|
interactive: false,
|
||||||
|
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||||
|
if (states.contains(WidgetState.dragged)) return themeSchema.primary;
|
||||||
|
if (states.contains(WidgetState.hovered)) return themeSchema.primary;
|
||||||
|
return themeSchema.primary;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return MaterialApp.router(
|
return MaterialApp.router(
|
||||||
scrollBehavior: CustomScrollBehavior(),
|
scrollBehavior: CustomScrollBehavior(),
|
||||||
key: navigatorKey,
|
key: navigatorKey,
|
||||||
|
@ -209,8 +210,8 @@ class _AppState extends State<App> {
|
||||||
localizationsDelegates: localizationsDelegates,
|
localizationsDelegates: localizationsDelegates,
|
||||||
locale: _locale,
|
locale: _locale,
|
||||||
supportedLocales: supportedLocales,
|
supportedLocales: supportedLocales,
|
||||||
theme: _theme,
|
theme: lightTheme,
|
||||||
darkTheme: _darkTheme,
|
darkTheme: darkTheme,
|
||||||
themeMode: _themeMode,
|
themeMode: _themeMode,
|
||||||
routerConfig: _router,
|
routerConfig: _router,
|
||||||
);
|
);
|
||||||
|
|
|
@ -163,8 +163,10 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
||||||
|
|
||||||
// updateImage!();
|
// updateImage!();
|
||||||
(() async {
|
(() async {
|
||||||
Response response = await get(Uri.parse(
|
final String url =
|
||||||
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId'));
|
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId';
|
||||||
|
print('img: $url');
|
||||||
|
Response response = await get(Uri.parse(url));
|
||||||
String base64 = base64Encode(response.bodyBytes);
|
String base64 = base64Encode(response.bodyBytes);
|
||||||
uploadedTempFile = await ImageUtils.convertToUploadFile(base64);
|
uploadedTempFile = await ImageUtils.convertToUploadFile(base64);
|
||||||
updateImage?.call();
|
updateImage?.call();
|
||||||
|
@ -280,6 +282,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
||||||
img = "base64;jpeg,$img";
|
img = "base64;jpeg,$img";
|
||||||
final url =
|
final url =
|
||||||
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId';
|
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId';
|
||||||
|
print('img: $url');
|
||||||
final response = await FreAccessWSGlobal.updatePet.call(
|
final response = await FreAccessWSGlobal.updatePet.call(
|
||||||
petID: petId,
|
petID: petId,
|
||||||
image: img,
|
image: img,
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
extension StringNullableExtensions on String? {
|
extension StringNullableExtensions on String? {
|
||||||
bool toBoolean() {
|
bool toBoolean() {
|
||||||
if (this == null) return false;
|
if (this == null) return false;
|
||||||
return this!.toLowerCase() == 'true';
|
return this!.toLowerCase() == 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNullOrEmpty() {
|
bool get isNullOrEmpty {
|
||||||
if (this == null) return true;
|
if (this == null) return true;
|
||||||
if (this == '') return true;
|
if (this == '') return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -18,3 +20,16 @@ extension StringExtensions on String {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StringExtension on String? {}
|
extension StringExtension on String? {}
|
||||||
|
|
||||||
|
extension HexColor on String {
|
||||||
|
Color toColor() {
|
||||||
|
final hexCode = replaceAll('#', '');
|
||||||
|
final buffer = StringBuffer();
|
||||||
|
if (hexCode.length == 6) {
|
||||||
|
buffer
|
||||||
|
.write('ff'); // Adiciona opacidade total caso não esteja especificada
|
||||||
|
}
|
||||||
|
buffer.write(hexCode);
|
||||||
|
return Color(int.parse(buffer.toString(), radix: 16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
|
export 'pegeable_mixin.dart';
|
||||||
export 'status_mixin.dart';
|
export 'status_mixin.dart';
|
||||||
export 'switcher_mixin.dart';
|
export 'switcher_mixin.dart';
|
||||||
|
|
|
@ -7,30 +7,33 @@ extension PagedListViewExtension<PageKeyType, ItemType>
|
||||||
on PagedSliverList<PageKeyType, ItemType> {}
|
on PagedSliverList<PageKeyType, ItemType> {}
|
||||||
|
|
||||||
mixin Pageable<T extends StatefulWidget> on State<T> {
|
mixin Pageable<T extends StatefulWidget> on State<T> {
|
||||||
Expanded buildPaginatedListView<X, Y>(
|
Expanded buildPaginatedListView<PageKeyType, ItemType>(
|
||||||
String noDataFound,
|
String noDataFound,
|
||||||
PagingController<X, Y> pg,
|
PagingController<PageKeyType, ItemType> pg,
|
||||||
Widget Function(BuildContext, Y, int) itemBuilder) {
|
Widget Function(BuildContext) headerBuilder,
|
||||||
|
Widget Function(BuildContext, ItemType, int) bodyBuilder) {
|
||||||
final theme = FlutterFlowTheme.of(context);
|
final theme = FlutterFlowTheme.of(context);
|
||||||
|
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
backgroundColor: theme.primaryBackground,
|
backgroundColor: theme.primaryBackground,
|
||||||
color: theme.primary,
|
color: theme.primary,
|
||||||
onRefresh: () async => pg.refresh(),
|
onRefresh: () async => pg.refresh(),
|
||||||
child: PagedListView<X, Y>(
|
child: PagedListView<PageKeyType, ItemType>(
|
||||||
pagingController: pg,
|
pagingController: pg,
|
||||||
builderDelegate: PagedChildBuilderDelegate<Y>(
|
builderDelegate: PagedChildBuilderDelegate<ItemType>(
|
||||||
animateTransitions: true,
|
animateTransitions: true,
|
||||||
itemBuilder: (context, item, index) =>
|
itemBuilder: (context, item, int index) {
|
||||||
itemBuilder(context, item, index),
|
return Column(children: [
|
||||||
// noMoreItemsIndicatorBuilder: ,
|
if (index == 0) headerBuilder(context),
|
||||||
|
bodyBuilder(context, item, index),
|
||||||
|
]);
|
||||||
|
},
|
||||||
newPageProgressIndicatorBuilder: (context) =>
|
newPageProgressIndicatorBuilder: (context) =>
|
||||||
buildLoadingIndicator(context),
|
buildLoadingIndicator(context),
|
||||||
firstPageProgressIndicatorBuilder: (context) =>
|
firstPageProgressIndicatorBuilder: (context) =>
|
||||||
buildLoadingIndicator(context),
|
buildLoadingIndicator(context),
|
||||||
noItemsFoundIndicatorBuilder: (context) =>
|
noItemsFoundIndicatorBuilder: (context) =>
|
||||||
buildNoDataFound(context, noDataFound),
|
buildNoDataFound(context, noDataFound, headerBuilder),
|
||||||
firstPageErrorIndicatorBuilder: (context) => const Placeholder(),
|
firstPageErrorIndicatorBuilder: (context) => const Placeholder(),
|
||||||
newPageErrorIndicatorBuilder: (context) => const Placeholder(),
|
newPageErrorIndicatorBuilder: (context) => const Placeholder(),
|
||||||
),
|
),
|
||||||
|
@ -89,10 +92,17 @@ mixin Pageable<T extends StatefulWidget> on State<T> {
|
||||||
showSnackbar(context, message, true);
|
showSnackbar(context, message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildNoDataFound(BuildContext context, String title) {
|
Widget buildNoDataFound(
|
||||||
|
BuildContext context,
|
||||||
|
String title,
|
||||||
|
Widget Function(BuildContext) headerBuilder,
|
||||||
|
) {
|
||||||
final headerFontSize = LimitedFontSizeUtil.getHeaderFontSize(context);
|
final headerFontSize = LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||||
// final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
// final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||||
return Expanded(
|
return Column(
|
||||||
|
children: [
|
||||||
|
headerBuilder(context),
|
||||||
|
Expanded(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
title,
|
||||||
|
@ -102,10 +112,13 @@ mixin Pageable<T extends StatefulWidget> on State<T> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildLoadingIndicator(BuildContext context) {
|
Widget buildLoadingIndicator(BuildContext context) {
|
||||||
|
print('Loading');
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 15),
|
padding: const EdgeInsets.symmetric(vertical: 15),
|
||||||
child: Center(
|
child: Center(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class ValidatorUtil {
|
class ValidatorUtil {
|
||||||
|
@ -34,10 +36,16 @@ class ValidatorUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
static String toLocalDateTime(String format, String value) {
|
static String toLocalDateTime(String format, String value) {
|
||||||
|
try {
|
||||||
|
if (value.isEmpty) return '';
|
||||||
DateFormat dateFormat = DateFormat(format);
|
DateFormat dateFormat = DateFormat(format);
|
||||||
DateTime dateTime = dateFormat.parse(value);
|
DateTime? dateTime = dateFormat.tryParse(value);
|
||||||
|
if (dateTime == null) return '';
|
||||||
return DateFormat('dd/MM/yyyy HH:mm:ss').format(dateTime);
|
return dateFormat.format(dateTime);
|
||||||
|
} catch (e, s) {
|
||||||
|
log(e.toString(), stackTrace: s);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static String formatDateTimePicker(String dateTime) {
|
static String formatDateTimePicker(String dateTime) {
|
||||||
|
|
|
@ -1,46 +1,28 @@
|
||||||
part of '../widgets.dart';
|
part of '../widgets.dart';
|
||||||
|
|
||||||
class CategoryCarousel extends StatelessWidget {
|
class CategoryCarousel<T> extends StatelessWidget {
|
||||||
final List<Category> categories;
|
final List<T?> categories;
|
||||||
final void Function(Category) onSelect;
|
final void Function(T) filter;
|
||||||
final void Function(Category) onUnselect;
|
|
||||||
|
|
||||||
const CategoryCarousel({
|
const CategoryCarousel({
|
||||||
super.key,
|
super.key,
|
||||||
required this.categories,
|
required this.categories,
|
||||||
required this.onSelect,
|
required this.filter,
|
||||||
required this.onUnselect,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final backgroundTheme = FlutterFlowTheme.of(context).primaryBackground;
|
final backgroundTheme = FlutterFlowTheme.of(context).primaryBackground;
|
||||||
|
|
||||||
bool isSelected = false;
|
return SizedBox(
|
||||||
Category? current = null;
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 120,
|
height: 120,
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: backgroundTheme,
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
child: CarouselView(
|
child: CarouselView(
|
||||||
itemExtent: 100,
|
itemExtent: 100,
|
||||||
onTap: (index) {
|
onTap: (index) => filter(categories[index]!),
|
||||||
if (isSelected && current == categories[index]) {
|
|
||||||
onUnselect(categories[index]);
|
|
||||||
isSelected = false;
|
|
||||||
current = null;
|
|
||||||
} else {
|
|
||||||
onSelect(categories[index]);
|
|
||||||
isSelected = true;
|
|
||||||
current = categories[index];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
children: categories.map((category) {
|
children: categories.map((category) {
|
||||||
return GestureDetector(
|
category as Category?;
|
||||||
onTap: () {},
|
return ColoredBox(
|
||||||
|
color: backgroundTheme,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -48,7 +30,7 @@ class CategoryCarousel extends StatelessWidget {
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: category.color,
|
color: category!.color,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
part of '../widgets.dart';
|
part of '../widgets.dart';
|
||||||
|
|
||||||
|
typedef SearchKey = GlobalKey<RemoteSearchViewState>;
|
||||||
|
|
||||||
|
typedef Query<X extends DocumentEntity> = X?;
|
||||||
|
|
||||||
/// -----------------------------------------------
|
/// -----------------------------------------------
|
||||||
/// [SearchView]
|
/// [SearchView]
|
||||||
|
/// -----------------------------------------------
|
||||||
|
|
||||||
class SearchView<T> extends StatefulComponent {
|
class SearchView<T> extends StatefulComponent {
|
||||||
const SearchView({super.key});
|
const SearchView({super.key});
|
||||||
|
@ -17,6 +22,10 @@ class _SearchViewState<T> extends State<SearchView> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// -----------------------------------------------
|
||||||
|
/// [LocalSearchView]
|
||||||
|
/// -----------------------------------------------
|
||||||
|
|
||||||
class LocalSearchView<T> extends SearchView<T> {
|
class LocalSearchView<T> extends SearchView<T> {
|
||||||
final List<T> list;
|
final List<T> list;
|
||||||
final Widget Function(T) itemBuilder;
|
final Widget Function(T) itemBuilder;
|
||||||
|
@ -78,108 +87,103 @@ class LocalSearchViewState<T> extends State<LocalSearchView<T>> {
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(30.0),
|
padding: const EdgeInsets.all(30.0),
|
||||||
child: TextField(
|
child: TextFormField(
|
||||||
onChanged: filter,
|
|
||||||
controller: editingController,
|
controller: editingController,
|
||||||
|
onChanged: filter,
|
||||||
cursorColor: Colors.black,
|
cursorColor: Colors.black,
|
||||||
|
cursorWidth: 2.0,
|
||||||
|
cursorRadius: Radius.circular(2.0),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 16.0,
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.search,
|
||||||
|
autocorrect: true,
|
||||||
|
textCapitalization: TextCapitalization.sentences,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
prefixIcon: Icon(Icons.search),
|
prefixIcon: Icon(Icons.search, color: Colors.black),
|
||||||
focusColor: Colors.black,
|
labelText: 'Pesquisar',
|
||||||
hoverColor: Colors.black,
|
labelStyle: TextStyle(
|
||||||
fillColor: Colors.black,
|
color: Colors.black,
|
||||||
iconColor: Colors.black,
|
fontSize: 16.0,
|
||||||
|
),
|
||||||
|
hintText: 'Digite sua pesquisa',
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
color: Colors.grey,
|
||||||
|
fontSize: 14.0,
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
contentPadding:
|
contentPadding:
|
||||||
EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
|
EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
|
||||||
border: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
borderSide:
|
borderSide: BorderSide(color: Colors.black),
|
||||||
BorderSide(color: Colors.black), // Set border color here
|
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(color: Colors.blue),
|
||||||
color: Colors.black), // Set focused border color here
|
),
|
||||||
),
|
errorBorder: OutlineInputBorder(
|
||||||
),
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
|
borderSide: BorderSide(color: Colors.red),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
|
borderSide: BorderSide(color: Colors.red, width: 2.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
)),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RemoteSearchListView<T> extends SearchView<T> {
|
/// -----------------------------------------------
|
||||||
final List<T> list;
|
/// [RemoteSearchView]
|
||||||
final String title;
|
/// -----------------------------------------------
|
||||||
final Widget Function(T) itemBuilder;
|
|
||||||
// final Future<List<T>> Function(String) fetchItems;
|
|
||||||
final bool Function(T, String) filter;
|
|
||||||
final Widget header;
|
|
||||||
final List<T> Function(String)? onSearch;
|
|
||||||
|
|
||||||
RemoteSearchListView({
|
class RemoteSearchView<T> extends SearchView<T> {
|
||||||
|
final Widget Function(BuildContext, T, int) bodyBuilder;
|
||||||
|
Widget Function(BuildContext) headerBuilder;
|
||||||
|
final PagingController<int, T> pagingController;
|
||||||
|
final Future<(bool, List<T?>)> Function(int pageKey, Query query)
|
||||||
|
dataProvider;
|
||||||
|
|
||||||
|
final void Function(Object, StackTrace) onFetchError;
|
||||||
|
|
||||||
|
RemoteSearchView({
|
||||||
Key? key,
|
Key? key,
|
||||||
// required this.fetchItems,
|
// required this.fetchItems,
|
||||||
required this.title,
|
required this.bodyBuilder,
|
||||||
required this.list,
|
required this.headerBuilder,
|
||||||
required this.itemBuilder,
|
required this.pagingController,
|
||||||
required this.filter,
|
required this.dataProvider,
|
||||||
List<T> Function(String)? onSearch,
|
required this.onFetchError,
|
||||||
Widget? header,
|
}) : super(key: key);
|
||||||
}) : header = header ?? const SizedBox.shrink(),
|
|
||||||
onSearch = onSearch ??
|
|
||||||
((String query) =>
|
|
||||||
list.where((documents) => filter(documents, query)).toList()),
|
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_RemoteSearchViewState<T> createState() => _RemoteSearchViewState<T>();
|
RemoteSearchViewState<T> createState() => RemoteSearchViewState<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RemoteSearchViewState<T> extends State<RemoteSearchListView<T>>
|
class RemoteSearchViewState<T> extends State<RemoteSearchView<T>>
|
||||||
with Pageable {
|
with Pageable {
|
||||||
TextEditingController editingController = TextEditingController();
|
TextEditingController editingController = TextEditingController();
|
||||||
late List<T> filteredItems;
|
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
final apiCall = FreAccessWSGlobal.getDocuments;
|
Query query = Document.fromDesc('');
|
||||||
int count = 0;
|
|
||||||
final PagingController<int, dynamic> _pagingController =
|
|
||||||
PagingController<int, dynamic>(firstPageKey: 1);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
filteredItems = widget.list;
|
widget.pagingController.addPageRequestListener(
|
||||||
_pagingController.addPageRequestListener(
|
(page) => fetchPage(
|
||||||
(dynamic pageKey) => fetchPage(
|
dataProvider: () async => await widget.dataProvider(page, query),
|
||||||
dataProvider: () async {
|
onDataUnavailable: () => showNoMoreDataSnackBar(context),
|
||||||
final newItems = await apiCall.call(pageKey.toString());
|
onDataAvailable: (data) =>
|
||||||
if (newItems.jsonBody == null) return (false, null);
|
widget.pagingController.appendLastPage(data),
|
||||||
final List<dynamic> docs =
|
onFetchError: (e, s) => widget.onFetchError),
|
||||||
(newItems.jsonBody['value']['list'] as List<dynamic>?) ?? [];
|
|
||||||
_pagingController.nextPageKey = pageKey + 1;
|
|
||||||
|
|
||||||
safeSetState(() {
|
|
||||||
count = newItems.jsonBody['value']['count'] ?? 0;
|
|
||||||
});
|
|
||||||
return (docs.isNotEmpty, docs);
|
|
||||||
},
|
|
||||||
onDataUnavailable: () {
|
|
||||||
setState(() {});
|
|
||||||
showNoMoreDataSnackBar(context);
|
|
||||||
},
|
|
||||||
onDataAvailable: (vehicles) {
|
|
||||||
setState(() {});
|
|
||||||
_pagingController.appendLastPage(vehicles);
|
|
||||||
},
|
|
||||||
onFetchError: (e, s) {
|
|
||||||
DialogUtil.errorDefault(context);
|
|
||||||
LogUtil.requestAPIFailed(
|
|
||||||
"proccessRequest.php", "", "Consulta de Veículo", e, s);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
_pagingController.addStatusListener(_showError);
|
widget.pagingController.addStatusListener(_showError);
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
@ -200,57 +204,122 @@ class _RemoteSearchViewState<T> extends State<RemoteSearchListView<T>>
|
||||||
content: Text(message),
|
content: Text(message),
|
||||||
action: SnackBarAction(
|
action: SnackBarAction(
|
||||||
label: retry,
|
label: retry,
|
||||||
onPressed: () => _pagingController.retryLastFailedRequest(),
|
onPressed: () => widget.pagingController.retryLastFailedRequest(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void filterSearchResults(String query) async {
|
void filter(Query data) async {
|
||||||
setState(() {
|
if (data is Category) {
|
||||||
isLoading = true;
|
safeSetState(() => query = Category(
|
||||||
|
id: data.id,
|
||||||
|
color: data.color,
|
||||||
|
title: data.title,
|
||||||
|
));
|
||||||
|
widget.pagingController.refresh();
|
||||||
|
} else if (data is Document) {
|
||||||
|
log('filter: ${data.description}');
|
||||||
|
|
||||||
|
safeSetState(() => query = data);
|
||||||
|
widget.pagingController.refresh();
|
||||||
|
} else {
|
||||||
|
safeSetState(() {
|
||||||
|
query = Document.fromDesc('');
|
||||||
});
|
});
|
||||||
// final results = await widget.fetchItems(query);
|
widget.pagingController.refresh();
|
||||||
// setState(() {
|
}
|
||||||
// filteredItems = results;
|
|
||||||
// isLoading = false;
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final noDataFound = FFLocalizations.of(context).getVariableText(
|
final noDataFound = FFLocalizations.of(context).getVariableText(
|
||||||
ptText: "Nenhum veículo encontrado!",
|
ptText: "Nenhum item encontrado!",
|
||||||
enText: "No vehicle found",
|
enText: "No item found",
|
||||||
);
|
);
|
||||||
|
final theme = FlutterFlowTheme.of(context);
|
||||||
|
final locale = FFLocalizations.of(context);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
buildPaginatedListView<int, T>(
|
||||||
|
noDataFound,
|
||||||
|
widget.pagingController,
|
||||||
|
widget.headerBuilder,
|
||||||
|
widget.bodyBuilder,
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: TextField(
|
child: TextFormField(
|
||||||
onChanged: (value) => filterSearchResults(value),
|
|
||||||
controller: editingController,
|
controller: editingController,
|
||||||
|
onChanged: (value) => EasyDebounce.debounce(
|
||||||
|
'_model.keyTextFieldTextController',
|
||||||
|
const Duration(milliseconds: 500),
|
||||||
|
() => filter(Document.fromDesc(value)),
|
||||||
|
),
|
||||||
|
cursorColor: theme.primaryText,
|
||||||
|
showCursor: false,
|
||||||
|
cursorWidth: 2.0,
|
||||||
|
cursorRadius: Radius.circular(100),
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.primaryText,
|
||||||
|
fontSize: 16.0,
|
||||||
|
decorationColor: Colors.amber,
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.search,
|
||||||
|
autocorrect: true,
|
||||||
|
textCapitalization: TextCapitalization.sentences,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: "Search",
|
prefixIcon: Icon(Icons.search, color: theme.primary),
|
||||||
hintText: "Search",
|
labelText: locale.getVariableText(
|
||||||
prefixIcon: Icon(Icons.search),
|
ptText: 'Pesquisar',
|
||||||
border: OutlineInputBorder(
|
enText: 'Search',
|
||||||
borderRadius: BorderRadius.all(Radius.circular(25.0)),
|
),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.primaryText,
|
||||||
|
fontSize: 16.0,
|
||||||
|
),
|
||||||
|
hintText: locale.getVariableText(
|
||||||
|
ptText: 'Digite sua pesquisa',
|
||||||
|
enText: 'Enter your search',
|
||||||
|
),
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
color: theme.accent2,
|
||||||
|
fontSize: 14.0,
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.transparent,
|
||||||
|
helperStyle: TextStyle(
|
||||||
|
color: theme.primaryText,
|
||||||
|
decorationColor: theme.primaryText,
|
||||||
|
),
|
||||||
|
focusColor: theme.primaryText,
|
||||||
|
contentPadding:
|
||||||
|
EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
|
||||||
|
enabledBorder: UnderlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
|
borderSide: BorderSide(color: theme.primaryText),
|
||||||
|
),
|
||||||
|
focusedBorder: UnderlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
|
borderSide: BorderSide(color: theme.primaryText),
|
||||||
|
),
|
||||||
|
errorBorder: UnderlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
|
borderSide: BorderSide(color: theme.primaryText),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: UnderlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
|
borderSide: BorderSide(color: theme.primaryText, width: 2.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
widget.header,
|
|
||||||
buildPaginatedListView<int, dynamic>(
|
|
||||||
noDataFound,
|
|
||||||
_pagingController,
|
|
||||||
(BuildContext context, dynamic item, int index) =>
|
|
||||||
widget.itemBuilder(item),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
part of '../widgets.dart';
|
part of '../widgets.dart';
|
||||||
|
|
||||||
typedef PDFViewerState = GlobalKey<SfPdfViewerState>;
|
typedef PDFViewerKey = GlobalKey<SfPdfViewerState>;
|
||||||
|
|
||||||
abstract class Viewer extends StatelessComponent {
|
abstract interface class Viewer extends StatelessComponent {
|
||||||
const Viewer({super.key, required this.src});
|
const Viewer({
|
||||||
|
super.key,
|
||||||
|
required this.src,
|
||||||
|
});
|
||||||
final String src;
|
final String src;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -14,13 +17,24 @@ abstract class Viewer extends StatelessComponent {
|
||||||
Widget buildViewer(BuildContext context);
|
Widget buildViewer(BuildContext context);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FREViewerPDF extends Viewer {
|
class FREViewerPDF extends StatelessComponent {
|
||||||
const FREViewerPDF({required Key key, required this.url})
|
final String src;
|
||||||
: super(key: key as PDFViewerState, src: url);
|
final PDFViewerKey search;
|
||||||
final String url;
|
|
||||||
|
const FREViewerPDF({
|
||||||
|
required this.search,
|
||||||
|
required this.src,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return buildViewer(context);
|
||||||
|
}
|
||||||
|
|
||||||
Widget buildViewer(BuildContext context) {
|
Widget buildViewer(BuildContext context) {
|
||||||
return SfPdfViewer.network(src, key: key as PDFViewerState);
|
return SfPdfViewer.network(
|
||||||
|
src,
|
||||||
|
key: search,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:auto_size_text/auto_size_text.dart';
|
import 'package:auto_size_text/auto_size_text.dart';
|
||||||
|
import 'package:easy_debounce/easy_debounce.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:hub/features/backend/api_requests/api_calls.dart';
|
|
||||||
import 'package:hub/features/documents/index.dart';
|
import 'package:hub/features/documents/index.dart';
|
||||||
import 'package:hub/flutter_flow/index.dart';
|
import 'package:hub/flutter_flow/index.dart';
|
||||||
import 'package:hub/shared/mixins/pegeable_mixin.dart';
|
import 'package:hub/shared/mixins/pegeable_mixin.dart';
|
||||||
import 'package:hub/shared/utils/index.dart';
|
|
||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
|
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ dependencies:
|
||||||
flutter_animate: ^4.5.2
|
flutter_animate: ^4.5.2
|
||||||
# flutter_cache_manager: ^3.4.1
|
# flutter_cache_manager: ^3.4.1
|
||||||
# flutter_plugin_android_lifecycle: ^2.0.23
|
# flutter_plugin_android_lifecycle: ^2.0.23
|
||||||
share_plus: ^10.0.0
|
share_plus: ^10.1.4
|
||||||
# connectivity_plus: ^6.0.5
|
# connectivity_plus: ^6.0.5
|
||||||
flutter_secure_storage: ^10.0.0-beta.2
|
flutter_secure_storage: ^10.0.0-beta.2
|
||||||
flutter_secure_storage_linux: ^2.0.0
|
flutter_secure_storage_linux: ^2.0.0
|
||||||
|
|
Loading…
Reference in New Issue