Merge branch 'main' into fix/fd-707
This commit is contained in:
commit
9a2aa45b07
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 {
|
||||
for (var i = 0; i < payload['convites'].length; i++) {
|
||||
log('ADD');
|
||||
await Share.share('''
|
||||
Olá, \*${payload['convites'][i]['VTE_NOME']}\*! Você foi convidado para \*${AppState().local}\*.
|
||||
|
||||
|
|
|
@ -160,12 +160,17 @@ class AppState extends ChangeNotifier {
|
|||
await _safeInitAsync(() async {
|
||||
_whatsapp = await secureStorage.getBool('whatsapp') ?? _whatsapp;
|
||||
});
|
||||
await _safeInitAsync(() async {
|
||||
_pets = await secureStorage.getBool('pets') ?? _pets;
|
||||
});
|
||||
await _safeInitAsync(() async {
|
||||
_haveLocal = await secureStorage.getBool('ff_have_local') ?? _haveLocal;
|
||||
});
|
||||
|
||||
await _safeInitAsync(() async {
|
||||
_isRequestOSNotification = await secureStorage.getBool('ff_request_os_notification') ?? _isRequestOSNotification;
|
||||
_isRequestOSNotification =
|
||||
await secureStorage.getBool('ff_request_os_notification') ??
|
||||
_isRequestOSNotification;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -181,10 +186,21 @@ class AppState extends ChangeNotifier {
|
|||
_isRequestOSNotification = value;
|
||||
secureStorage.setBool('ff_request_os_notification', value);
|
||||
}
|
||||
|
||||
void deleteIsRequestOSNotification() {
|
||||
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 get whatsapp => _whatsapp;
|
||||
|
|
|
@ -49,8 +49,223 @@ class PhpGroup {
|
|||
static DeleteAccount deleteAccount = DeleteAccount();
|
||||
static CancelaVisita cancelaVisita = CancelaVisita();
|
||||
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 {
|
||||
Future<ApiCallResponse> call({
|
||||
|
@ -58,7 +273,6 @@ class BuscaEnconcomendas {
|
|||
String? userUUID = '',
|
||||
String? cliID = '',
|
||||
String? atividade = '',
|
||||
|
||||
String? page = '',
|
||||
String? pageSize = '',
|
||||
String? adresseeType = '',
|
||||
|
@ -78,7 +292,6 @@ class BuscaEnconcomendas {
|
|||
'userUUID': userUUID,
|
||||
'atividade': atividade,
|
||||
'cliID': cliID,
|
||||
|
||||
'page': page,
|
||||
'pageSize': pageSize,
|
||||
'adresseeType': adresseeType,
|
||||
|
@ -94,9 +307,9 @@ class BuscaEnconcomendas {
|
|||
}
|
||||
|
||||
bool? error(dynamic response) => castToType<bool>(getJsonField(
|
||||
response,
|
||||
r'''$.error''',
|
||||
));
|
||||
response,
|
||||
r'''$.error''',
|
||||
));
|
||||
}
|
||||
|
||||
class CancelaVisita {
|
||||
|
|
|
@ -29,6 +29,7 @@ enum BodyType {
|
|||
TEXT,
|
||||
X_WWW_FORM_URL_ENCODED,
|
||||
MULTIPART,
|
||||
BLOB,
|
||||
}
|
||||
|
||||
class ApiCallOptions extends Equatable {
|
||||
|
@ -133,13 +134,18 @@ class ApiCallResponse {
|
|||
http.Response response,
|
||||
bool returnBody,
|
||||
bool decodeUtf8,
|
||||
BodyType? bodyType,
|
||||
) {
|
||||
dynamic jsonBody;
|
||||
try {
|
||||
final responseBody = decodeUtf8 && returnBody
|
||||
? const Utf8Decoder().convert(response.bodyBytes)
|
||||
: response.body;
|
||||
jsonBody = returnBody ? json.decode(responseBody) : null;
|
||||
if (bodyType == BodyType.BLOB) {
|
||||
jsonBody = response.bodyBytes; // Armazenar os bytes diretamente
|
||||
} else {
|
||||
final responseBody = decodeUtf8 && returnBody
|
||||
? const Utf8Decoder().convert(response.bodyBytes)
|
||||
: response.body;
|
||||
jsonBody = returnBody ? json.decode(responseBody) : null;
|
||||
}
|
||||
} catch (_) {}
|
||||
return ApiCallResponse(
|
||||
jsonBody,
|
||||
|
@ -194,6 +200,7 @@ class ApiManager {
|
|||
bool decodeUtf8,
|
||||
bool isStreamingApi, {
|
||||
http.Client? client,
|
||||
BodyType? bodyType, // Adicionado para verificar o tipo de corpo
|
||||
}) async {
|
||||
if (params.isNotEmpty) {
|
||||
final specifier =
|
||||
|
@ -218,7 +225,8 @@ class ApiManager {
|
|||
: (client != null ? client.delete : http.delete);
|
||||
final response =
|
||||
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(
|
||||
|
@ -259,7 +267,7 @@ class ApiManager {
|
|||
|
||||
if (bodyType == BodyType.MULTIPART) {
|
||||
return multipartRequest(type, apiUrl, headers, params, returnBody,
|
||||
decodeUtf8, alwaysAllowBody);
|
||||
decodeUtf8, alwaysAllowBody, bodyType);
|
||||
}
|
||||
|
||||
final requestFn = {
|
||||
|
@ -270,7 +278,8 @@ class ApiManager {
|
|||
}[type]!;
|
||||
final response = await requestFn(Uri.parse(apiUrl),
|
||||
headers: toStringMap(headers), body: postBody);
|
||||
return ApiCallResponse.fromHttpResponse(response, returnBody, decodeUtf8);
|
||||
return ApiCallResponse.fromHttpResponse(
|
||||
response, returnBody, decodeUtf8, bodyType);
|
||||
}
|
||||
|
||||
static Future<ApiCallResponse> multipartRequest(
|
||||
|
@ -281,6 +290,7 @@ class ApiManager {
|
|||
bool returnBody,
|
||||
bool decodeUtf8,
|
||||
bool alwaysAllowBody,
|
||||
BodyType? bodyType,
|
||||
) async {
|
||||
assert(
|
||||
{ApiCallType.POST, ApiCallType.PUT, ApiCallType.PATCH}.contains(type) ||
|
||||
|
@ -321,7 +331,8 @@ class ApiManager {
|
|||
nonFileParams.forEach((key, value) => request.fields[key] = value);
|
||||
|
||||
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) {
|
||||
|
@ -362,6 +373,10 @@ class ApiManager {
|
|||
contentType = 'multipart/form-data';
|
||||
postBody = params;
|
||||
break;
|
||||
case BodyType.BLOB:
|
||||
contentType = 'application/octet-stream';
|
||||
postBody = body;
|
||||
break;
|
||||
case BodyType.NONE:
|
||||
case null:
|
||||
break;
|
||||
|
@ -513,8 +528,8 @@ class ApiManager {
|
|||
log('API Call: $callName');
|
||||
log('URL: $apiUrl');
|
||||
log('Headers: $headers');
|
||||
log('Params$params');
|
||||
log('Response${result.jsonBody}');
|
||||
log('Params: $params');
|
||||
log('Response: ${result.jsonBody}');
|
||||
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',
|
||||
),
|
||||
),
|
||||
MenuButtonWidget(
|
||||
icon: Icons.pets,
|
||||
action: () async {
|
||||
await _model.petsAction(context);
|
||||
setState(() {});
|
||||
},
|
||||
title: FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Pets\nRegister',
|
||||
ptText: 'Cadastro\nde Pet',
|
||||
),
|
||||
),
|
||||
MenuButtonWidget(
|
||||
icon: Icons.people,
|
||||
action: () async {
|
||||
|
@ -213,6 +224,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
|||
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(
|
||||
icon: Icons.transfer_within_a_station_outlined,
|
||||
action: () async {
|
||||
|
@ -338,6 +360,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
|||
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(
|
||||
icon: Icons.event_available,
|
||||
action: () async {
|
||||
|
@ -452,6 +485,17 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
|||
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(
|
||||
icon: Icons.transfer_within_a_station_outlined,
|
||||
action: () async {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import 'dart:developer';
|
||||
|
||||
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/details_component/details_component_widget.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_theme.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:share_plus/share_plus.dart';
|
||||
|
||||
Widget buildDetails(
|
||||
dynamic visitaWrapItem,
|
||||
Widget buildVisitDetails(
|
||||
dynamic item,
|
||||
BuildContext context,
|
||||
Future<dynamic> Function(BuildContext, int, int, String, String)?
|
||||
changeStatusAction) {
|
||||
return DetailsComponentWidget(
|
||||
buttons: [
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) ==
|
||||
status.active) // REJECT ACTION
|
||||
if (getStatus(item['VAW_STATUS']) == status.active) // REJECT ACTION
|
||||
FFButtonWidget(
|
||||
text: FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Cancelar',
|
||||
|
@ -37,10 +39,10 @@ Widget buildDetails(
|
|||
await changeStatusAction
|
||||
?.call(
|
||||
context,
|
||||
int.parse(visitaWrapItem['VAW_DESTINO']),
|
||||
int.parse(visitaWrapItem['VAW_ID']),
|
||||
visitaWrapItem['VAW_CHAVE'] ?? '',
|
||||
visitaWrapItem['VTE_DOCUMENTO'] ?? '',
|
||||
int.parse(item['VAW_DESTINO']),
|
||||
int.parse(item['VAW_ID']),
|
||||
item['VAW_CHAVE'] ?? '',
|
||||
item['VTE_DOCUMENTO'] ?? '',
|
||||
)
|
||||
.then((value) {
|
||||
// Navigator.pop(context, value);
|
||||
|
@ -93,8 +95,7 @@ Widget buildDetails(
|
|||
// borderRadius: 12,
|
||||
),
|
||||
),
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) !=
|
||||
status.active) // RECALL ACTION
|
||||
if (getStatus(item['VAW_STATUS']) != status.active) // RECALL ACTION
|
||||
FFButtonWidget(
|
||||
text: FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Reagendar',
|
||||
|
@ -106,10 +107,10 @@ Widget buildDetails(
|
|||
context.pop();
|
||||
|
||||
context.pushNamed('scheduleCompleteVisitPage', extra: {
|
||||
'dropdownValue1': visitaWrapItem['MOT_DESCRICAO'],
|
||||
'dropdownValue2': visitaWrapItem['NAC_DESCRICAO'],
|
||||
'visitorJsonList': [visitaWrapItem],
|
||||
'visitorStrList': visitaWrapItem['VTE_DOCUMENTO'],
|
||||
'dropdownValue1': item['MOT_DESCRICAO'],
|
||||
'dropdownValue2': item['NAC_DESCRICAO'],
|
||||
'visitorJsonList': [item],
|
||||
'visitorStrList': item['VTE_DOCUMENTO'],
|
||||
});
|
||||
},
|
||||
options: FFButtonOptions(
|
||||
|
@ -127,8 +128,7 @@ Widget buildDetails(
|
|||
// borderRadius: 12,
|
||||
),
|
||||
),
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) ==
|
||||
status.active) // SHARE ACTION
|
||||
if (getStatus(item['VAW_STATUS']) == status.active) // SHARE ACTION
|
||||
FFButtonWidget(
|
||||
text: FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Compartilhar',
|
||||
|
@ -137,13 +137,13 @@ Widget buildDetails(
|
|||
icon: const Icon(Icons.share),
|
||||
onPressed: () async {
|
||||
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\*:
|
||||
- Início: ${visitaWrapItem['VAW_DTINICIO']}
|
||||
- Fim: ${visitaWrapItem['VAW_DTFIM']}
|
||||
- Início: ${item['VAW_DTINICIO']}
|
||||
- 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(
|
||||
|
@ -164,59 +164,57 @@ URL do Convite: https://visita.freaccess.com.br/${visitaWrapItem['VAW_ID']}/${Ap
|
|||
],
|
||||
labelsHashMap: Map<String, String>.from({
|
||||
'${FFLocalizations.of(context).getVariableText(ptText: "Nome", enText: "Name")}:':
|
||||
visitaWrapItem['VTE_NOME'] ?? '',
|
||||
item['VTE_NOME'] ?? '',
|
||||
'${FFLocalizations.of(context).getVariableText(ptText: "Inicio", enText: "Start")}:':
|
||||
visitaWrapItem['VAW_DTINICIO'] != '' &&
|
||||
visitaWrapItem['VAW_DTINICIO'] != null
|
||||
item['VAW_DTINICIO'] != '' && item['VAW_DTINICIO'] != null
|
||||
? 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")}:':
|
||||
visitaWrapItem['VAW_DTFIM'] != '' &&
|
||||
visitaWrapItem['VAW_DTFIM'] != null
|
||||
item['VAW_DTFIM'] != '' && item['VAW_DTFIM'] != null
|
||||
? ValidatorUtil.toLocalDateTime(
|
||||
'yyyy-MM-dd HH:mm:ss', visitaWrapItem['VAW_DTFIM'])
|
||||
'yyyy-MM-dd HH:mm:ss', item['VAW_DTFIM'])
|
||||
: '',
|
||||
}),
|
||||
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: [
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.active)
|
||||
if (getStatus(item['VAW_STATUS']) == status.active)
|
||||
Map<String, Color>.from({
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Ativo',
|
||||
enText: 'Active',
|
||||
): FlutterFlowTheme.of(context).warning,
|
||||
}),
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.unknown)
|
||||
if (getStatus(item['VAW_STATUS']) == status.unknown)
|
||||
Map<String, Color>.from({
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Pendente',
|
||||
enText: 'Pending',
|
||||
): FlutterFlowTheme.of(context).alternate,
|
||||
}),
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.canceled)
|
||||
if (getStatus(item['VAW_STATUS']) == status.canceled)
|
||||
Map<String, Color>.from({
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Cancelado',
|
||||
enText: 'Canceled',
|
||||
): FlutterFlowTheme.of(context).error,
|
||||
}),
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.finished)
|
||||
if (getStatus(item['VAW_STATUS']) == status.finished)
|
||||
Map<String, Color>.from({
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Finalizado',
|
||||
enText: 'Finished',
|
||||
): FlutterFlowTheme.of(context).success,
|
||||
}),
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.blocked)
|
||||
if (getStatus(item['VAW_STATUS']) == status.blocked)
|
||||
Map<String, Color>.from({
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Bloqueado',
|
||||
enText: 'Blocked',
|
||||
): FlutterFlowTheme.of(context).error,
|
||||
}),
|
||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.inactive)
|
||||
if (getStatus(item['VAW_STATUS']) == status.inactive)
|
||||
Map<String, Color>.from({
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
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';
|
||||
|
||||
|
||||
const kThemeModeKey = '__theme_mode__';
|
||||
SharedPreferences? _prefs;
|
||||
|
||||
|
@ -620,4 +619,4 @@ extension TextStyleHelper on TextStyle {
|
|||
height: lineHeight,
|
||||
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/message_history_page/message_history_page_widget.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/reception_page/reception_page_widget.dart';
|
||||
import 'package:hub/pages/reservation_page/reservation_page_widget.dart';
|
||||
|
@ -201,6 +202,20 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
|
|||
path: '/reservation',
|
||||
builder: (context, params) => ReservationPageWidget(),
|
||||
),
|
||||
FFRoute(
|
||||
name: 'petsPage',
|
||||
path: '/petsPage',
|
||||
builder: (context, params) {
|
||||
final pet = params.getParam(
|
||||
'pet',
|
||||
ParamType.JSON,
|
||||
);
|
||||
|
||||
return PetsPageWidget(
|
||||
pet: pet,
|
||||
);
|
||||
},
|
||||
),
|
||||
// FFRoute(
|
||||
// name: 'settingsPage',
|
||||
// path: '/settingsPage',
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import 'dart:async';
|
||||
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/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
@ -38,6 +34,79 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
|||
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
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
|
|
|
@ -240,7 +240,6 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
|||
liberationHistoryItem['VTE_ID'].toString(),
|
||||
)
|
||||
.then((value) {
|
||||
log('test: $value');
|
||||
if (value) {
|
||||
showSnackbar(
|
||||
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());
|
||||
} on Exception catch (e) {
|
||||
log(e.toString());
|
||||
context.pop();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -236,7 +236,7 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget>
|
|||
builder: (context) {
|
||||
return Dialog(
|
||||
alignment: Alignment.center,
|
||||
child: buildDetails(
|
||||
child: buildVisitDetails(
|
||||
visitaWrapItem,
|
||||
context,
|
||||
changeStatusAction,
|
||||
|
|
|
@ -20,10 +20,21 @@ class ValidatorUtil {
|
|||
}
|
||||
|
||||
static String toISO8601(String format, String value) {
|
||||
log('value: $value');
|
||||
DateFormat dateFormat = DateFormat(format);
|
||||
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) {
|
||||
|
@ -32,4 +43,13 @@ class ValidatorUtil {
|
|||
|
||||
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
|
||||
version: "0.3.4+2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: crypto
|
||||
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
|
||||
|
@ -241,6 +241,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -97,6 +97,8 @@ dependencies:
|
|||
firebase_crashlytics: ^4.0.1
|
||||
awesome_notifications: ^0.9.3+1
|
||||
app_tracking_transparency: ^2.0.6
|
||||
dio: ^5.7.0
|
||||
crypto: ^3.0.5
|
||||
|
||||
dependency_overrides:
|
||||
http: 1.2.1
|
||||
|
|
Loading…
Reference in New Issue