This commit is contained in:
jantunesmessias 2025-02-06 11:23:55 -03:00
parent 2e378a00d4
commit 8573d722f5
58 changed files with 935 additions and 112 deletions

BIN
assets/files/document.pdf Normal file

Binary file not shown.

0
hx Normal file
View File

View File

@ -1,5 +1,4 @@
import 'dart:collection'; import 'dart:collection';
import 'dart:math';
import 'package:app_tracking_transparency/app_tracking_transparency.dart'; import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
@ -7,12 +6,9 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart'; import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart';
import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
import 'package:hub/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart';
import 'package:hub/features/backend/api_requests/index.dart'; import 'package:hub/features/backend/api_requests/index.dart';
import 'package:hub/features/local/index.dart'; import 'package:hub/features/local/index.dart';
import 'package:hub/features/menu/index.dart'; import 'package:hub/features/menu/index.dart';
@ -22,12 +18,9 @@ import 'package:hub/features/notification/index.dart';
import 'package:hub/features/storage/index.dart'; import 'package:hub/features/storage/index.dart';
import 'package:hub/flutter_flow/index.dart' as ff; import 'package:hub/flutter_flow/index.dart' as ff;
import 'package:hub/flutter_flow/index.dart'; import 'package:hub/flutter_flow/index.dart';
import 'package:hub/initialization.dart';
import 'package:hub/main.dart'; import 'package:hub/main.dart';
import 'package:hub/pages/forgot_password_page/forgot_password_screen.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:flutter_web_plugins/url_strategy.dart'; import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:patrol/patrol.dart';
import 'app_test.dart'; import 'app_test.dart';
import 'fuzzer/fuzzer.dart'; import 'fuzzer/fuzzer.dart';

View File

