Merge branch 'main' into fix/fd-787
This commit is contained in:
commit
6b9fad6591
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -348,7 +348,6 @@ Future<bool> checkLocals({
|
||||||
|
|
||||||
Future<void> showShare(payload) async {
|
Future<void> showShare(payload) async {
|
||||||
for (var i = 0; i < payload['convites'].length; i++) {
|
for (var i = 0; i < payload['convites'].length; i++) {
|
||||||
log('ADD');
|
|
||||||
await Share.share('''
|
await Share.share('''
|
||||||
Olá, \*${payload['convites'][i]['VTE_NOME']}\*! Você foi convidado para \*${AppState().local}\*.
|
Olá, \*${payload['convites'][i]['VTE_NOME']}\*! Você foi convidado para \*${AppState().local}\*.
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,9 @@ class AppState extends ChangeNotifier {
|
||||||
await _safeInitAsync(() async {
|
await _safeInitAsync(() async {
|
||||||
_whatsapp = await secureStorage.getBool('whatsapp') ?? _whatsapp;
|
_whatsapp = await secureStorage.getBool('whatsapp') ?? _whatsapp;
|
||||||
});
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_pets = await secureStorage.getBool('pets') ?? _pets;
|
||||||
|
});
|
||||||
await _safeInitAsync(() async {
|
await _safeInitAsync(() async {
|
||||||
_haveLocal = await secureStorage.getBool('ff_have_local') ?? _haveLocal;
|
_haveLocal = await secureStorage.getBool('ff_have_local') ?? _haveLocal;
|
||||||
});
|
});
|
||||||
|
@ -188,6 +191,17 @@ class AppState extends ChangeNotifier {
|
||||||
secureStorage.delete(key: 'ff_request_os_notification');
|
secureStorage.delete(key: 'ff_request_os_notification');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _pets = false;
|
||||||
|
bool get pets => _pets;
|
||||||
|
set pets(bool value) {
|
||||||
|
_pets = value;
|
||||||
|
secureStorage.setBool('pets', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deletePets() {
|
||||||
|
secureStorage.delete(key: 'pets');
|
||||||
|
}
|
||||||
|
|
||||||
bool _whatsapp = false;
|
bool _whatsapp = false;
|
||||||
bool get whatsapp => _whatsapp;
|
bool get whatsapp => _whatsapp;
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,223 @@ class PhpGroup {
|
||||||
static DeleteAccount deleteAccount = DeleteAccount();
|
static DeleteAccount deleteAccount = DeleteAccount();
|
||||||
static CancelaVisita cancelaVisita = CancelaVisita();
|
static CancelaVisita cancelaVisita = CancelaVisita();
|
||||||
static BuscaEnconcomendas buscaEnconcomendas = BuscaEnconcomendas();
|
static BuscaEnconcomendas buscaEnconcomendas = BuscaEnconcomendas();
|
||||||
|
static RegisterPet registerPet = RegisterPet();
|
||||||
|
static DeletePet deletePet = DeletePet();
|
||||||
|
static UpdatePet updatePet = UpdatePet();
|
||||||
|
static GetPets getPets = GetPets();
|
||||||
|
static GetPetPhoto getPetPhoto = GetPetPhoto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DeletePet {
|
||||||
|
Future<ApiCallResponse> call({
|
||||||
|
String? devUUID = '',
|
||||||
|
String? userUUID = '',
|
||||||
|
String? cliID = '',
|
||||||
|
String? atividade = 'excluirPet',
|
||||||
|
int? petID = 0,
|
||||||
|
}) async {
|
||||||
|
final baseUrl = PhpGroup.getBaseUrl();
|
||||||
|
|
||||||
|
return ApiManager.instance.makeApiCall(
|
||||||
|
callName: 'deletePet',
|
||||||
|
apiUrl: '$baseUrl/processRequest.php',
|
||||||
|
callType: ApiCallType.POST,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
'devUUID': devUUID,
|
||||||
|
'userUUID': userUUID,
|
||||||
|
'cliID': cliID,
|
||||||
|
'atividade': atividade,
|
||||||
|
'petId': petID,
|
||||||
|
},
|
||||||
|
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||||
|
returnBody: true,
|
||||||
|
encodeBodyUtf8: false,
|
||||||
|
decodeUtf8: false,
|
||||||
|
cache: false,
|
||||||
|
isStreamingApi: false,
|
||||||
|
alwaysAllowBody: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpdatePet {
|
||||||
|
Future<ApiCallResponse> call({
|
||||||
|
String? devUUID = '',
|
||||||
|
String? userUUID = '',
|
||||||
|
String? cliID = '',
|
||||||
|
String? atividade = 'atualizarPet',
|
||||||
|
int? petID = 0,
|
||||||
|
String? image = '',
|
||||||
|
String? name = '',
|
||||||
|
String? species = '',
|
||||||
|
String? breed = '',
|
||||||
|
String? color = '',
|
||||||
|
String? birthdayDate = '',
|
||||||
|
String? gender = '',
|
||||||
|
String? size = '',
|
||||||
|
String? notes = '',
|
||||||
|
}) async {
|
||||||
|
final baseUrl = PhpGroup.getBaseUrl();
|
||||||
|
|
||||||
|
return ApiManager.instance.makeApiCall(
|
||||||
|
callName: 'updatePet',
|
||||||
|
apiUrl: '$baseUrl/processRequest.php',
|
||||||
|
callType: ApiCallType.POST,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
'devUUID': devUUID,
|
||||||
|
'userUUID': userUUID,
|
||||||
|
'cliID': cliID,
|
||||||
|
'atividade': atividade,
|
||||||
|
'id': petID,
|
||||||
|
'image': image,
|
||||||
|
'name': name,
|
||||||
|
'species': species,
|
||||||
|
'breed': breed,
|
||||||
|
'color': color,
|
||||||
|
'birthdayDate': ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!),
|
||||||
|
'gender': gender,
|
||||||
|
'size': size,
|
||||||
|
'notes': notes,
|
||||||
|
},
|
||||||
|
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||||
|
returnBody: true,
|
||||||
|
encodeBodyUtf8: false,
|
||||||
|
decodeUtf8: false,
|
||||||
|
cache: false,
|
||||||
|
isStreamingApi: false,
|
||||||
|
alwaysAllowBody: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GetPets {
|
||||||
|
Future<ApiCallResponse> call({
|
||||||
|
String? devUUID = '',
|
||||||
|
String? userUUID = '',
|
||||||
|
String? cliID = '',
|
||||||
|
String? atividade = 'consultaPets',
|
||||||
|
int? page = 0,
|
||||||
|
int? pageSize = 0,
|
||||||
|
}) async {
|
||||||
|
final baseUrl = PhpGroup.getBaseUrl();
|
||||||
|
|
||||||
|
return ApiManager.instance.makeApiCall(
|
||||||
|
callName: 'getPets',
|
||||||
|
apiUrl: '$baseUrl/processRequest.php',
|
||||||
|
callType: ApiCallType.POST,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
'devUUID': devUUID,
|
||||||
|
'userUUID': userUUID,
|
||||||
|
'cliID': cliID,
|
||||||
|
'atividade': atividade,
|
||||||
|
'page': page,
|
||||||
|
'pageSize': pageSize,
|
||||||
|
},
|
||||||
|
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||||
|
returnBody: true,
|
||||||
|
encodeBodyUtf8: false,
|
||||||
|
decodeUtf8: false,
|
||||||
|
cache: false,
|
||||||
|
alwaysAllowBody: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GetPetPhoto {
|
||||||
|
Future<ApiCallResponse> call({
|
||||||
|
String? devUUID = '',
|
||||||
|
String? userUUID = '',
|
||||||
|
String? cliID = '',
|
||||||
|
String? atividade = 'consultaFotoPet',
|
||||||
|
int? petId = 0,
|
||||||
|
}) async {
|
||||||
|
final baseUrl = PhpGroup.getBaseUrl();
|
||||||
|
|
||||||
|
return ApiManager.instance.makeApiCall(
|
||||||
|
callName: 'getPetPhoto',
|
||||||
|
apiUrl: '$baseUrl/getImage.php',
|
||||||
|
callType: ApiCallType.POST,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
'devUUID': devUUID,
|
||||||
|
'userUUID': userUUID,
|
||||||
|
'atividade': atividade,
|
||||||
|
'cliID': cliID,
|
||||||
|
'petId': petId,
|
||||||
|
},
|
||||||
|
bodyType: BodyType.BLOB,
|
||||||
|
returnBody: true,
|
||||||
|
encodeBodyUtf8: false,
|
||||||
|
decodeUtf8: false,
|
||||||
|
cache: false,
|
||||||
|
isStreamingApi: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegisterPet {
|
||||||
|
Future<ApiCallResponse> call({
|
||||||
|
String? devUUID = '',
|
||||||
|
String? userUUID = '',
|
||||||
|
String? cliID = '',
|
||||||
|
String? atividade = 'cadastrarPet',
|
||||||
|
String? image = '',
|
||||||
|
String? name = '',
|
||||||
|
String? species = '',
|
||||||
|
String? breed = '',
|
||||||
|
String? color = '',
|
||||||
|
String? birthdayDate = '',
|
||||||
|
String? gender = '',
|
||||||
|
String? size = '',
|
||||||
|
String? notes = '',
|
||||||
|
}) async {
|
||||||
|
final baseUrl = PhpGroup.getBaseUrl();
|
||||||
|
|
||||||
|
return ApiManager.instance.makeApiCall(
|
||||||
|
callName: 'registerPet',
|
||||||
|
apiUrl: '$baseUrl/processRequest.php',
|
||||||
|
callType: ApiCallType.POST,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
'devUUID': devUUID,
|
||||||
|
'userUUID': userUUID,
|
||||||
|
'cliID': cliID,
|
||||||
|
'atividade': atividade,
|
||||||
|
'image': image,
|
||||||
|
'name': name,
|
||||||
|
'species': species,
|
||||||
|
'breed': breed,
|
||||||
|
if (color != '') 'color': color,
|
||||||
|
if (birthdayDate != '')
|
||||||
|
'birthdayDate':
|
||||||
|
ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!),
|
||||||
|
'gender': gender,
|
||||||
|
'size': size,
|
||||||
|
if (notes != '') 'notes': notes,
|
||||||
|
},
|
||||||
|
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||||
|
returnBody: true,
|
||||||
|
encodeBodyUtf8: false,
|
||||||
|
decodeUtf8: false,
|
||||||
|
cache: false,
|
||||||
|
isStreamingApi: false,
|
||||||
|
alwaysAllowBody: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class BuscaEnconcomendas {
|
class BuscaEnconcomendas {
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
|
@ -58,7 +273,6 @@ class BuscaEnconcomendas {
|
||||||
String? userUUID = '',
|
String? userUUID = '',
|
||||||
String? cliID = '',
|
String? cliID = '',
|
||||||
String? atividade = '',
|
String? atividade = '',
|
||||||
|
|
||||||
String? page = '',
|
String? page = '',
|
||||||
String? pageSize = '',
|
String? pageSize = '',
|
||||||
String? adresseeType = '',
|
String? adresseeType = '',
|
||||||
|
@ -78,7 +292,6 @@ class BuscaEnconcomendas {
|
||||||
'userUUID': userUUID,
|
'userUUID': userUUID,
|
||||||
'atividade': atividade,
|
'atividade': atividade,
|
||||||
'cliID': cliID,
|
'cliID': cliID,
|
||||||
|
|
||||||
'page': page,
|
'page': page,
|
||||||
'pageSize': pageSize,
|
'pageSize': pageSize,
|
||||||
'adresseeType': adresseeType,
|
'adresseeType': adresseeType,
|
||||||
|
@ -94,9 +307,9 @@ class BuscaEnconcomendas {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool? error(dynamic response) => castToType<bool>(getJsonField(
|
bool? error(dynamic response) => castToType<bool>(getJsonField(
|
||||||
response,
|
response,
|
||||||
r'''$.error''',
|
r'''$.error''',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
class CancelaVisita {
|
class CancelaVisita {
|
||||||
|
|
|
@ -29,6 +29,7 @@ enum BodyType {
|
||||||
TEXT,
|
TEXT,
|
||||||
X_WWW_FORM_URL_ENCODED,
|
X_WWW_FORM_URL_ENCODED,
|
||||||
MULTIPART,
|
MULTIPART,
|
||||||
|
BLOB,
|
||||||
}
|
}
|
||||||
|
|
||||||
class ApiCallOptions extends Equatable {
|
class ApiCallOptions extends Equatable {
|
||||||
|
@ -133,13 +134,18 @@ class ApiCallResponse {
|
||||||
http.Response response,
|
http.Response response,
|
||||||
bool returnBody,
|
bool returnBody,
|
||||||
bool decodeUtf8,
|
bool decodeUtf8,
|
||||||
|
BodyType? bodyType,
|
||||||
) {
|
) {
|
||||||
dynamic jsonBody;
|
dynamic jsonBody;
|
||||||
try {
|
try {
|
||||||
final responseBody = decodeUtf8 && returnBody
|
if (bodyType == BodyType.BLOB) {
|
||||||
? const Utf8Decoder().convert(response.bodyBytes)
|
jsonBody = response.bodyBytes; // Armazenar os bytes diretamente
|
||||||
: response.body;
|
} else {
|
||||||
jsonBody = returnBody ? json.decode(responseBody) : null;
|
final responseBody = decodeUtf8 && returnBody
|
||||||
|
? const Utf8Decoder().convert(response.bodyBytes)
|
||||||
|
: response.body;
|
||||||
|
jsonBody = returnBody ? json.decode(responseBody) : null;
|
||||||
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
return ApiCallResponse(
|
return ApiCallResponse(
|
||||||
jsonBody,
|
jsonBody,
|
||||||
|
@ -194,6 +200,7 @@ class ApiManager {
|
||||||
bool decodeUtf8,
|
bool decodeUtf8,
|
||||||
bool isStreamingApi, {
|
bool isStreamingApi, {
|
||||||
http.Client? client,
|
http.Client? client,
|
||||||
|
BodyType? bodyType, // Adicionado para verificar o tipo de corpo
|
||||||
}) async {
|
}) async {
|
||||||
if (params.isNotEmpty) {
|
if (params.isNotEmpty) {
|
||||||
final specifier =
|
final specifier =
|
||||||
|
@ -218,7 +225,8 @@ class ApiManager {
|
||||||
: (client != null ? client.delete : http.delete);
|
: (client != null ? client.delete : http.delete);
|
||||||
final response =
|
final response =
|
||||||
await makeRequest(Uri.parse(apiUrl), headers: toStringMap(headers));
|
await makeRequest(Uri.parse(apiUrl), headers: toStringMap(headers));
|
||||||
return ApiCallResponse.fromHttpResponse(response, returnBody, decodeUtf8);
|
return ApiCallResponse.fromHttpResponse(
|
||||||
|
response, returnBody, decodeUtf8, bodyType); // Passar bodyType
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<ApiCallResponse> requestWithBody(
|
static Future<ApiCallResponse> requestWithBody(
|
||||||
|
@ -259,7 +267,7 @@ class ApiManager {
|
||||||
|
|
||||||
if (bodyType == BodyType.MULTIPART) {
|
if (bodyType == BodyType.MULTIPART) {
|
||||||
return multipartRequest(type, apiUrl, headers, params, returnBody,
|
return multipartRequest(type, apiUrl, headers, params, returnBody,
|
||||||
decodeUtf8, alwaysAllowBody);
|
decodeUtf8, alwaysAllowBody, bodyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
final requestFn = {
|
final requestFn = {
|
||||||
|
@ -270,7 +278,8 @@ class ApiManager {
|
||||||
}[type]!;
|
}[type]!;
|
||||||
final response = await requestFn(Uri.parse(apiUrl),
|
final response = await requestFn(Uri.parse(apiUrl),
|
||||||
headers: toStringMap(headers), body: postBody);
|
headers: toStringMap(headers), body: postBody);
|
||||||
return ApiCallResponse.fromHttpResponse(response, returnBody, decodeUtf8);
|
return ApiCallResponse.fromHttpResponse(
|
||||||
|
response, returnBody, decodeUtf8, bodyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<ApiCallResponse> multipartRequest(
|
static Future<ApiCallResponse> multipartRequest(
|
||||||
|
@ -281,6 +290,7 @@ class ApiManager {
|
||||||
bool returnBody,
|
bool returnBody,
|
||||||
bool decodeUtf8,
|
bool decodeUtf8,
|
||||||
bool alwaysAllowBody,
|
bool alwaysAllowBody,
|
||||||
|
BodyType? bodyType,
|
||||||
) async {
|
) async {
|
||||||
assert(
|
assert(
|
||||||
{ApiCallType.POST, ApiCallType.PUT, ApiCallType.PATCH}.contains(type) ||
|
{ApiCallType.POST, ApiCallType.PUT, ApiCallType.PATCH}.contains(type) ||
|
||||||
|
@ -321,7 +331,8 @@ class ApiManager {
|
||||||
nonFileParams.forEach((key, value) => request.fields[key] = value);
|
nonFileParams.forEach((key, value) => request.fields[key] = value);
|
||||||
|
|
||||||
final response = await http.Response.fromStream(await request.send());
|
final response = await http.Response.fromStream(await request.send());
|
||||||
return ApiCallResponse.fromHttpResponse(response, returnBody, decodeUtf8);
|
return ApiCallResponse.fromHttpResponse(
|
||||||
|
response, returnBody, decodeUtf8, bodyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MediaType? _getMediaType(String? filename) {
|
static MediaType? _getMediaType(String? filename) {
|
||||||
|
@ -362,6 +373,10 @@ class ApiManager {
|
||||||
contentType = 'multipart/form-data';
|
contentType = 'multipart/form-data';
|
||||||
postBody = params;
|
postBody = params;
|
||||||
break;
|
break;
|
||||||
|
case BodyType.BLOB:
|
||||||
|
contentType = 'application/octet-stream';
|
||||||
|
postBody = body;
|
||||||
|
break;
|
||||||
case BodyType.NONE:
|
case BodyType.NONE:
|
||||||
case null:
|
case null:
|
||||||
break;
|
break;
|
||||||
|
@ -513,8 +528,8 @@ class ApiManager {
|
||||||
log('API Call: $callName');
|
log('API Call: $callName');
|
||||||
log('URL: $apiUrl');
|
log('URL: $apiUrl');
|
||||||
log('Headers: $headers');
|
log('Headers: $headers');
|
||||||
log('Params$params');
|
log('Params: $params');
|
||||||
log('Response${result.jsonBody}');
|
log('Response: ${result.jsonBody}');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
|
||||||
|
class AppBarUtil extends StatelessWidget implements PreferredSizeWidget {
|
||||||
|
final String title;
|
||||||
|
final VoidCallback? onBackButtonPressed;
|
||||||
|
final Widget? actionButton;
|
||||||
|
|
||||||
|
const AppBarUtil({
|
||||||
|
Key? key,
|
||||||
|
required this.title,
|
||||||
|
this.onBackButtonPressed,
|
||||||
|
this.actionButton,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AppBar(
|
||||||
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
forceMaterialTransparency: true,
|
||||||
|
elevation: 0.0,
|
||||||
|
leading: FlutterFlowIconButton(
|
||||||
|
borderColor: Colors.transparent,
|
||||||
|
borderRadius: 30.0,
|
||||||
|
borderWidth: 1.0,
|
||||||
|
buttonSize: 60.0,
|
||||||
|
icon: Icon(
|
||||||
|
Icons.keyboard_arrow_left,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
size: 30.0,
|
||||||
|
),
|
||||||
|
onPressed: onBackButtonPressed ?? () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
title,
|
||||||
|
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
||||||
|
fontFamily: 'Nunito',
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 15.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
if (actionButton != null) actionButton!,
|
||||||
|
],
|
||||||
|
centerTitle: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
||||||
|
}
|
|
@ -0,0 +1,273 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
|
||||||
|
class CustomDatePickerUtil extends StatefulWidget {
|
||||||
|
TextEditingController? controller;
|
||||||
|
final FocusNode? focusNode;
|
||||||
|
final String hintText;
|
||||||
|
final String dateFormat;
|
||||||
|
final String locale;
|
||||||
|
final DateTime? initialDate;
|
||||||
|
final DateTime firstDate;
|
||||||
|
final DateTime? lastDate;
|
||||||
|
final bool timePicker;
|
||||||
|
final FormFieldValidator<String>? validator;
|
||||||
|
|
||||||
|
CustomDatePickerUtil({
|
||||||
|
Key? key,
|
||||||
|
this.controller,
|
||||||
|
this.focusNode,
|
||||||
|
required this.hintText,
|
||||||
|
required this.dateFormat,
|
||||||
|
required this.locale,
|
||||||
|
required this.timePicker,
|
||||||
|
this.initialDate,
|
||||||
|
required this.firstDate,
|
||||||
|
this.lastDate,
|
||||||
|
this.validator,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_CustomDatePickerState createState() => _CustomDatePickerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomDatePickerState extends State<CustomDatePickerUtil> {
|
||||||
|
DateTime? _selectedDate;
|
||||||
|
TimeOfDay? _selectedTime;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_selectedDate = widget.initialDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectDate(BuildContext context) async {
|
||||||
|
final pickedDate = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDate: getCurrentTimestamp,
|
||||||
|
firstDate: widget.firstDate,
|
||||||
|
lastDate: widget.lastDate ?? DateTime(2100),
|
||||||
|
builder: (context, child) {
|
||||||
|
return wrapInMaterialDatePickerTheme(
|
||||||
|
context,
|
||||||
|
child!,
|
||||||
|
headerBackgroundColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
headerForegroundColor: FlutterFlowTheme.of(context).info,
|
||||||
|
headerTextStyle: FlutterFlowTheme.of(context).headlineLarge.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).headlineLargeFamily,
|
||||||
|
fontSize: 32.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).headlineLargeFamily),
|
||||||
|
),
|
||||||
|
pickerBackgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
pickerForegroundColor: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
selectedDateTimeBackgroundColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
selectedDateTimeForegroundColor: FlutterFlowTheme.of(context).info,
|
||||||
|
actionButtonForegroundColor: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
iconSize: 24.0,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pickedDate != null) {
|
||||||
|
if (widget.timePicker == true) {
|
||||||
|
final TimeOfDay? pickedTime = await showTimePicker(
|
||||||
|
context: context,
|
||||||
|
initialTime: TimeOfDay.fromDateTime(_selectedDate ?? DateTime.now()),
|
||||||
|
builder: (context, child) {
|
||||||
|
return wrapInMaterialTimePickerTheme(
|
||||||
|
context,
|
||||||
|
child!,
|
||||||
|
headerBackgroundColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
headerForegroundColor: FlutterFlowTheme.of(context).info,
|
||||||
|
headerTextStyle:
|
||||||
|
FlutterFlowTheme.of(context).headlineLarge.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).headlineLargeFamily,
|
||||||
|
fontSize: 32.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).headlineLargeFamily),
|
||||||
|
),
|
||||||
|
pickerBackgroundColor:
|
||||||
|
FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
pickerForegroundColor: FlutterFlowTheme.of(context).info,
|
||||||
|
selectedDateTimeBackgroundColor:
|
||||||
|
FlutterFlowTheme.of(context).primary,
|
||||||
|
selectedDateTimeForegroundColor:
|
||||||
|
FlutterFlowTheme.of(context).info,
|
||||||
|
pickerDialForegroundColor:
|
||||||
|
FlutterFlowTheme.of(context).primaryText,
|
||||||
|
actionButtonForegroundColor:
|
||||||
|
FlutterFlowTheme.of(context).primaryText,
|
||||||
|
iconSize: 24.0,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pickedTime != null) {
|
||||||
|
setState(() {
|
||||||
|
_selectedDate = DateTime(
|
||||||
|
pickedDate.year,
|
||||||
|
pickedDate.month,
|
||||||
|
pickedDate.day,
|
||||||
|
pickedTime.hour,
|
||||||
|
pickedTime.minute,
|
||||||
|
);
|
||||||
|
widget.controller?.text = dateTimeFormat(
|
||||||
|
widget.dateFormat,
|
||||||
|
_selectedDate,
|
||||||
|
locale: widget.locale,
|
||||||
|
);
|
||||||
|
widget.controller?.selection = TextSelection.collapsed(
|
||||||
|
offset: widget.controller!.text.length,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_selectedDate = DateTime(
|
||||||
|
pickedDate.year,
|
||||||
|
pickedDate.month,
|
||||||
|
pickedDate.day,
|
||||||
|
);
|
||||||
|
widget.controller = TextEditingController(
|
||||||
|
text: dateTimeFormat(
|
||||||
|
widget.dateFormat,
|
||||||
|
_selectedDate,
|
||||||
|
locale: widget.locale,
|
||||||
|
));
|
||||||
|
widget.controller?.selection = TextSelection.collapsed(
|
||||||
|
offset: widget.controller!.text.length,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: 60.0,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0),
|
||||||
|
child: TextFormField(
|
||||||
|
controller: widget.controller,
|
||||||
|
focusNode: widget.focusNode,
|
||||||
|
readOnly: true,
|
||||||
|
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||||
|
autofocus: false,
|
||||||
|
obscureText: false,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
labelStyle: FlutterFlowTheme.of(context)
|
||||||
|
.labelMedium
|
||||||
|
.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).labelMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).labelMediumFamily),
|
||||||
|
),
|
||||||
|
hintText: widget.hintText,
|
||||||
|
hintStyle: FlutterFlowTheme.of(context)
|
||||||
|
.labelMedium
|
||||||
|
.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).labelMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).labelMediumFamily),
|
||||||
|
lineHeight: 1.0,
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).customColor6,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).primary,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
suffixIcon: Icon(
|
||||||
|
Icons.date_range,
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
|
lineHeight: 1.8,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
validator: widget.validator,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0),
|
||||||
|
child: InkWell(
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
focusColor: Colors.transparent,
|
||||||
|
hoverColor: Colors.transparent,
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
|
onTap: () => _selectDate(context),
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 80.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
import 'package:easy_debounce/easy_debounce.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:hub/components/atomic_components/shared_components_atoms/tabview.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
|
||||||
|
class CustomInputUtil extends StatefulWidget {
|
||||||
|
final TextEditingController? controller;
|
||||||
|
final String? labelText;
|
||||||
|
final String? hintText;
|
||||||
|
final bool? obscureText;
|
||||||
|
final IconData? suffixIcon;
|
||||||
|
final bool autoFocus;
|
||||||
|
FocusNode? focusNode;
|
||||||
|
final TextInputAction textInputAction;
|
||||||
|
final TextInputType keyboardType;
|
||||||
|
final int maxLength;
|
||||||
|
final String? Function(String?)? validator;
|
||||||
|
final bool haveMaxLength;
|
||||||
|
final void Function(String)? onChanged;
|
||||||
|
|
||||||
|
CustomInputUtil(
|
||||||
|
{Key? key,
|
||||||
|
this.controller,
|
||||||
|
required this.labelText,
|
||||||
|
required this.hintText,
|
||||||
|
required this.suffixIcon,
|
||||||
|
this.autoFocus = false,
|
||||||
|
required this.focusNode,
|
||||||
|
this.onChanged,
|
||||||
|
this.textInputAction = TextInputAction.next,
|
||||||
|
this.keyboardType = TextInputType.text,
|
||||||
|
this.maxLength = 80,
|
||||||
|
this.validator,
|
||||||
|
this.obscureText,
|
||||||
|
required this.haveMaxLength})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CustomInputUtil> createState() => _CustomInputUtilState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomInputUtilState extends State<CustomInputUtil> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 10.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
controller: widget.controller,
|
||||||
|
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||||
|
validator: widget.validator,
|
||||||
|
autofocus: widget.autoFocus,
|
||||||
|
focusNode: widget.focusNode,
|
||||||
|
onChanged: (_) => EasyDebounce.debounce(
|
||||||
|
'${widget.controller}',
|
||||||
|
const Duration(milliseconds: 500),
|
||||||
|
() => setState(() {}),
|
||||||
|
),
|
||||||
|
textInputAction: widget.textInputAction,
|
||||||
|
obscureText: false,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
labelText: widget.labelText,
|
||||||
|
labelStyle: FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).labelMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).labelMediumFamily,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
hintText: widget.hintText,
|
||||||
|
hintStyle: FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).labelMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).labelMediumFamily,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).customColor6,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).primary,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
suffixIcon: Icon(
|
||||||
|
widget.suffixIcon,
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
maxLines: null,
|
||||||
|
maxLength: widget.haveMaxLength ? widget.maxLength : null,
|
||||||
|
keyboardType: widget.keyboardType,
|
||||||
|
inputFormatters: [
|
||||||
|
LengthLimitingTextInputFormatter(widget.maxLength),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:hub/components/organism_components/message_well_component/message_well_component_widget.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_drop_down.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
|
||||||
|
import 'package:hub/flutter_flow/form_field_controller.dart';
|
||||||
|
|
||||||
|
class CustomSelect extends StatefulWidget {
|
||||||
|
final List<String> options;
|
||||||
|
final List<String> optionsLabel;
|
||||||
|
final String hintText;
|
||||||
|
final bool isMultiSelect;
|
||||||
|
FormFieldController<String> controller;
|
||||||
|
dynamic Function(String?)? changed;
|
||||||
|
String? dropDownValue;
|
||||||
|
bool isRequired;
|
||||||
|
|
||||||
|
CustomSelect({
|
||||||
|
Key? key,
|
||||||
|
required this.options,
|
||||||
|
required this.optionsLabel,
|
||||||
|
required this.hintText,
|
||||||
|
required this.controller,
|
||||||
|
required this.changed,
|
||||||
|
this.isRequired = false,
|
||||||
|
this.dropDownValue,
|
||||||
|
this.isMultiSelect = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_CustomSelectState createState() => _CustomSelectState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomSelectState extends State<CustomSelect> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(0, 0.0, 0, 10.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
24.0, 0.0, 24.0, 0.0),
|
||||||
|
child: Container(
|
||||||
|
width: 100.0,
|
||||||
|
height: 48.0,
|
||||||
|
decoration: const BoxDecoration(),
|
||||||
|
child: FlutterFlowDropDown<String>(
|
||||||
|
fillColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
controller: widget.controller ??=
|
||||||
|
FormFieldController<String>(
|
||||||
|
widget.dropDownValue ??= ''),
|
||||||
|
options: widget.options,
|
||||||
|
optionLabels: widget.optionsLabel,
|
||||||
|
onChanged: widget.changed,
|
||||||
|
isMultiSelect: false,
|
||||||
|
width: double.infinity,
|
||||||
|
height: double.infinity,
|
||||||
|
textStyle: FlutterFlowTheme.of(context)
|
||||||
|
.bodyMedium
|
||||||
|
.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
|
),
|
||||||
|
hintText: widget.hintText,
|
||||||
|
icon: Icon(
|
||||||
|
Icons.keyboard_arrow_down_rounded,
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
size: 24.0,
|
||||||
|
),
|
||||||
|
elevation: 2.0,
|
||||||
|
borderColor: FlutterFlowTheme.of(context).customColor6,
|
||||||
|
borderWidth: 0.5,
|
||||||
|
borderRadius: 10.0,
|
||||||
|
margin: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
12.0, 0.0, 16.0, 0.0),
|
||||||
|
hidesUnderline: true,
|
||||||
|
isOverButton: true,
|
||||||
|
isSearchable: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (widget.isRequired)
|
||||||
|
if (widget.dropDownValue == null || widget.dropDownValue == '')
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsetsDirectional.only(top: 5, start: 15),
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'This field is required',
|
||||||
|
ptText: 'Este campo é obrigatório',
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context)
|
||||||
|
.bodySmall
|
||||||
|
.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context)
|
||||||
|
.bodySmallFamily,
|
||||||
|
color:
|
||||||
|
FlutterFlowTheme.of(context).customColor6,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context)
|
||||||
|
.bodySmallFamily),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,178 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
|
||||||
|
import 'package:hub/flutter_flow/upload_data.dart';
|
||||||
|
import 'package:hub/flutter_flow/uploaded_file.dart';
|
||||||
|
|
||||||
|
class MediaUploadButtonUtil extends StatefulWidget {
|
||||||
|
final Function(FFUploadedFile) onUploadComplete;
|
||||||
|
bool isUploading;
|
||||||
|
final String labelText;
|
||||||
|
FFUploadedFile? uploadedFiles;
|
||||||
|
|
||||||
|
MediaUploadButtonUtil(
|
||||||
|
{Key? key,
|
||||||
|
required this.onUploadComplete,
|
||||||
|
required this.isUploading,
|
||||||
|
required this.labelText,
|
||||||
|
this.uploadedFiles})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MediaUploadButtonUtil> createState() => _MediaUploadButtonUtilState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MediaUploadButtonUtilState extends State<MediaUploadButtonUtil> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0),
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
if (widget.uploadedFiles != null &&
|
||||||
|
widget.uploadedFiles!.bytes!.isNotEmpty) {
|
||||||
|
{
|
||||||
|
return InkWell(
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
focusColor: Colors.transparent,
|
||||||
|
hoverColor: Colors.transparent,
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
|
onTap: () async {
|
||||||
|
setState(() {
|
||||||
|
widget.isUploading = false;
|
||||||
|
widget.uploadedFiles =
|
||||||
|
FFUploadedFile(bytes: Uint8List.fromList([]));
|
||||||
|
widget.onUploadComplete(widget.uploadedFiles!);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
child: Image.memory(
|
||||||
|
widget.uploadedFiles!.bytes ?? Uint8List.fromList([]),
|
||||||
|
width: 300.0,
|
||||||
|
height: 200.0,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
child: FFButtonWidget(
|
||||||
|
onPressed: () async {
|
||||||
|
final selectedMedia =
|
||||||
|
await selectMediaWithSourceBottomSheet(
|
||||||
|
context: context,
|
||||||
|
imageQuality: 100,
|
||||||
|
allowPhoto: true,
|
||||||
|
includeDimensions: true,
|
||||||
|
);
|
||||||
|
if (selectedMedia != null) {
|
||||||
|
setState(() => widget.isUploading = true);
|
||||||
|
var selectedUploadedFiles = <FFUploadedFile>[];
|
||||||
|
|
||||||
|
try {
|
||||||
|
showUploadMessage(
|
||||||
|
context,
|
||||||
|
'Uploading file...',
|
||||||
|
showLoading: true,
|
||||||
|
);
|
||||||
|
selectedUploadedFiles = selectedMedia
|
||||||
|
.map((m) => FFUploadedFile(
|
||||||
|
name: m.storagePath.split('/').last,
|
||||||
|
bytes: m.bytes,
|
||||||
|
height: m.dimensions?.height,
|
||||||
|
width: m.dimensions?.width,
|
||||||
|
// blurHash: m.blurHash,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
} finally {
|
||||||
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||||
|
widget.isUploading = false;
|
||||||
|
}
|
||||||
|
if (selectedUploadedFiles.length ==
|
||||||
|
selectedMedia.length) {
|
||||||
|
setState(() {
|
||||||
|
widget.uploadedFiles = selectedUploadedFiles.first;
|
||||||
|
});
|
||||||
|
widget.onUploadComplete(widget.uploadedFiles!);
|
||||||
|
|
||||||
|
showUploadMessage(context, 'Success!');
|
||||||
|
} else {
|
||||||
|
setState(() {});
|
||||||
|
showUploadMessage(context, 'Failed to upload data');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: '',
|
||||||
|
icon: Icon(
|
||||||
|
Icons.photo_camera,
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
size: 30.0,
|
||||||
|
),
|
||||||
|
options: FFButtonOptions(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 120.0,
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
0.0, 0.0, 0.0, 20.0),
|
||||||
|
iconPadding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
14.0, 0.0, 0.0, 20.0),
|
||||||
|
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
textStyle: FlutterFlowTheme.of(context)
|
||||||
|
.titleSmall
|
||||||
|
.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).titleSmallFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 16.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).titleSmallFamily),
|
||||||
|
),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
width: 0.2,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
10.0, 65.0, 10.0, 0.0),
|
||||||
|
child: Text(
|
||||||
|
widget.labelText,
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
|
||||||
|
import 'package:hub/flutter_flow/internationalization.dart';
|
||||||
|
import 'package:json_path/fun_sdk.dart';
|
||||||
|
|
||||||
|
class SubmitButtonUtil extends StatelessWidget {
|
||||||
|
final String labelText;
|
||||||
|
Future Function()? onPressed;
|
||||||
|
|
||||||
|
SubmitButtonUtil({
|
||||||
|
required this.labelText,
|
||||||
|
required this.onPressed,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FFButtonWidget(
|
||||||
|
onPressed: onPressed,
|
||||||
|
text: labelText,
|
||||||
|
options: FFButtonOptions(
|
||||||
|
width: 250.0,
|
||||||
|
height: 36.0,
|
||||||
|
disabledColor: FlutterFlowTheme.of(context).customColor5,
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(80.0, 0.0, 80.0, 0.0),
|
||||||
|
iconPadding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0),
|
||||||
|
color: FlutterFlowTheme.of(context).primary,
|
||||||
|
textStyle: FlutterFlowTheme.of(context).titleSmall.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).titleSmallFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).info,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey(FlutterFlowTheme.of(context).titleSmallFamily),
|
||||||
|
),
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.transparent,
|
||||||
|
width: 30.0,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(15.0),
|
||||||
|
bottomRight: Radius.circular(15.0),
|
||||||
|
topLeft: Radius.circular(15.0),
|
||||||
|
topRight: Radius.circular(15.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
|
||||||
|
class TabViewUtil extends StatelessWidget {
|
||||||
|
final BuildContext context;
|
||||||
|
final dynamic model;
|
||||||
|
String labelTab1;
|
||||||
|
String labelTab2;
|
||||||
|
final TabController controller;
|
||||||
|
final Function(bool) onEditingChanged;
|
||||||
|
Widget widget1;
|
||||||
|
Widget widget2;
|
||||||
|
|
||||||
|
TabViewUtil({
|
||||||
|
super.key,
|
||||||
|
required this.onEditingChanged,
|
||||||
|
required this.context,
|
||||||
|
required this.model,
|
||||||
|
required this.labelTab1,
|
||||||
|
required this.labelTab2,
|
||||||
|
required this.controller,
|
||||||
|
required this.widget1,
|
||||||
|
required this.widget2,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SafeArea(
|
||||||
|
top: true,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: const Alignment(0.0, 0),
|
||||||
|
child: TabBar(
|
||||||
|
labelColor: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
unselectedLabelColor: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
labelStyle: FlutterFlowTheme.of(context).titleMedium.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).titleMediumFamily,
|
||||||
|
fontSize: 13.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).titleMediumFamily),
|
||||||
|
),
|
||||||
|
unselectedLabelStyle: const TextStyle(),
|
||||||
|
indicatorColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
padding: const EdgeInsets.all(4.0),
|
||||||
|
tabs: [
|
||||||
|
Tab(
|
||||||
|
text: labelTab1,
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
text: labelTab2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
controller: controller,
|
||||||
|
onTap: (i) async {
|
||||||
|
if (i == 1) onEditingChanged(false);
|
||||||
|
[() async {}, () async {}][i]();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TabBarView(
|
||||||
|
controller: controller,
|
||||||
|
children: [
|
||||||
|
widget1,
|
||||||
|
widget2,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Adicione o conteúdo do TabBarView aqui
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -356,4 +356,22 @@ class MenuComponentModel extends FlutterFlowModel<MenuComponentWidget> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future petsAction(BuildContext context) async {
|
||||||
|
bool isPet = AppState().pets;
|
||||||
|
if (isPet) {
|
||||||
|
context.push(
|
||||||
|
'/petsPage',
|
||||||
|
extra: <String, dynamic>{
|
||||||
|
kTransitionInfoKey: const TransitionInfo(
|
||||||
|
hasTransition: true,
|
||||||
|
transitionType: PageTransitionType.scale,
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
DialogUnavailable.unavailableFeature(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
||||||
ptText: 'QRCode\nde Acesso',
|
ptText: 'QRCode\nde Acesso',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
MenuButtonWidget(
|
||||||
|
icon: Icons.pets,
|
||||||
|
action: () async {
|
||||||
|
await _model.petsAction(context);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
title: FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Pets\nRegister',
|
||||||
|
ptText: 'Cadastro\nde Pet',
|
||||||
|
),
|
||||||
|
),
|
||||||
MenuButtonWidget(
|
MenuButtonWidget(
|
||||||
icon: Icons.people,
|
icon: Icons.people,
|
||||||
action: () async {
|
action: () async {
|
||||||
|
@ -213,6 +224,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
||||||
ptText: 'QRCode\nde Acesso',
|
ptText: 'QRCode\nde Acesso',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
MenuButtonWidget(
|
||||||
|
icon: Icons.pets,
|
||||||
|
action: () async {
|
||||||
|
await _model.petsAction(context);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
title: FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Pets\nRegister',
|
||||||
|
ptText: 'Cadastrar\nPet',
|
||||||
|
),
|
||||||
|
),
|
||||||
MenuButtonWidget(
|
MenuButtonWidget(
|
||||||
icon: Icons.transfer_within_a_station_outlined,
|
icon: Icons.transfer_within_a_station_outlined,
|
||||||
action: () async {
|
action: () async {
|
||||||
|
@ -338,6 +360,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
||||||
ptText: 'Encomendas',
|
ptText: 'Encomendas',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
MenuButtonWidget(
|
||||||
|
icon: Icons.pets,
|
||||||
|
action: () async {
|
||||||
|
await _model.petsAction(context);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
title: FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Pets\nRegister',
|
||||||
|
ptText: 'Cadastrar\nPet',
|
||||||
|
),
|
||||||
|
),
|
||||||
MenuCardItem(
|
MenuCardItem(
|
||||||
icon: Icons.event_available,
|
icon: Icons.event_available,
|
||||||
action: () async {
|
action: () async {
|
||||||
|
@ -452,6 +485,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
||||||
ptText: 'QRCode de Acesso',
|
ptText: 'QRCode de Acesso',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
MenuCardItem(
|
||||||
|
icon: Icons.pets,
|
||||||
|
action: () async {
|
||||||
|
await _model.petsAction(context);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
title: FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Pets Register',
|
||||||
|
ptText: 'Cadastro de Pet',
|
||||||
|
),
|
||||||
|
),
|
||||||
MenuCardItem(
|
MenuCardItem(
|
||||||
icon: Icons.transfer_within_a_station_outlined,
|
icon: Icons.transfer_within_a_station_outlined,
|
||||||
action: () async {
|
action: () async {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hub/actions/actions.dart';
|
import 'package:hub/actions/actions.dart';
|
||||||
|
import 'package:hub/backend/api_requests/api_calls.dart';
|
||||||
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
|
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
|
||||||
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
@ -8,15 +11,14 @@ import 'package:hub/flutter_flow/nav/nav.dart';
|
||||||
import 'package:hub/shared/utils/validator_util.dart';
|
import 'package:hub/shared/utils/validator_util.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
Widget buildDetails(
|
Widget buildVisitDetails(
|
||||||
dynamic visitaWrapItem,
|
dynamic item,
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Future<dynamic> Function(BuildContext, int, int, String, String)?
|
Future<dynamic> Function(BuildContext, int, int, String, String)?
|
||||||
changeStatusAction) {
|
changeStatusAction) {
|
||||||
return DetailsComponentWidget(
|
return DetailsComponentWidget(
|
||||||
buttons: [
|
buttons: [
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) ==
|
if (getStatus(item['VAW_STATUS']) == status.active) // REJECT ACTION
|
||||||
status.active) // REJECT ACTION
|
|
||||||
FFButtonWidget(
|
FFButtonWidget(
|
||||||
text: FFLocalizations.of(context).getVariableText(
|
text: FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Cancelar',
|
ptText: 'Cancelar',
|
||||||
|
@ -37,10 +39,10 @@ Widget buildDetails(
|
||||||
await changeStatusAction
|
await changeStatusAction
|
||||||
?.call(
|
?.call(
|
||||||
context,
|
context,
|
||||||
int.parse(visitaWrapItem['VAW_DESTINO']),
|
int.parse(item['VAW_DESTINO']),
|
||||||
int.parse(visitaWrapItem['VAW_ID']),
|
int.parse(item['VAW_ID']),
|
||||||
visitaWrapItem['VAW_CHAVE'] ?? '',
|
item['VAW_CHAVE'] ?? '',
|
||||||
visitaWrapItem['VTE_DOCUMENTO'] ?? '',
|
item['VTE_DOCUMENTO'] ?? '',
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
// Navigator.pop(context, value);
|
// Navigator.pop(context, value);
|
||||||
|
@ -93,8 +95,7 @@ Widget buildDetails(
|
||||||
// borderRadius: 12,
|
// borderRadius: 12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) !=
|
if (getStatus(item['VAW_STATUS']) != status.active) // RECALL ACTION
|
||||||
status.active) // RECALL ACTION
|
|
||||||
FFButtonWidget(
|
FFButtonWidget(
|
||||||
text: FFLocalizations.of(context).getVariableText(
|
text: FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Reagendar',
|
ptText: 'Reagendar',
|
||||||
|
@ -106,10 +107,10 @@ Widget buildDetails(
|
||||||
context.pop();
|
context.pop();
|
||||||
|
|
||||||
context.pushNamed('scheduleCompleteVisitPage', extra: {
|
context.pushNamed('scheduleCompleteVisitPage', extra: {
|
||||||
'dropdownValue1': visitaWrapItem['MOT_DESCRICAO'],
|
'dropdownValue1': item['MOT_DESCRICAO'],
|
||||||
'dropdownValue2': visitaWrapItem['NAC_DESCRICAO'],
|
'dropdownValue2': item['NAC_DESCRICAO'],
|
||||||
'visitorJsonList': [visitaWrapItem],
|
'visitorJsonList': [item],
|
||||||
'visitorStrList': visitaWrapItem['VTE_DOCUMENTO'],
|
'visitorStrList': item['VTE_DOCUMENTO'],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
options: FFButtonOptions(
|
options: FFButtonOptions(
|
||||||
|
@ -127,8 +128,7 @@ Widget buildDetails(
|
||||||
// borderRadius: 12,
|
// borderRadius: 12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) ==
|
if (getStatus(item['VAW_STATUS']) == status.active) // SHARE ACTION
|
||||||
status.active) // SHARE ACTION
|
|
||||||
FFButtonWidget(
|
FFButtonWidget(
|
||||||
text: FFLocalizations.of(context).getVariableText(
|
text: FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Compartilhar',
|
ptText: 'Compartilhar',
|
||||||
|
@ -137,13 +137,13 @@ Widget buildDetails(
|
||||||
icon: const Icon(Icons.share),
|
icon: const Icon(Icons.share),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Share.share('''
|
Share.share('''
|
||||||
Olá, \*${visitaWrapItem['VTE_NOME']}\*! Você foi convidado para \*${AppState().local}\*.
|
Olá, \*${item['VTE_NOME']}\*! Você foi convidado para \*${AppState().local}\*.
|
||||||
|
|
||||||
\*Validade do Convite\*:
|
\*Validade do Convite\*:
|
||||||
- Início: ${visitaWrapItem['VAW_DTINICIO']}
|
- Início: ${item['VAW_DTINICIO']}
|
||||||
- Fim: ${visitaWrapItem['VAW_DTFIM']}
|
- Fim: ${item['VAW_DTFIM']}
|
||||||
|
|
||||||
URL do Convite: https://visita.freaccess.com.br/${visitaWrapItem['VAW_ID']}/${AppState().cliUUID}/${visitaWrapItem['VAW_CHAVE']}
|
URL do Convite: https://visita.freaccess.com.br/${item['VAW_ID']}/${AppState().cliUUID}/${item['VAW_CHAVE']}
|
||||||
''');
|
''');
|
||||||
},
|
},
|
||||||
options: FFButtonOptions(
|
options: FFButtonOptions(
|
||||||
|
@ -164,59 +164,57 @@ URL do Convite: https://visita.freaccess.com.br/${visitaWrapItem['VAW_ID']}/${Ap
|
||||||
],
|
],
|
||||||
labelsHashMap: Map<String, String>.from({
|
labelsHashMap: Map<String, String>.from({
|
||||||
'${FFLocalizations.of(context).getVariableText(ptText: "Nome", enText: "Name")}:':
|
'${FFLocalizations.of(context).getVariableText(ptText: "Nome", enText: "Name")}:':
|
||||||
visitaWrapItem['VTE_NOME'] ?? '',
|
item['VTE_NOME'] ?? '',
|
||||||
'${FFLocalizations.of(context).getVariableText(ptText: "Inicio", enText: "Start")}:':
|
'${FFLocalizations.of(context).getVariableText(ptText: "Inicio", enText: "Start")}:':
|
||||||
visitaWrapItem['VAW_DTINICIO'] != '' &&
|
item['VAW_DTINICIO'] != '' && item['VAW_DTINICIO'] != null
|
||||||
visitaWrapItem['VAW_DTINICIO'] != null
|
|
||||||
? ValidatorUtil.toLocalDateTime(
|
? ValidatorUtil.toLocalDateTime(
|
||||||
'yyyy-MM-dd HH:mm:ss', visitaWrapItem['VAW_DTINICIO'])
|
'yyyy-MM-dd HH:mm:ss', item['VAW_DTINICIO'])
|
||||||
: '',
|
: '',
|
||||||
'${FFLocalizations.of(context).getVariableText(ptText: "Fim", enText: "End")}:':
|
'${FFLocalizations.of(context).getVariableText(ptText: "Fim", enText: "End")}:':
|
||||||
visitaWrapItem['VAW_DTFIM'] != '' &&
|
item['VAW_DTFIM'] != '' && item['VAW_DTFIM'] != null
|
||||||
visitaWrapItem['VAW_DTFIM'] != null
|
|
||||||
? ValidatorUtil.toLocalDateTime(
|
? ValidatorUtil.toLocalDateTime(
|
||||||
'yyyy-MM-dd HH:mm:ss', visitaWrapItem['VAW_DTFIM'])
|
'yyyy-MM-dd HH:mm:ss', item['VAW_DTFIM'])
|
||||||
: '',
|
: '',
|
||||||
}),
|
}),
|
||||||
imagePath:
|
imagePath:
|
||||||
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E',
|
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${item['VTE_DOCUMENTO'] ?? ''}&tipo=E',
|
||||||
statusHashMap: [
|
statusHashMap: [
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.active)
|
if (getStatus(item['VAW_STATUS']) == status.active)
|
||||||
Map<String, Color>.from({
|
Map<String, Color>.from({
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Ativo',
|
ptText: 'Ativo',
|
||||||
enText: 'Active',
|
enText: 'Active',
|
||||||
): FlutterFlowTheme.of(context).warning,
|
): FlutterFlowTheme.of(context).warning,
|
||||||
}),
|
}),
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.unknown)
|
if (getStatus(item['VAW_STATUS']) == status.unknown)
|
||||||
Map<String, Color>.from({
|
Map<String, Color>.from({
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Pendente',
|
ptText: 'Pendente',
|
||||||
enText: 'Pending',
|
enText: 'Pending',
|
||||||
): FlutterFlowTheme.of(context).alternate,
|
): FlutterFlowTheme.of(context).alternate,
|
||||||
}),
|
}),
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.canceled)
|
if (getStatus(item['VAW_STATUS']) == status.canceled)
|
||||||
Map<String, Color>.from({
|
Map<String, Color>.from({
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Cancelado',
|
ptText: 'Cancelado',
|
||||||
enText: 'Canceled',
|
enText: 'Canceled',
|
||||||
): FlutterFlowTheme.of(context).error,
|
): FlutterFlowTheme.of(context).error,
|
||||||
}),
|
}),
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.finished)
|
if (getStatus(item['VAW_STATUS']) == status.finished)
|
||||||
Map<String, Color>.from({
|
Map<String, Color>.from({
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Finalizado',
|
ptText: 'Finalizado',
|
||||||
enText: 'Finished',
|
enText: 'Finished',
|
||||||
): FlutterFlowTheme.of(context).success,
|
): FlutterFlowTheme.of(context).success,
|
||||||
}),
|
}),
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.blocked)
|
if (getStatus(item['VAW_STATUS']) == status.blocked)
|
||||||
Map<String, Color>.from({
|
Map<String, Color>.from({
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Bloqueado',
|
ptText: 'Bloqueado',
|
||||||
enText: 'Blocked',
|
enText: 'Blocked',
|
||||||
): FlutterFlowTheme.of(context).error,
|
): FlutterFlowTheme.of(context).error,
|
||||||
}),
|
}),
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.inactive)
|
if (getStatus(item['VAW_STATUS']) == status.inactive)
|
||||||
Map<String, Color>.from({
|
Map<String, Color>.from({
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Inativo',
|
ptText: 'Inativo',
|
||||||
|
@ -226,3 +224,178 @@ URL do Convite: https://visita.freaccess.com.br/${visitaWrapItem['VAW_ID']}/${Ap
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildPetDetails(
|
||||||
|
dynamic item,
|
||||||
|
BuildContext context,
|
||||||
|
Future<dynamic> Function(BuildContext, int, int, String, String)?
|
||||||
|
changeStatusAction) {
|
||||||
|
return DetailsComponentWidget(
|
||||||
|
buttons: [
|
||||||
|
// EDIT ACTION
|
||||||
|
FFButtonWidget(
|
||||||
|
text: FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Editar',
|
||||||
|
enText: 'Edit',
|
||||||
|
),
|
||||||
|
icon: const Icon(Icons.edit),
|
||||||
|
onPressed: () async {
|
||||||
|
context.pop();
|
||||||
|
context.pop();
|
||||||
|
|
||||||
|
context.pushNamed('petsPage', extra: {
|
||||||
|
'pet': item,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
options: FFButtonOptions(
|
||||||
|
width: 130,
|
||||||
|
height: 40,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
elevation: 0,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
// borderRadius: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// DELETE ACTION
|
||||||
|
FFButtonWidget(
|
||||||
|
text: FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Excluir',
|
||||||
|
enText: 'Delete',
|
||||||
|
),
|
||||||
|
icon: const Icon(Icons.close),
|
||||||
|
onPressed: () async {
|
||||||
|
showAlertDialog(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Excluir Pet',
|
||||||
|
enText: 'Delete Pet',
|
||||||
|
),
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Você tem certeza que deseja excluir esse pet?',
|
||||||
|
enText: 'Are you sure you want to delete this pet?',
|
||||||
|
), () async {
|
||||||
|
int id = item['id'];
|
||||||
|
await PhpGroup.deletePet
|
||||||
|
.call(
|
||||||
|
userUUID: AppState().userUUID,
|
||||||
|
devUUID: AppState().devUUID,
|
||||||
|
cliID: AppState().cliUUID,
|
||||||
|
petID: id,
|
||||||
|
)
|
||||||
|
.then((value) {
|
||||||
|
// Navigator.pop(context, value);
|
||||||
|
context.pop(value);
|
||||||
|
context.pop(value);
|
||||||
|
|
||||||
|
if (value == false) {
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Erro ao excluir pet',
|
||||||
|
enText: 'Error deleting pet',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
} else if (value == true) {
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Success deleting pet',
|
||||||
|
ptText: 'Succeso ao excluir pet',
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}).catchError((err, stack) {
|
||||||
|
context.pop();
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Error deleting pet',
|
||||||
|
ptText: 'Erro ao excluir pet',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
options: FFButtonOptions(
|
||||||
|
width: 130,
|
||||||
|
height: 40,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
elevation: 0,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
// borderRadius: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
// 'MIN', 'PEQ', 'MED', 'GRA', 'GIG'
|
||||||
|
labelsHashMap: Map<String, String>.from({
|
||||||
|
if (item['species'] != null && item['species'] != '')
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Espécie", enText: "Species")}:':
|
||||||
|
item['species'].toString().toUpperCase(),
|
||||||
|
if (item['breed'] != null && item['breed'] != '')
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Raça", enText: "Breed")}:':
|
||||||
|
item['breed'].toString().toUpperCase(),
|
||||||
|
if (item['color'] != null && item['color'] != '')
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:':
|
||||||
|
item['color'].toString().toUpperCase(),
|
||||||
|
if (item['birthdayDate'] != null && item['birthdayDate'] != '')
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Data de Nascimento", enText: "Date of Birth")}:':
|
||||||
|
ValidatorUtil.formatDateTimePicker(item['birthdayDate']),
|
||||||
|
if (item['gender'] != null && item['gender'] != '')
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Gênero", enText: "Gender")}:':
|
||||||
|
item['gender'] == 'MAC'
|
||||||
|
? FFLocalizations.of(context)
|
||||||
|
.getVariableText(ptText: 'MACHO', enText: 'MALE')
|
||||||
|
: FFLocalizations.of(context)
|
||||||
|
.getVariableText(enText: 'FEMALE', ptText: 'FÊMEA'),
|
||||||
|
if (item['size'] != null && item['size'] != '')
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Porte", enText: "Size")}:':
|
||||||
|
item['size'] == 'MIN'
|
||||||
|
? FFLocalizations.of(context)
|
||||||
|
.getVariableText(ptText: 'MINI', enText: 'MINI')
|
||||||
|
: item['size'] == 'PEQ'
|
||||||
|
? FFLocalizations.of(context)
|
||||||
|
.getVariableText(ptText: 'PEQUENO', enText: 'SMALL')
|
||||||
|
: item['size'] == 'MED'
|
||||||
|
? FFLocalizations.of(context)
|
||||||
|
.getVariableText(ptText: 'MÉDIO', enText: 'MEDIUM')
|
||||||
|
: item['size'] == 'GRD'
|
||||||
|
? FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'GRANDE', enText: 'LARGE')
|
||||||
|
: item['size'] == 'GIG'
|
||||||
|
? FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'GIGANTE', enText: 'GIANT')
|
||||||
|
: '',
|
||||||
|
if (item['notes'] != null && item['notes'] != '')
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Observação", enText: "Notes")}:':
|
||||||
|
item['notes'] ?? '',
|
||||||
|
}),
|
||||||
|
imagePath:
|
||||||
|
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${AppState().devUUID}&userUUID=${AppState().userUUID}&cliID=${AppState().cliUUID}&atividade=consultaFotoPet&petId=${item['id'] ?? ''}',
|
||||||
|
statusHashMap: [
|
||||||
|
if (item['gender'] == "MAC")
|
||||||
|
Map<String, Color>.from({
|
||||||
|
item['name']: Color(0xFF094CB0),
|
||||||
|
}),
|
||||||
|
if (item['gender'] == "FEM")
|
||||||
|
Map<String, Color>.from({
|
||||||
|
item['name']: Color(0xFFE463E7),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
|
||||||
const kThemeModeKey = '__theme_mode__';
|
const kThemeModeKey = '__theme_mode__';
|
||||||
SharedPreferences? _prefs;
|
SharedPreferences? _prefs;
|
||||||
|
|
||||||
|
@ -620,4 +619,4 @@ extension TextStyleHelper on TextStyle {
|
||||||
height: lineHeight,
|
height: lineHeight,
|
||||||
shadows: shadows,
|
shadows: shadows,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:hub/pages/delivery_schedule_page/delivery_schedule_widget.dart';
|
||||||
import 'package:hub/pages/fast_pass_page/fast_pass_page_widget.dart';
|
import 'package:hub/pages/fast_pass_page/fast_pass_page_widget.dart';
|
||||||
import 'package:hub/pages/message_history_page/message_history_page_widget.dart';
|
import 'package:hub/pages/message_history_page/message_history_page_widget.dart';
|
||||||
import 'package:hub/pages/package_order_page/package_order_page.dart';
|
import 'package:hub/pages/package_order_page/package_order_page.dart';
|
||||||
|
import 'package:hub/pages/pets_page/pets_page_widget.dart';
|
||||||
import 'package:hub/pages/provisional_schedule_page/provisional_schedule_widget.dart';
|
import 'package:hub/pages/provisional_schedule_page/provisional_schedule_widget.dart';
|
||||||
import 'package:hub/pages/reception_page/reception_page_widget.dart';
|
import 'package:hub/pages/reception_page/reception_page_widget.dart';
|
||||||
import 'package:hub/pages/reservation_page/reservation_page_widget.dart';
|
import 'package:hub/pages/reservation_page/reservation_page_widget.dart';
|
||||||
|
@ -201,6 +202,20 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
|
||||||
path: '/reservation',
|
path: '/reservation',
|
||||||
builder: (context, params) => ReservationPageWidget(),
|
builder: (context, params) => ReservationPageWidget(),
|
||||||
),
|
),
|
||||||
|
FFRoute(
|
||||||
|
name: 'petsPage',
|
||||||
|
path: '/petsPage',
|
||||||
|
builder: (context, params) {
|
||||||
|
final pet = params.getParam(
|
||||||
|
'pet',
|
||||||
|
ParamType.JSON,
|
||||||
|
);
|
||||||
|
|
||||||
|
return PetsPageWidget(
|
||||||
|
pet: pet,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
// FFRoute(
|
// FFRoute(
|
||||||
// name: 'settingsPage',
|
// name: 'settingsPage',
|
||||||
// path: '/settingsPage',
|
// path: '/settingsPage',
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
||||||
import 'package:hub/backend/notifications/notification_service.dart';
|
|
||||||
import 'package:hub/shared/utils/log_util.dart';
|
|
||||||
|
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.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';
|
||||||
|
@ -38,6 +34,79 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
||||||
LocalProfileComponentWidget(showBottomSheet: showModalSelectLocal);
|
LocalProfileComponentWidget(showBottomSheet: showModalSelectLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> processData() async {
|
||||||
|
try {
|
||||||
|
var response = await PhpGroup.getDadosCall.call(
|
||||||
|
devUUID: AppState().devUUID,
|
||||||
|
userUUID: AppState().userUUID,
|
||||||
|
cliUUID: AppState().cliUUID,
|
||||||
|
atividade: 'getDados',
|
||||||
|
);
|
||||||
|
|
||||||
|
final error = response.jsonBody['error'];
|
||||||
|
final errorMsg = response.jsonBody['error_msg'];
|
||||||
|
|
||||||
|
if (error == false) {
|
||||||
|
log(response.jsonBody.toString());
|
||||||
|
AppState().whatsapp = response.jsonBody['whatsapp'] ?? false;
|
||||||
|
AppState().provisional = response.jsonBody['provisional'] ?? false;
|
||||||
|
AppState().pets = response.jsonBody['pet'] ?? false;
|
||||||
|
AppState().name = response.jsonBody['visitado']['VDO_NOME'];
|
||||||
|
safeSetState(() {});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogUtil.warningDefault(context).whenComplete(() => processLocals());
|
||||||
|
safeSetState(() {});
|
||||||
|
return;
|
||||||
|
} catch (e, s) {
|
||||||
|
DialogUtil.warningDefault(context).whenComplete(() => processLocals());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> processLocals() async {
|
||||||
|
try {
|
||||||
|
var response = await PhpGroup.getLocalsCall.call(
|
||||||
|
devUUID: AppState().devUUID,
|
||||||
|
userUUID: AppState().userUUID,
|
||||||
|
);
|
||||||
|
|
||||||
|
List<dynamic> locals = response.jsonBody['locais'] ?? [];
|
||||||
|
|
||||||
|
final activeLocals =
|
||||||
|
locals.where((local) => local['CLU_STATUS'] == 'A').toList();
|
||||||
|
|
||||||
|
if (activeLocals.isEmpty || AppState().cliUUID.isEmpty) {
|
||||||
|
await showModalSelectLocal();
|
||||||
|
} else {
|
||||||
|
await processData();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
await showModalSelectLocal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> showModalSelectLocal() async {
|
||||||
|
await showModalBottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
enableDrag: false,
|
||||||
|
isDismissible: false,
|
||||||
|
context: context,
|
||||||
|
builder: (context) => Padding(
|
||||||
|
padding: MediaQuery.viewInsetsOf(context),
|
||||||
|
child: const BottomArrowLinkedLocalsComponentWidget(),
|
||||||
|
),
|
||||||
|
).then((_) async {
|
||||||
|
_model.updatePage(() => safeSetState(() {
|
||||||
|
_localProfileComponentWidget = LocalProfileComponentWidget(
|
||||||
|
showBottomSheet: showModalSelectLocal);
|
||||||
|
}));
|
||||||
|
|
||||||
|
await processData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
|
@ -240,7 +240,6 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
||||||
id: liberationHistoryItem['VTE_ID'].toString(),
|
id: liberationHistoryItem['VTE_ID'].toString(),
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
log('test: $value');
|
|
||||||
if (value) {
|
if (value) {
|
||||||
showSnackbar(
|
showSnackbar(
|
||||||
context,
|
context,
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hub/actions/actions.dart';
|
||||||
|
import 'package:hub/backend/api_requests/api_calls.dart';
|
||||||
|
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
|
||||||
|
import 'package:hub/components/templates_components/details_component/details_component_action.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import 'package:hub/pages/schedule_complete_visit_page/schedule_complete_visit_page_model.dart';
|
||||||
|
import 'package:hub/shared/utils/dialog_util.dart';
|
||||||
|
import 'package:hub/shared/utils/log_util.dart';
|
||||||
|
import 'package:hub/shared/utils/validator_util.dart';
|
||||||
|
|
||||||
|
class PetsHistoryScreen extends StatefulWidget {
|
||||||
|
PetsHistoryScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PetsHistoryScreenState createState() => _PetsHistoryScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PetsHistoryScreenState extends State<PetsHistoryScreen>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
late ScrollController _scrollController;
|
||||||
|
int _pageNumber = 1;
|
||||||
|
final int _pageSize = 10;
|
||||||
|
bool _hasData = false;
|
||||||
|
bool _loading = false;
|
||||||
|
|
||||||
|
late Future<void> _petsFuture;
|
||||||
|
List<dynamic> _petsWrap = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_petsFuture = _fetchVisits();
|
||||||
|
|
||||||
|
_scrollController = ScrollController()
|
||||||
|
..addListener(() {
|
||||||
|
if (_scrollController.position.atEdge &&
|
||||||
|
_scrollController.position.pixels != 0) {
|
||||||
|
_loadMore();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_scrollController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiCallResponse?> _fetchVisits() async {
|
||||||
|
try {
|
||||||
|
setState(() => _loading = true);
|
||||||
|
|
||||||
|
var response = await PhpGroup.getPets.call(
|
||||||
|
devUUID: AppState().devUUID,
|
||||||
|
userUUID: AppState().userUUID,
|
||||||
|
cliID: AppState().cliUUID,
|
||||||
|
atividade: 'consultaPets',
|
||||||
|
pageSize: _pageSize,
|
||||||
|
page: _pageNumber,
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<dynamic> pets = response.jsonBody['pets'] ?? [];
|
||||||
|
|
||||||
|
if (pets != null && pets.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
_petsWrap.addAll(pets);
|
||||||
|
_hasData = true;
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
_showNoMoreDataSnackBar(context);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_hasData = false;
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (e, s) {
|
||||||
|
DialogUtil.errorDefault(context);
|
||||||
|
LogUtil.requestAPIFailed(
|
||||||
|
"proccessRequest.php", "", "Consulta de Pets", e, s);
|
||||||
|
setState(() {
|
||||||
|
_hasData = false;
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadMore() {
|
||||||
|
if (_hasData == true) {
|
||||||
|
_pageNumber++;
|
||||||
|
_petsFuture = _fetchVisits();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showNoMoreDataSnackBar(BuildContext context) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: "Não há mais dados.", enText: "No more data."),
|
||||||
|
),
|
||||||
|
duration: const Duration(seconds: 3),
|
||||||
|
backgroundColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (_hasData == false && _pageNumber <= 1 && _loading == false)
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Text(FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: "Nenhum Pet encontrado!",
|
||||||
|
enText: "No pets found")),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else if (_hasData == true || _pageNumber >= 1)
|
||||||
|
Expanded(
|
||||||
|
child: FutureBuilder<void>(
|
||||||
|
future: _petsFuture,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
return ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
controller: _scrollController,
|
||||||
|
itemCount: _petsWrap.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final item = _petsWrap[index];
|
||||||
|
return _item(context, item);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
if (_hasData == true && _loading == true)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.only(top: 15, bottom: 15),
|
||||||
|
child: Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
|
FlutterFlowTheme.of(context).primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
].addToStart(const SizedBox(height: 0)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _item(BuildContext context, dynamic uItem) {
|
||||||
|
return CardItemTemplateComponentWidget(
|
||||||
|
imagePath:
|
||||||
|
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${AppState().devUUID}&userUUID=${AppState().userUUID}&cliID=${AppState().cliUUID}&atividade=consultaFotoPet&petId=${uItem['id'] ?? ''}',
|
||||||
|
labelsHashMap: {
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Nome", enText: "Name")}:':
|
||||||
|
uItem['name'] ?? '',
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Espécie", enText: "Species")}:':
|
||||||
|
uItem['species'] ?? '',
|
||||||
|
'${FFLocalizations.of(context).getVariableText(ptText: "Raça", enText: "Breed")}:':
|
||||||
|
uItem['breed'] ?? '',
|
||||||
|
},
|
||||||
|
statusHashMap: [
|
||||||
|
if (uItem['size'] == "MIN")
|
||||||
|
{
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Mini',
|
||||||
|
enText: 'Mini',
|
||||||
|
): FlutterFlowTheme.of(context).accent4,
|
||||||
|
},
|
||||||
|
if (uItem['size'] == "PEQ")
|
||||||
|
{
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Pequeno',
|
||||||
|
enText: 'Small',
|
||||||
|
): FlutterFlowTheme.of(context).accent4,
|
||||||
|
},
|
||||||
|
if (uItem['size'] == "MED")
|
||||||
|
{
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Medio',
|
||||||
|
enText: 'Medium',
|
||||||
|
): FlutterFlowTheme.of(context).accent4,
|
||||||
|
},
|
||||||
|
if (uItem['size'] == "GRA")
|
||||||
|
{
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Grande',
|
||||||
|
enText: 'Big',
|
||||||
|
): FlutterFlowTheme.of(context).accent4,
|
||||||
|
},
|
||||||
|
if (uItem['size'] == "GIG")
|
||||||
|
{
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Gigante',
|
||||||
|
enText: 'Giant',
|
||||||
|
): FlutterFlowTheme.of(context).accent4,
|
||||||
|
},
|
||||||
|
if (uItem['gender'] == "MAC")
|
||||||
|
{
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Macho', enText: 'Male'): Color(0xFF094CB0),
|
||||||
|
},
|
||||||
|
if (uItem['gender'] == "FEM")
|
||||||
|
{
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Femêa',
|
||||||
|
enText: 'Female',
|
||||||
|
): Color(0xFFE463E7),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
onTapCardItemAction: () async {
|
||||||
|
await showDialog(
|
||||||
|
useSafeArea: true,
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return Dialog(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: buildPetDetails(
|
||||||
|
uItem,
|
||||||
|
context,
|
||||||
|
changeStatusAction,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
).whenComplete(() {
|
||||||
|
safeSetState(() {
|
||||||
|
_pageNumber = 1;
|
||||||
|
_petsWrap = [];
|
||||||
|
_petsFuture = _fetchVisits();
|
||||||
|
});
|
||||||
|
}).catchError((e, s) {
|
||||||
|
DialogUtil.errorDefault(context);
|
||||||
|
LogUtil.requestAPIFailed(
|
||||||
|
"proccessRequest.php", "", "Consulta de Pets", e, s);
|
||||||
|
safeSetState(() {
|
||||||
|
_hasData = false;
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,246 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hub/backend/api_requests/api_calls.dart';
|
||||||
|
import 'package:hub/backend/api_requests/api_manager.dart';
|
||||||
|
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import 'package:hub/flutter_flow/form_field_controller.dart';
|
||||||
|
import 'package:hub/pages/pets_page/pets_page_widget.dart';
|
||||||
|
import 'package:hub/shared/utils/dialog_util.dart';
|
||||||
|
import 'package:hub/shared/utils/log_util.dart';
|
||||||
|
import '/custom_code/actions/index.dart' as actions;
|
||||||
|
|
||||||
|
class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
||||||
|
late final TabController tabBarController;
|
||||||
|
|
||||||
|
ApiCallResponse? petsResponse;
|
||||||
|
int? petId;
|
||||||
|
BuildContext? buildContext;
|
||||||
|
|
||||||
|
// Controller para o Upload de Arquivos
|
||||||
|
bool isDataUploading = false;
|
||||||
|
FFUploadedFile? uploadedLocalFile;
|
||||||
|
String? imgBase64;
|
||||||
|
|
||||||
|
// Controller para o DropDown
|
||||||
|
String? dropDownValue1;
|
||||||
|
FormFieldController<String>? dropDownValueController1;
|
||||||
|
|
||||||
|
String? dropDownValue2;
|
||||||
|
FormFieldController<String>? dropDownValueController2;
|
||||||
|
|
||||||
|
// Controller para o TextField
|
||||||
|
FocusNode? textFieldFocusName;
|
||||||
|
TextEditingController? textControllerName;
|
||||||
|
String? textControllerNameValidator(BuildContext context, String? val) {
|
||||||
|
if (val == null || val.isEmpty) {
|
||||||
|
return FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'This field is required',
|
||||||
|
ptText: 'Este campo é obrigatório',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusNode? textFieldFocusSpecies;
|
||||||
|
TextEditingController? textControllerSpecies;
|
||||||
|
String? textControllerSpeciesValidator(BuildContext context, String? val) {
|
||||||
|
if (val == null || val.isEmpty) {
|
||||||
|
return FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'This field is required',
|
||||||
|
ptText: 'Este campo é obrigatório',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusNode? textFieldFocusRace;
|
||||||
|
TextEditingController? textControllerRace;
|
||||||
|
String? textControllerRaceValidator(BuildContext context, String? val) {
|
||||||
|
if (val == null || val.isEmpty) {
|
||||||
|
return FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'This field is required',
|
||||||
|
ptText: 'Este campo é obrigatório',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusNode? textFieldFocusColor;
|
||||||
|
TextEditingController? textControllerColor;
|
||||||
|
String? Function(BuildContext, String?)? textControllerColorValidator;
|
||||||
|
|
||||||
|
DateTime? selectedDate;
|
||||||
|
FocusNode? textFieldFocusData;
|
||||||
|
TextEditingController? textControllerData;
|
||||||
|
String? textControllerDataValidator(BuildContext context, String? val) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusNode? textFieldFocusObservation;
|
||||||
|
TextEditingController? textControllerObservation;
|
||||||
|
String? Function(BuildContext, String?)? textControllerObservationValidator;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState(BuildContext context) {
|
||||||
|
// Se liga! Esse é o controller do TabBar
|
||||||
|
tabBarController = TabController(
|
||||||
|
vsync: Navigator.of(context),
|
||||||
|
length: 2,
|
||||||
|
);
|
||||||
|
|
||||||
|
textFieldFocusName = FocusNode();
|
||||||
|
textControllerName = TextEditingController();
|
||||||
|
// textControllerNameValidator =
|
||||||
|
// (context, value) => _textControllerNameValidator(context, value);
|
||||||
|
|
||||||
|
textFieldFocusSpecies = FocusNode();
|
||||||
|
textControllerSpecies = TextEditingController();
|
||||||
|
|
||||||
|
textFieldFocusRace = FocusNode();
|
||||||
|
textControllerRace = TextEditingController();
|
||||||
|
|
||||||
|
textFieldFocusColor = FocusNode();
|
||||||
|
textControllerColor = TextEditingController();
|
||||||
|
|
||||||
|
textFieldFocusData = FocusNode();
|
||||||
|
textControllerData = TextEditingController(
|
||||||
|
text: dateTimeFormat(
|
||||||
|
'dd/MM/yyyy',
|
||||||
|
DateTime.now(),
|
||||||
|
));
|
||||||
|
|
||||||
|
textFieldFocusObservation = FocusNode();
|
||||||
|
textControllerObservation = TextEditingController();
|
||||||
|
|
||||||
|
dropDownValueController1 =
|
||||||
|
FormFieldController<String>(dropDownValue1 ??= 'Selecione uma opção');
|
||||||
|
|
||||||
|
dropDownValueController2 =
|
||||||
|
FormFieldController<String>(dropDownValue2 ??= 'Selecione uma opção');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
tabBarController.dispose();
|
||||||
|
|
||||||
|
textFieldFocusName?.dispose();
|
||||||
|
textControllerName?.dispose();
|
||||||
|
|
||||||
|
textFieldFocusSpecies?.dispose();
|
||||||
|
textControllerSpecies?.dispose();
|
||||||
|
|
||||||
|
textFieldFocusRace?.dispose();
|
||||||
|
textControllerRace?.dispose();
|
||||||
|
|
||||||
|
textFieldFocusColor?.dispose();
|
||||||
|
textControllerColor?.dispose();
|
||||||
|
|
||||||
|
textFieldFocusData?.dispose();
|
||||||
|
textControllerData?.dispose();
|
||||||
|
|
||||||
|
textFieldFocusObservation?.dispose();
|
||||||
|
textControllerObservation?.dispose();
|
||||||
|
|
||||||
|
dropDownValueController1?.dispose();
|
||||||
|
dropDownValueController2?.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validador do formulário
|
||||||
|
bool isFormValid(BuildContext context) {
|
||||||
|
if (uploadedLocalFile == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (textControllerName.text.isEmpty ||
|
||||||
|
textControllerName.text.length > 80 ||
|
||||||
|
textControllerName.text == '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (textControllerSpecies.text.isEmpty ||
|
||||||
|
textControllerSpecies.text == '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (textControllerRace.text.isEmpty || textControllerRace.text == '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dropDownValue1 == null ||
|
||||||
|
dropDownValue1!.isEmpty ||
|
||||||
|
dropDownValue1 == '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dropDownValue2 == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updatePet() async {
|
||||||
|
await PhpGroup.updatePet
|
||||||
|
.call(
|
||||||
|
cliID: AppState().cliUUID,
|
||||||
|
devUUID: AppState().devUUID,
|
||||||
|
userUUID: AppState().userUUID,
|
||||||
|
petID: petId,
|
||||||
|
image: await actions.convertImageFileToBase64(
|
||||||
|
uploadedLocalFile!,
|
||||||
|
),
|
||||||
|
birthdayDate: textControllerData!.text,
|
||||||
|
color: textControllerColor!.text,
|
||||||
|
breed: textControllerRace!.text,
|
||||||
|
species: textControllerSpecies!.text,
|
||||||
|
name: textControllerName!.text,
|
||||||
|
gender: dropDownValue1!,
|
||||||
|
notes: textControllerObservation!.text,
|
||||||
|
size: dropDownValue2!,
|
||||||
|
)
|
||||||
|
.then((response) {
|
||||||
|
if (response.jsonBody['error'] == true) {
|
||||||
|
DialogUtil.error(buildContext!,
|
||||||
|
jsonDecode(response.jsonBody['error_msg'])[0]['message']);
|
||||||
|
}
|
||||||
|
DialogUtil.success(
|
||||||
|
buildContext!,
|
||||||
|
FFLocalizations.of(buildContext!).getVariableText(
|
||||||
|
enText: 'Pet successfully updated',
|
||||||
|
ptText: 'Pet atualizado com sucesso',
|
||||||
|
));
|
||||||
|
}).catchError((error) {
|
||||||
|
log(error.toString());
|
||||||
|
DialogUtil.errorDefault(buildContext!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> registerPet() async {
|
||||||
|
await PhpGroup.registerPet
|
||||||
|
.call(
|
||||||
|
cliID: AppState().cliUUID,
|
||||||
|
devUUID: AppState().devUUID,
|
||||||
|
userUUID: AppState().userUUID,
|
||||||
|
image: await actions.convertImageFileToBase64(
|
||||||
|
uploadedLocalFile!,
|
||||||
|
),
|
||||||
|
birthdayDate: textControllerData!.text,
|
||||||
|
color: textControllerColor!.text,
|
||||||
|
breed: textControllerRace!.text,
|
||||||
|
species: textControllerSpecies!.text,
|
||||||
|
name: textControllerName!.text,
|
||||||
|
gender: dropDownValue1!,
|
||||||
|
size: dropDownValue2!,
|
||||||
|
notes: textControllerObservation!.text,
|
||||||
|
)
|
||||||
|
.then((response) {
|
||||||
|
if (response.jsonBody['error'] == true) {
|
||||||
|
DialogUtil.error(buildContext!,
|
||||||
|
jsonDecode(response.jsonBody['error_msg'])[0]['message']);
|
||||||
|
}
|
||||||
|
DialogUtil.success(
|
||||||
|
buildContext!,
|
||||||
|
FFLocalizations.of(buildContext!).getVariableText(
|
||||||
|
enText: 'Pet successfully registered',
|
||||||
|
ptText: 'Pet cadastrado com sucesso',
|
||||||
|
));
|
||||||
|
}).catchError((error) {
|
||||||
|
DialogUtil.errorDefault(buildContext!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -225,7 +225,6 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
);
|
);
|
||||||
}).whenComplete(() => notifyListeners());
|
}).whenComplete(() => notifyListeners());
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
log(e.toString());
|
|
||||||
context.pop();
|
context.pop();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -236,7 +236,7 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget>
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return Dialog(
|
return Dialog(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: buildDetails(
|
child: buildVisitDetails(
|
||||||
visitaWrapItem,
|
visitaWrapItem,
|
||||||
context,
|
context,
|
||||||
changeStatusAction,
|
changeStatusAction,
|
||||||
|
|
|
@ -20,10 +20,21 @@ class ValidatorUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
static String toISO8601(String format, String value) {
|
static String toISO8601(String format, String value) {
|
||||||
|
log('value: $value');
|
||||||
DateFormat dateFormat = DateFormat(format);
|
DateFormat dateFormat = DateFormat(format);
|
||||||
DateTime dateTime = dateFormat.parse(value);
|
DateTime dateTime = dateFormat.parse(value);
|
||||||
|
|
||||||
return dateTime.toIso8601String();
|
return dateTime.toIso8601String() + 'Z';
|
||||||
|
}
|
||||||
|
|
||||||
|
static String toISO8601USA(String format, String value) {
|
||||||
|
log('value: $value');
|
||||||
|
DateFormat dateFormat = DateFormat(format);
|
||||||
|
DateTime dateTime = dateFormat.parse(value);
|
||||||
|
String date = dateTime.toIso8601String() + 'Z';
|
||||||
|
date = date.substring(0, 11) + '03:00:00.000Z';
|
||||||
|
|
||||||
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String toLocalDateTime(String format, String value) {
|
static String toLocalDateTime(String format, String value) {
|
||||||
|
@ -32,4 +43,13 @@ class ValidatorUtil {
|
||||||
|
|
||||||
return DateFormat('dd/MM/yyyy HH:mm:ss').format(dateTime);
|
return DateFormat('dd/MM/yyyy HH:mm:ss').format(dateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String formatDateTimePicker(String dateTime) {
|
||||||
|
log('dateTime: $dateTime');
|
||||||
|
List<String> parts = dateTime.split(' ');
|
||||||
|
String datePart = parts[0];
|
||||||
|
List<String> dateParts = datePart.split('-');
|
||||||
|
String formattedDate = '${dateParts[2]}/${dateParts[1]}/${dateParts[0]}';
|
||||||
|
return formattedDate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
18
pubspec.lock
18
pubspec.lock
|
@ -186,7 +186,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.4+2"
|
version: "0.3.4+2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
|
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
|
||||||
|
@ -241,6 +241,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
|
dio:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dio
|
||||||
|
sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.7.0"
|
||||||
|
dio_web_adapter:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dio_web_adapter
|
||||||
|
sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
dropdown_button2:
|
dropdown_button2:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -97,6 +97,8 @@ dependencies:
|
||||||
firebase_crashlytics: ^4.0.1
|
firebase_crashlytics: ^4.0.1
|
||||||
awesome_notifications: ^0.9.3+1
|
awesome_notifications: ^0.9.3+1
|
||||||
app_tracking_transparency: ^2.0.6
|
app_tracking_transparency: ^2.0.6
|
||||||
|
dio: ^5.7.0
|
||||||
|
crypto: ^3.0.5
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
http: 1.2.1
|
http: 1.2.1
|
||||||
|
|
Loading…
Reference in New Issue