@ -255,10 +255,3 @@ Future<void> _submit(
_navigateBackUsingSystemGesture(); _navigateBackUsingSystemGesture();
} }
} }
String _generateRandomString(int length) {
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
final rand = Random();
return List.generate(length, (index) => chars[rand.nextInt(chars.length)])
.join();
}

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:hub/shared/utils/limited_text_size.dart';
class ToastUtil { class ToastUtil {
static void showToast({ static void showToast({

View File

@ -14,6 +14,7 @@ import 'package:hub/shared/utils/log_util.dart';
import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_theme.dart';
// ignore: must_be_immutable
class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget { class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
BottomArrowLinkedLocalsComponentWidget({super.key, required this.response}); BottomArrowLinkedLocalsComponentWidget({super.key, required this.response});
ApiCallResponse? response; ApiCallResponse? response;

View File

@ -4,7 +4,6 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:material_symbols_icons/symbols.dart';
import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart'; import '/flutter_flow/flutter_flow_util.dart';

View File

@ -60,8 +60,7 @@ class _MessageNotificationModalTemplateComponentWidgetState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context);
LimitedFontSizeUtil.getSubHeaderFontSize(context);
return Container( return Container(
width: MediaQuery.sizeOf(context).width, width: MediaQuery.sizeOf(context).width,

View File

@ -1,5 +1,3 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hub/components/templates_components/provisional_schedule_template/provisional_shcedule_template_widget.dart'; import 'package:hub/components/templates_components/provisional_schedule_template/provisional_shcedule_template_widget.dart';
import 'package:hub/features/backend/index.dart'; import 'package:hub/features/backend/index.dart';

View File

@ -15,7 +15,6 @@ import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart'; import '/flutter_flow/flutter_flow_util.dart';
import '/flutter_flow/flutter_flow_widgets.dart'; import '/flutter_flow/flutter_flow_widgets.dart';
import '/flutter_flow/form_field_controller.dart'; import '/flutter_flow/form_field_controller.dart';
import '/flutter_flow/upload_data.dart';
import 'regisiter_vistor_template_component_model.dart'; import 'regisiter_vistor_template_component_model.dart';
export 'regisiter_vistor_template_component_model.dart'; export 'regisiter_vistor_template_component_model.dart';
@ -35,7 +34,6 @@ class RegisiterVistorTemplateComponentWidget extends StatefulWidget {
class _RegisiterVistorTemplateComponentWidgetState class _RegisiterVistorTemplateComponentWidgetState
extends State<RegisiterVistorTemplateComponentWidget> { extends State<RegisiterVistorTemplateComponentWidget> {
late RegisiterVistorTemplateComponentModel _model; late RegisiterVistorTemplateComponentModel _model;
bool _isLoading = false;
final scaffoldKey = GlobalKey<ScaffoldState>(); final scaffoldKey = GlobalKey<ScaffoldState>();
bool _isVisitorRegistered = false; bool _isVisitorRegistered = false;
@ -43,10 +41,6 @@ class _RegisiterVistorTemplateComponentWidgetState
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
void _resetForm() {
_formKey.currentState?.reset();
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();

View File

@ -107,9 +107,9 @@ class _SignUpTemplateComponentWidgetState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final MediaQueryData mediaQuery = MediaQuery.of(context); // final MediaQueryData mediaQuery = MediaQuery.of(context);
final double screenWidth = mediaQuery.size.width; // final double screenWidth = mediaQuery.size.width;
final double screenHeight = mediaQuery.size.height; // final double screenHeight = mediaQuery.size.height;
double limitedHeaderFontSize = double limitedHeaderFontSize =
LimitedFontSizeUtil.getHeaderFontSize(context); LimitedFontSizeUtil.getHeaderFontSize(context);

View File

@ -1,5 +1,3 @@
import 'package:meta/meta.dart';
class DeadCode { class DeadCode {
final String? desc; final String? desc;

View File

@ -1,3 +1,5 @@
// ignore_for_file: unused_element
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:developer'; import 'dart:developer';

View File

@ -3,8 +3,6 @@
import 'package:hub/features/backend/index.dart'; import 'package:hub/features/backend/index.dart';
import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/nav/nav.dart';
import 'index.dart';
class DeviceStruct extends BaseStruct { class DeviceStruct extends BaseStruct {
DeviceStruct({ DeviceStruct({
String? devUUID, String? devUUID,

View File

@ -0,0 +1,154 @@
part of 'index.dart';
interface class Category extends Entity {
final Color color;
final String title;
Category({
required this.color,
required this.title,
});
}
interface class Document extends Entity {
final String title;
final String description;
final Category category;
final String to;
final String from;
final String createdAt;
final String updatedAt;
Document({
required this.createdAt,
required this.updatedAt,
required this.category,
required this.to,
required this.from,
required this.title,
required this.description,
});
}
class DocumentItem extends StatelessWidget {
final Document document;
const DocumentItem({Key? key, required this.document}) : super(key: key);
Tooltip _buildTooltip(String text, Color color, BuildContext context,
BoxConstraints constraints) {
final Color textColor = FlutterFlowTheme.of(context).info;
final double boxHeight = MediaQuery.of(context).size.height * 0.02;
final double boxWidth = MediaQuery.of(context).size.height * 0.1;
return Tooltip(
message: text,
child: Container(
width: boxWidth,
height: boxHeight,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: AutoText(
text,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: textColor,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
final Color primaryText = FlutterFlowTheme.of(context).primaryText;
final Color primaryColor = FlutterFlowTheme.of(context).primary;
final TextStyle textStyleMajor = TextStyle(
color: primaryText,
fontWeight: FontWeight.bold,
);
final TextStyle textStyleMinor = TextStyle(
color: primaryText,
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
);
return Padding(
padding: const EdgeInsets.all(8),
child: LayoutBuilder(
builder: (context, constraints) {
final double boxHeight = constraints.maxHeight > 350
? MediaQuery.of(context).size.height * 0.07
: MediaQuery.of(context).size.height * 2;
return InkWell(
onTap: () => print('Click'),
enableFeedback: true,
overlayColor: MaterialStateProperty.all<Color>(primaryColor),
borderRadius: BorderRadius.circular(10),
child: SizedBox(
height: boxHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// const SizedBox(width: 10),
Icon(Icons.description, color: document.category.color),
// const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Tooltip(
message: document.title,
child: AutoText(
document.title,
style: textStyleMajor,
overflow: TextOverflow.ellipsis,
),
),
AutoText(
document.updatedAt,
style: textStyleMinor,
overflow: TextOverflow.ellipsis,
),
],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
_buildTooltip(
document.category.title,
document.category.color,
context,
constraints,
),
],
),
),
// const SizedBox(width: 10),
Center(
child: Icon(
Icons.arrow_right,
color: primaryText,
),
),
],
),
),
);
},
),
);
}
}

View File

@ -0,0 +1,92 @@
part of 'index.dart';
class DocumentManagerScreen extends StatelessScreen {
DocumentManagerScreen({
super.key,
required this.documents,
required this.categories,
});
List<Document> documents;
final List<Category> categories;
@override
Widget build(BuildContext context) {
final GlobalKey<LocalSearchViewState> _listViewKey =
GlobalKey<LocalSearchViewState>();
bool filter(document, query) {
final lowerQuery = query.toLowerCase();
return document.title.toLowerCase().contains(lowerQuery) ||
document.description.toLowerCase().contains(lowerQuery) ||
document.category.title.toLowerCase().contains(lowerQuery) ||
document.to.toLowerCase().contains(lowerQuery) ||
document.from.toLowerCase().contains(lowerQuery) ||
document.createdAt.toLowerCase().contains(lowerQuery) ||
document.updatedAt.toLowerCase().contains(lowerQuery);
}
DocumentItem itemBuilder(document) => DocumentItem(document: document);
void filterByCategory(Category query) {
print('Test');
final state = _listViewKey.currentState;
if (state != null) {
state.safeSetState(() {
state.filteredItems = documents
.where((documents) => filter(documents, query.title))
.toList();
});
}
}
void unfilter(Category) {
final state = _listViewKey.currentState;
if (state != null) {
state.safeSetState(() {
state.filteredItems = documents;
});
}
}
final header = Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(15, 0, 50, 0),
child: Text('Últimos Documentos'),
),
CategoryCarousel(
categories: categories,
onSelect: filterByCategory,
onUnselect: unfilter,
),
],
);
List<Document> filterByString(String query) {
return documents.where((documents) => filter(documents, query)).toList();
}
final SizedBox space = SizedBox(height: 30);
return Column(
children: [
Expanded(
child: LocalSearchView<Document>(
key: _listViewKey,
header: header,
onSearch: filterByString,
list: documents,
itemBuilder: itemBuilder,
filter: filter,
),
),
] //
.addToStart(space)
.addToEnd(space),
);
}
}

View File

@ -0,0 +1 @@
part of 'index.dart';

View File

@ -0,0 +1,70 @@
part of 'index.dart';
List<Document> generateDocuments(int count) {
String str() => randomString(8, 8, true, true, true);
Color color() => randomColor();
return List<Document>.generate(
count,
(index) => Document(
title: 'Lorem Ipsum et Cetera $index',
description: 'Description for document $index',
category: Category(color: color(), title: str()),
to: str(),
from: str(),
createdAt: '00/00/0000',
updatedAt: '00/00/0000',
),
);
}
List<Category> generateCategories(List<Document> documents) {
final Map<String, Category> categoryMap = {};
for (var document in documents) {
final category = document.category;
if (!categoryMap.containsKey(category.title)) {
categoryMap[category.title] = category;
}
}
return categoryMap.values.toList();
}
class FREDocumentPage extends StatefulPage {
const FREDocumentPage({super.key});
@override
State<FREDocumentPage> createState() => _FREDocumentPageState();
}
class _FREDocumentPageState extends PageState<FREDocumentPage> {
@override
Widget build(BuildContext context) {
final String title = FFLocalizations.of(context)
.getVariableText(enText: 'Documents', ptText: 'Documentos');
return Scaffold(
appBar: buildAppBar(title, context),
body: buildBody(context),
);
}
late List<Document> documents;
late List<Category> categories;
@override
void initState() {
super.initState();
documents = generateDocuments(20);
categories = generateCategories(documents);
}
Widget buildBody(BuildContext context) {
return DocumentManagerScreen(
documents: documents,
categories: categories,
);
// return DocumentViewScreen(document: documents.first);
}
}

View File

@ -0,0 +1,48 @@
part of 'index.dart';
class DocumentViewScreen extends StatefulScreen {
const DocumentViewScreen({
super.key,
required this.document,
});
final Document document;
@override
State<DocumentViewScreen> createState() => _DocumentViewScreenState();
}
class _DocumentViewScreenState extends State<DocumentViewScreen> {
final PDFViewerState _viewerKey = PDFViewerState();
@override
Widget build(BuildContext context) {
return Stack(
children: [
Padding(
padding: EdgeInsets.all(10),
child: FREViewerPDF(
key: _viewerKey,
url:
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
),
),
Positioned(
bottom: 10,
right: 10,
child: IconButton(
icon: Icon(Icons.share, color: Colors.black),
color: Colors.black,
onPressed: () {
_viewerKey.currentState?.openBookmarkView();
// Share.share(FFLocalizations.of(context).getVariableText(
// ptText: '',
// enText: '',
// ));
},
),
),
],
);
}
}

View File

@ -0,0 +1,12 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:hub/flutter_flow/index.dart';
import 'package:hub/shared/utils/index.dart';
import 'package:hub/shared/widgets/widgets.dart';
part 'document_manager_screen.dart';
part 'document_page_widget.dart';
part 'document_viewer_screen.dart';
part 'document_page_model.dart';
part 'document_item_component.dart';

View File

@ -350,6 +350,7 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
); );
} }
// ignore: unused_element
String _imageUrlAtomWidget(String document, String type) { String _imageUrlAtomWidget(String document, String type) {
return valueOrDefault<String>( return valueOrDefault<String>(
"https://freaccess.com.br/freaccess/getImage.php?&cliID=&atividade=getFoto&Documento=$document&tipo=$type", "https://freaccess.com.br/freaccess/getImage.php?&cliID=&atividade=getFoto&Documento=$document&tipo=$type",
@ -404,6 +405,7 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
} }
Map<String, Color> _getStatusMap(BuildContext context, dynamic json) { Map<String, Color> _getStatusMap(BuildContext context, dynamic json) {
// ignore: unused_local_variable
late Map<String, Color> statusColorMap; late Map<String, Color> statusColorMap;
log(DateTime.parse(json['AGP_DT_VISITA']).toString()); log(DateTime.parse(json['AGP_DT_VISITA']).toString());
log(DateTime.now().toString()); log(DateTime.now().toString());

View File

@ -187,6 +187,7 @@ class _AccessFilterState extends State<AccessFilter> {
); );
} }
// ignore: unused_element
void _updateSelection(String? value, String key) { void _updateSelection(String? value, String key) {
setState(() { setState(() {
if (value == '.') { if (value == '.') {

View File

@ -1,5 +1,3 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '/flutter_flow/flutter_flow_util.dart'; import '/flutter_flow/flutter_flow_util.dart';

View File

@ -1,6 +1,5 @@
import 'dart:developer'; import 'dart:developer';
import 'package:firebase_crashlytics/firebase_crashlytics.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';
@ -8,8 +7,6 @@ import 'package:hub/flutter_flow/flutter_flow_icon_button.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';
import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/shared/utils/log_util.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';

View File

@ -136,6 +136,7 @@ class DrawerWidget extends StatelessWidget {
); );
} }
// ignore: unused_element
Padding _buildSearchBar(BuildContext context, HomeState state) { Padding _buildSearchBar(BuildContext context, HomeState state) {
final theme = FlutterFlowTheme.of(context); final theme = FlutterFlowTheme.of(context);
final errorColor = theme.error; final errorColor = theme.error;

View File

@ -58,7 +58,7 @@ class LocalsLocalDataSourceImpl implements LocalsLocalDataSource {
}, },
conflictAlgorithm: ConflictAlgorithm.replace, conflictAlgorithm: ConflictAlgorithm.replace,
); );
} catch (e, s) {} } catch (e) {}
} }
@override @override

View File

@ -41,10 +41,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
return; return;
} }
if (response.jsonBody == null) { if (response.jsonBody == null) {
final String errorMsg = FFLocalizations.of(context).getVariableText( // final String errorMsg = FFLocalizations.of(context).getVariableText(
enText: 'Verify your connection', // enText: 'Verify your connection',
ptText: 'Verifique sua conexão', // ptText: 'Verifique sua conexão',
); // );
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response)); // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
return; return;
} }
@ -82,10 +82,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
return false; return false;
} }
if (response.jsonBody == null) { if (response.jsonBody == null) {
final String errorMsg = FFLocalizations.of(context).getVariableText( // final String errorMsg = FFLocalizations.of(context).getVariableText(
enText: 'Verify your connection', // enText: 'Verify your connection',
ptText: 'Verifique sua conexão', // ptText: 'Verifique sua conexão',
); // );
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response)); // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
return false; return false;
} }
@ -140,10 +140,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
log('() => stack: $s'); log('() => stack: $s');
log('() => catch: $e', stackTrace: s); log('() => catch: $e', stackTrace: s);
// return await selectLocal(context); // return await selectLocal(context);
final String errorMsg = FFLocalizations.of(context).getVariableText( // final String errorMsg = FFLocalizations.of(context).getVariableText(
enText: 'Error getting locals, verify your connection', // enText: 'Error getting locals, verify your connection',
ptText: 'Erro ao obter locais, verifique sua conexão', // ptText: 'Erro ao obter locais, verifique sua conexão',
); // );
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null)); // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null));
return false; return false;
} }
@ -168,10 +168,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
if (response.jsonBody == null) { if (response.jsonBody == null) {
final GetLocalsCall callback = PhpGroup.getLocalsCall; final GetLocalsCall callback = PhpGroup.getLocalsCall;
response = await callback.call(); response = await callback.call();
final String errorMsg = FFLocalizations.of(context).getVariableText( // final String errorMsg = FFLocalizations.of(context).getVariableText(
enText: 'Verify your connection', // enText: 'Verify your connection',
ptText: 'Verifique sua conexão', // ptText: 'Verifique sua conexão',
); // );
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response)); // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
return false; return false;
} }
@ -180,8 +180,8 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
if (isError == true) { if (isError == true) {
final GetLocalsCall callback = PhpGroup.getLocalsCall; final GetLocalsCall callback = PhpGroup.getLocalsCall;
response = await callback.call(); response = await callback.call();
final String errorMsg = // final String errorMsg =
response.jsonBody['error_msg'] ?? 'Local indisponível'; // response.jsonBody['error_msg'] ?? 'Local indisponível';
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response)); // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
return false; return false;
} else { } else {
@ -190,10 +190,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
} }
} catch (e, s) { } catch (e, s) {
log('() => error processData: $e', stackTrace: s); log('() => error processData: $e', stackTrace: s);
final String errorMsg = FFLocalizations.of(context).getVariableText( // final String errorMsg = FFLocalizations.of(context).getVariableText(
enText: 'Error getting data, verify your connection', // enText: 'Error getting data, verify your connection',
ptText: 'Erro ao obter dados, verifique sua conexão', // ptText: 'Erro ao obter dados, verifique sua conexão',
); // );
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null)); // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null));
return false; return false;
} }

View File

@ -107,6 +107,7 @@ class LocalsRepositoryImpl implements LocalsRepository {
await DialogUtil.error(context, errorMsg); await DialogUtil.error(context, errorMsg);
} }
// ignore: unused_element
Future<void> _notifyBlocs(BuildContext context) async { Future<void> _notifyBlocs(BuildContext context) async {
context.read<LocalProfileBloc>().add(LocalProfileEvent()); context.read<LocalProfileBloc>().add(LocalProfileEvent());
context.read<MenuBloc>().add(MenuEvent()); context.read<MenuBloc>().add(MenuEvent());

View File

@ -160,6 +160,16 @@ class MenuEntry implements BaseModule {
route: '/acessHistoryPage', route: '/acessHistoryPage',
types: [MenuEntryType.Home, MenuEntryType.Drawer], types: [MenuEntryType.Home, MenuEntryType.Drawer],
), ),
MenuEntry(
key: 'FRE-HUB-DOCUMENT',
icon: Icons.document_scanner,
name: FFLocalizations.of(navigatorKey.currentContext!).getVariableText(
ptText: 'Documentos',
enText: 'Documents',
),
route: '/documentPage',
types: [MenuEntryType.Home, MenuEntryType.Drawer],
),
MenuEntry( MenuEntry(
key: 'FRE-HUB-LIBERATIONS', key: 'FRE-HUB-LIBERATIONS',
icon: Icons.how_to_reg_outlined, icon: Icons.how_to_reg_outlined,

View File

@ -76,16 +76,15 @@ class _MenuButtonWidgetState extends State<ButtonMenuItem> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (widget.icon != null) Container(
Container( alignment: Alignment.topLeft,
alignment: Alignment.topLeft, padding: const EdgeInsets.only(left: 8.0),
padding: const EdgeInsets.only(left: 8.0), child: Icon(
child: Icon( widget.icon,
widget.icon, size: 24.0,
size: 24.0, color: FlutterFlowTheme.of(context).primaryText,
color: FlutterFlowTheme.of(context).primaryText,
),
), ),
),
Flexible( Flexible(
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 10.0), padding: const EdgeInsets.only(left: 10.0),

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'module_model.dart'; import 'module_model.dart';

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
part 'module_model.freezed.dart'; part 'module_model.freezed.dart';

View File

@ -1,6 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
abstract class BaseModule { abstract class BaseModule {
String get key; String get key;

View File

@ -25,7 +25,8 @@ enum LicenseKeys {
people('FRE-HUB-PEOPLE'), people('FRE-HUB-PEOPLE'),
petsHistory('FRE-HUB-PETS-HISTORY'), petsHistory('FRE-HUB-PETS-HISTORY'),
settings('FRE-HUB-SETTINGS'), settings('FRE-HUB-SETTINGS'),
logout('FRE-HUB-LOGOUT'); logout('FRE-HUB-LOGOUT'),
document('FRE-HUB-DOCUMENT');
final String value; final String value;
const LicenseKeys(this.value); const LicenseKeys(this.value);
@ -137,6 +138,13 @@ class License {
startDate: '', startDate: '',
quantity: 0, quantity: 0,
), ),
Module(
key: LicenseKeys.document.value,
display: ModuleStatus.active.key,
expirationDate: '',
startDate: '',
quantity: 0,
),
Module( Module(
key: LicenseKeys.openedVisits.value, key: LicenseKeys.openedVisits.value,
display: isNewVersionWithModule display: isNewVersionWithModule

View File

@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'package:app_links/app_links.dart'; import 'package:app_links/app_links.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hub/features/storage/index.dart'; import 'package:hub/features/storage/index.dart';

View File

@ -2,7 +2,6 @@ import 'dart:developer';
import 'package:hub/features/storage/constants/profile_constants.dart'; import 'package:hub/features/storage/constants/profile_constants.dart';
import 'package:hub/features/storage/index.dart'; import 'package:hub/features/storage/index.dart';
import 'package:hub/shared/constants/index.dart';
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';

View File

@ -9,8 +9,6 @@ extension SharedPreferencesKeyExtension on SharedPreferencesKey {
switch (this) { switch (this) {
case SharedPreferencesKey.isFirstRun: case SharedPreferencesKey.isFirstRun:
return 'fre_isFirstRun'; return 'fre_isFirstRun';
default:
return '';
} }
} }
} }

View File

@ -1,7 +1,6 @@
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:hub/features/profile/data/data_sources/profile_local_data_source.dart';
import 'package:hub/features/storage/index.dart'; import 'package:hub/features/storage/index.dart';
class StorageHelper implements StorageRepository { class StorageHelper implements StorageRepository {

View File

@ -1,6 +1,5 @@
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:auto_size_text/auto_size_text.dart';
class FFButtonOptions { class FFButtonOptions {
const FFButtonOptions({ const FFButtonOptions({

View File

@ -4,6 +4,7 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hub/features/backend/index.dart'; import 'package:hub/features/backend/index.dart';
import 'package:hub/features/documents/index.dart';
import 'package:hub/features/history/index.dart'; import 'package:hub/features/history/index.dart';
import 'package:hub/features/home/index.dart'; import 'package:hub/features/home/index.dart';
import 'package:hub/features/local/index.dart'; import 'package:hub/features/local/index.dart';
@ -298,6 +299,13 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
return PetsPageWidget(pet: pet); return PetsPageWidget(pet: pet);
}, },
), ),
FFRoute(
name: 'documentPage',
path: '/documentPage',
builder: (context, params) {
return FREDocumentPage();
},
),
// FFRoute(name: 'settingsPage', path: '/settingsPage', builder: (context, params) => params.isEmpty ? const NavBarPage(initialPage: 'settingsPage') : const SettingsPageWidget()) // FFRoute(name: 'settingsPage', path: '/settingsPage', builder: (context, params) => params.isEmpty ? const NavBarPage(initialPage: 'settingsPage') : const SettingsPageWidget())
].map((r) => r.toRoute(appStateNotifier)).toList(), ].map((r) => r.toRoute(appStateNotifier)).toList(),
); );

View File

@ -218,9 +218,6 @@ dynamic deserializeParam<T>(
case ParamType.Enum: case ParamType.Enum:
return deserializeEnum<T>(param); return deserializeEnum<T>(param);
default:
return null;
} }
} catch (e) { } catch (e) {
return null; return null;

View File

@ -1,5 +1,3 @@
import 'dart:developer';
import 'package:app_tracking_transparency/app_tracking_transparency.dart'; import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart';
@ -56,21 +54,21 @@ Future<void> _initializeSystemSettings() async {
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
if (kDebugMode) { if (kDebugMode) {
//kDebugMode
print('Debug mode'); print('Debug mode');
bool unsentReports =
await FirebaseCrashlytics.instance.checkForUnsentReports();
if (unsentReports) {
// Existem relatórios não enviados
await crashlyticsInstance.sendUnsentReports();
print('Existem relatórios de falhas não enviados.');
} else {
// Não existem relatórios não enviados
print('Todos os relatórios de falhas foram enviados.');
}
} else { } else {
print('Release mode'); print('Release mode');
// bool unsentReports =
// await FirebaseCrashlytics.instance.checkForUnsentReports();
// if (unsentReports) {
// // Existem relatórios não enviados
// await crashlyticsInstance.sendUnsentReports();
// print('Existem relatórios de falhas não enviados.');
// } else {
// // Não existem relatórios não enviados
// print('Todos os relatórios de falhas foram enviados.');
// }
await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); await crashlyticsInstance.setCrashlyticsCollectionEnabled(true);
// if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { // if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
FlutterError.onError = await crashlyticsInstance.recordFlutterError; FlutterError.onError = await crashlyticsInstance.recordFlutterError;

View File

@ -6,6 +6,7 @@ import 'dart:io';
import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -14,13 +15,21 @@ import 'package:hub/features/storage/index.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/shared/utils/test_util.dart';
import 'package:responsive_framework/responsive_framework.dart'; import 'package:responsive_framework/responsive_framework.dart';
import 'initialization.dart'; import 'initialization.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
class CustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
void main() async { void main() async {
await initializeApp(); await initializeApp();
runApp(const ProviderScope(child: App())); runApp(const ProviderScope(child: App()));
@ -193,6 +202,7 @@ class _AppState extends State<App> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp.router( return MaterialApp.router(
scrollBehavior: CustomScrollBehavior(),
key: navigatorKey, key: navigatorKey,
title: 'FRE ACCESS HUB', title: 'FRE ACCESS HUB',
builder: builder, builder: builder,

View File

@ -103,8 +103,7 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
screenWidth < screenHeight ? screenWidth : screenHeight; screenWidth < screenHeight ? screenWidth : screenHeight;
double dimension = smallerDimension * 0.75; double dimension = smallerDimension * 0.75;
double totalTimeInSeconds = 100.0; double totalTimeInSeconds = 100.0;
double limitedHeaderTextSize = LimitedFontSizeUtil.getCalculateFontSize(context, 18, 18, 16);
LimitedFontSizeUtil.getCalculateFontSize(context, 18, 18, 16);
double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
return SafeArea( return SafeArea(

View File

@ -1,6 +1,3 @@
import 'dart:developer';
import 'package:awesome_notifications/awesome_notifications.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';
@ -31,9 +28,7 @@ class _ReceptionPageWidgetState extends State<ReceptionPageWidget>
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
() async { () async {}();
final lifecycle = await AwesomeNotifications().getAppLifeCycle();
}();
FirebaseMessagingService().updateDeviceToken(); FirebaseMessagingService().updateDeviceToken();
LocalsRepositoryImpl().validateLocal(context); LocalsRepositoryImpl().validateLocal(context);

View File

@ -90,6 +90,7 @@ class _ScheduleCompleteVisitPageWidgetState
} }
} }
// ignore: unused_element
void _scrollListener() { void _scrollListener() {
if (_visitHistoryController.position.pixels == if (_visitHistoryController.position.pixels ==
_visitHistoryController.position.maxScrollExtent) { _visitHistoryController.position.maxScrollExtent) {

View File

@ -54,8 +54,8 @@ class _VisitsOnThePropertyState extends State<VisitsOnTheProperty>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
late final limitedBodyTextSize = // late final limitedBodyTextSize =
LimitedFontSizeUtil.getBodyFontSize(context); // LimitedFontSizeUtil.getBodyFontSize(context);
late final limitedHeaderTextSize = late final limitedHeaderTextSize =
LimitedFontSizeUtil.getHeaderFontSize(context); LimitedFontSizeUtil.getHeaderFontSize(context);

View File

@ -0,0 +1,22 @@
part of 'widgets.dart';
/// [ComponentWidget]
abstract class ComponentWidget<T> extends Widget {
const ComponentWidget({super.key});
}
abstract class ModelComponent<T> extends ModelWidget
implements ComponentWidget<T> {
const ModelComponent({super.key});
}
abstract class StatelessComponent<T> extends StatelessWidget
implements ComponentWidget<T> {
const StatelessComponent({super.key});
}
abstract class StatefulComponent<T> extends StatefulWidget
implements ComponentWidget<T> {
const StatefulComponent({super.key});
}

View File

@ -0,0 +1,3 @@
part of 'widgets.dart';
abstract class Entity<T> {}

View File

@ -0,0 +1,11 @@
part of 'widgets.dart';
class ModelWidget extends Widget {
const ModelWidget({super.key});
@override
Element createElement() {
// TODO: implement createElement
throw UnimplementedError();
}
}

View File

@ -0,0 +1,64 @@
part of 'widgets.dart';
mixin MixinPage {
PreferredSizeWidget buildAppBar(String title, BuildContext context) {
return AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
automaticallyImplyLeading: false,
title: Text(
title,
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 16.0,
fontWeight: FontWeight.bold,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(
FlutterFlowTheme.of(context).headlineMediumFamily),
),
),
leading: _backButton(context, FlutterFlowTheme.of(context)),
centerTitle: true,
elevation: 0.0,
actions: [],
);
}
Widget _backButton(BuildContext context, FlutterFlowTheme theme) {
return FlutterFlowIconButton(
key: ValueKey<String>('BackNavigationAppBar'),
borderColor: Colors.transparent,
borderRadius: 30.0,
borderWidth: 1.0,
buttonSize: 60.0,
icon: Icon(
Icons.keyboard_arrow_left,
color: theme.primaryText,
size: 30.0,
),
onPressed: () => Navigator.of(context).pop(),
);
}
}
/// [PageWidget]
abstract class PageWidget<T> extends Widget {
const PageWidget({super.key});
}
abstract class ModelPage<T> extends ModelWidget implements PageWidget<T> {
const ModelPage({super.key});
}
abstract class StatelessPage<T> extends StatelessWidget
implements PageWidget<T> {
const StatelessPage({super.key});
}
abstract class StatefulPage<T> extends StatefulWidget implements PageWidget<T> {
const StatefulPage({super.key});
}
abstract class PageState<T extends StatefulPage> extends State<T>
with MixinPage {}

View File

@ -0,0 +1,19 @@
part of 'widgets.dart';
abstract class ScreenWidget<T> extends Widget {
const ScreenWidget({super.key});
}
abstract class ModelScreen<T> extends ModelWidget implements ScreenWidget<T> {
const ModelScreen({super.key});
}
abstract class StatelessScreen<T> extends StatelessWidget
implements ScreenWidget<T> {
const StatelessScreen({super.key});
}
abstract class StatefulScreen<T> extends StatefulWidget
implements ScreenWidget<T> {
const StatefulScreen({super.key});
}

View File

@ -0,0 +1,12 @@
part of 'widgets.dart';
class AutoText extends AutoSizeText {
const AutoText(
super.text, {
super.key,
super.style,
super.overflow,
super.textAlign,
super.maxLines,
});
}

View File

@ -0,0 +1,77 @@
part of '../widgets.dart';
class CategoryCarousel extends StatelessWidget {
final List<Category> categories;
final void Function(Category) onSelect;
final void Function(Category) onUnselect;
const CategoryCarousel({
super.key,
required this.categories,
required this.onSelect,
required this.onUnselect,
});
@override
Widget build(BuildContext context) {
final backgroundTheme = FlutterFlowTheme.of(context).primaryBackground;
bool isSelected = false;
Category? current = null;
return Container(
height: 120,
decoration: BoxDecoration(
color: backgroundTheme,
borderRadius: BorderRadius.circular(10),
),
child: CarouselView(
itemExtent: 100,
onTap: (index) {
if (isSelected && current == categories[index]) {
onUnselect(categories[index]);
isSelected = false;
current = null;
} else {
onSelect(categories[index]);
isSelected = true;
current = categories[index];
}
},
children: categories.map((category) {
return GestureDetector(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: category.color,
shape: BoxShape.circle,
),
child: Icon(
Icons.folder,
color: Colors.white,
size: 40,
),
),
const SizedBox(height: 8),
Text(
category.title,
style: TextStyle(
color: category.color,
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
),
],
),
),
);
}).toList(),
),
);
}
}

View File

@ -0,0 +1,200 @@
part of '../widgets.dart';
/// -----------------------------------------------
/// [SearchView]
class SearchView<T> extends StatefulComponent {
const SearchView({super.key});
@override
State<SearchView> createState() => _SearchViewState();
}
class _SearchViewState<T> extends State<SearchView> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
class LocalSearchView<T> extends SearchView<T> {
final List<T> list;
final Widget Function(T) itemBuilder;
final bool Function(T, String) filter;
final Widget header;
final List<T> Function(String)? onSearch;
LocalSearchView({
Key? key,
required this.list,
required this.itemBuilder,
required this.filter,
List<T> Function(String)? onSearch,
Widget? header,
}) : header = header ?? const SizedBox.shrink(),
onSearch = onSearch ??
((String query) =>
list.where((documents) => filter(documents, query)).toList()),
super(key: key);
// return documents.where((documents) => filter(documents, query)).toList();
@override
LocalSearchViewState<T> createState() => LocalSearchViewState<T>();
}
class LocalSearchViewState<T> extends State<LocalSearchView<T>> {
TextEditingController editingController = TextEditingController();
late List<T> filteredItems;
@override
void initState() {
filteredItems = widget.list;
super.initState();
}
@override
Widget build(BuildContext context) {
void filter(value) {
safeSetState(() {
filteredItems = widget.onSearch!(value);
});
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: filteredItems.length + 1,
itemBuilder: (context, index) {
if (index == 0) return widget.header;
return widget.itemBuilder(filteredItems[index - 1]);
},
),
),
Padding(
padding: const EdgeInsets.all(30.0),
child: TextField(
onChanged: filter,
controller: editingController,
cursorColor: Colors.black,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
focusColor: Colors.black,
hoverColor: Colors.black,
fillColor: Colors.black,
iconColor: Colors.black,
contentPadding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(15.0)),
borderSide:
BorderSide(color: Colors.black), // Set border color here
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(15.0)),
borderSide: BorderSide(
color: Colors.black), // Set focused border color here
),
),
),
),
],
);
}
}
class RemoteSearchListView<T> extends SearchView<T> {
final List<T> items;
final String title;
final Widget Function(T) itemBuilder;
final Future<List<T>> Function(String) fetchItems;
RemoteSearchListView({
Key? key,
required this.items,
required this.title,
required this.itemBuilder,
required this.fetchItems,
}) : super(key: key);
@override
_RemoteSearchViewState<T> createState() => _RemoteSearchViewState<T>();
}
class _RemoteSearchViewState<T> extends State<RemoteSearchListView<T>> {
TextEditingController editingController = TextEditingController();
late List<T> filteredItems;
bool isLoading = false;
@override
void initState() {
filteredItems = widget.items;
super.initState();
}
void filterSearchResults(String query) async {
setState(() {
isLoading = true;
});
final results = await widget.fetchItems(query);
setState(() {
filteredItems = results;
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: (value) {
filterSearchResults(value);
},
controller: editingController,
decoration: InputDecoration(
labelText: "Search",
hintText: "Search",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(25.0)),
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(15, 0, 50, 0),
child: Text('Últimos Documentos'),
),
isLoading
? Center(child: CircularProgressIndicator())
: Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: filteredItems.length,
itemBuilder: (context, index) {
return widget.itemBuilder(filteredItems[index]);
},
),
),
],
),
),
);
}
}

View File

@ -0,0 +1,26 @@
part of '../widgets.dart';
typedef PDFViewerState = GlobalKey<SfPdfViewerState>;
abstract class Viewer extends StatelessComponent {
const Viewer({super.key, required this.src});
final String src;
@override
Widget build(BuildContext context) {
return buildViewer(context);
}
Widget buildViewer(BuildContext context);
}
class FREViewerPDF extends Viewer {
const FREViewerPDF({required Key key, required this.url})
: super(key: key as PDFViewerState, src: url);
final String url;
@override
Widget buildViewer(BuildContext context) {
return SfPdfViewer.network(src, key: key as PDFViewerState);
}
}

View File

@ -0,0 +1,21 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/features/documents/index.dart';
import 'package:hub/flutter_flow/index.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
part 'page.dart';
part 'component.dart';
part 'screen.dart';
part 'model.dart';
part 'entity.dart';
/// [View]'s
part 'view/search_view.dart';
part 'view/carousel_view.dart';
/// [Viewer]
part 'viewer/viewer.dart';
part 'text.dart';

View File

@ -13,7 +13,8 @@ dependencies:
sdk: flutter sdk: flutter
flutter_localizations: flutter_localizations:
sdk: flutter sdk: flutter
auto_size_text: 3.0.0 auto_size_text: ^3.0.0
syncfusion_flutter_pdfviewer: ^28.2.4
barcode_widget: ^2.0.4 barcode_widget: ^2.0.4
cached_network_image: ^3.4.0 cached_network_image: ^3.4.0
firebase_core: ^3.4.0 firebase_core: ^3.4.0
@ -24,7 +25,7 @@ dependencies:
app_links: ^6.3.2 app_links: ^6.3.2
# crop_your_image: 1.1.0 # crop_your_image: 1.1.0
csv: 6.0.0 csv: 6.0.0
device_info_plus: ^10.1.2 device_info_plus: ^11.2.2
firebase_messaging: ^15.1.0 firebase_messaging: ^15.1.0
dropdown_button2: 2.3.9 dropdown_button2: 2.3.9
easy_debounce: 2.0.3 easy_debounce: 2.0.3
@ -50,7 +51,7 @@ dependencies:
from_css_color: 2.0.0 from_css_color: 2.0.0
go_router: ^14.3.0 go_router: ^14.3.0
google_fonts: 6.2.1 google_fonts: 6.2.1
http: 1.2.1 http: 1.3.0
image_picker: 1.1.2 image_picker: 1.1.2
image_picker_android: ^0.8.12+15 image_picker_android: ^0.8.12+15
image_picker_for_web: ^3.0.5 image_picker_for_web: ^3.0.5
@ -106,7 +107,7 @@ dependencies:
# json_annotation: ^4.9.0 # json_annotation: ^4.9.0
dependency_overrides: dependency_overrides:
http: 1.2.1 http: 1.3.0
uuid: ^4.0.0 uuid: ^4.0.0
win32: 5.5.1 win32: 5.5.1
@ -145,6 +146,7 @@ flutter:
- assets/images/ - assets/images/
- assets/images/dark/ - assets/images/dark/
- assets/images/light/ - assets/images/light/
- assets/files/
fonts: fonts:
- family: "SF Pro" - family: "SF Pro"
fonts: fonts: