WIP
This commit is contained in:
parent
2e378a00d4
commit
8573d722f5
Binary file not shown.
|
@ -1,5 +1,4 @@
|
|||
import 'dart:collection';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:app_tracking_transparency/app_tracking_transparency.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/material.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/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/forgot_password_template_component/forgot_password_template_component_widget.dart';
|
||||
import 'package:hub/features/backend/api_requests/index.dart';
|
||||
import 'package:hub/features/local/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/flutter_flow/index.dart' as ff;
|
||||
import 'package:hub/flutter_flow/index.dart';
|
||||
import 'package:hub/initialization.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:flutter_web_plugins/url_strategy.dart';
|
||||
import 'package:patrol/patrol.dart';
|
||||
|
||||
import 'app_test.dart';
|
||||
import 'fuzzer/fuzzer.dart';
|
||||
|
|
|
@ -255,10 +255,3 @@ Future<void> _submit(
|
|||
_navigateBackUsingSystemGesture();
|
||||
}
|
||||
}
|
||||
|
||||
String _generateRandomString(int length) {
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
final rand = Random();
|
||||
return List.generate(length, (index) => chars[rand.nextInt(chars.length)])
|
||||
.join();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
|
||||
class ToastUtil {
|
||||
static void showToast({
|
||||
|
|
|
@ -14,6 +14,7 @@ import 'package:hub/shared/utils/log_util.dart';
|
|||
|
||||
import '/flutter_flow/flutter_flow_theme.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
|
||||
BottomArrowLinkedLocalsComponentWidget({super.key, required this.response});
|
||||
ApiCallResponse? response;
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:cached_network_image/cached_network_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.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_util.dart';
|
||||
|
|
|
@ -60,8 +60,7 @@ class _MessageNotificationModalTemplateComponentWidgetState
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
double limitedSubHeaderFontSize =
|
||||
LimitedFontSizeUtil.getSubHeaderFontSize(context);
|
||||
LimitedFontSizeUtil.getSubHeaderFontSize(context);
|
||||
|
||||
return Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/components/templates_components/provisional_schedule_template/provisional_shcedule_template_widget.dart';
|
||||
import 'package:hub/features/backend/index.dart';
|
||||
|
|
|
@ -15,7 +15,6 @@ import '/flutter_flow/flutter_flow_theme.dart';
|
|||
import '/flutter_flow/flutter_flow_util.dart';
|
||||
import '/flutter_flow/flutter_flow_widgets.dart';
|
||||
import '/flutter_flow/form_field_controller.dart';
|
||||
import '/flutter_flow/upload_data.dart';
|
||||
import 'regisiter_vistor_template_component_model.dart';
|
||||
|
||||
export 'regisiter_vistor_template_component_model.dart';
|
||||
|
@ -35,7 +34,6 @@ class RegisiterVistorTemplateComponentWidget extends StatefulWidget {
|
|||
class _RegisiterVistorTemplateComponentWidgetState
|
||||
extends State<RegisiterVistorTemplateComponentWidget> {
|
||||
late RegisiterVistorTemplateComponentModel _model;
|
||||
bool _isLoading = false;
|
||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
bool _isVisitorRegistered = false;
|
||||
|
@ -43,10 +41,6 @@ class _RegisiterVistorTemplateComponentWidgetState
|
|||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
void _resetForm() {
|
||||
_formKey.currentState?.reset();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
|
@ -107,9 +107,9 @@ class _SignUpTemplateComponentWidgetState
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final MediaQueryData mediaQuery = MediaQuery.of(context);
|
||||
final double screenWidth = mediaQuery.size.width;
|
||||
final double screenHeight = mediaQuery.size.height;
|
||||
// final MediaQueryData mediaQuery = MediaQuery.of(context);
|
||||
// final double screenWidth = mediaQuery.size.width;
|
||||
// final double screenHeight = mediaQuery.size.height;
|
||||
|
||||
double limitedHeaderFontSize =
|
||||
LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'package:meta/meta.dart';
|
||||
|
||||
class DeadCode {
|
||||
final String? desc;
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: unused_element
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
import 'package:hub/features/backend/index.dart';
|
||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
|
||||
import 'index.dart';
|
||||
|
||||
class DeviceStruct extends BaseStruct {
|
||||
DeviceStruct({
|
||||
String? devUUID,
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
part of 'index.dart';
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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: '',
|
||||
// ));
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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';
|
|
@ -350,6 +350,7 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
|
|||
);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
String _imageUrlAtomWidget(String document, String type) {
|
||||
return valueOrDefault<String>(
|
||||
"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) {
|
||||
// ignore: unused_local_variable
|
||||
late Map<String, Color> statusColorMap;
|
||||
log(DateTime.parse(json['AGP_DT_VISITA']).toString());
|
||||
log(DateTime.now().toString());
|
||||
|
|
|
@ -187,6 +187,7 @@ class _AccessFilterState extends State<AccessFilter> {
|
|||
);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
void _updateSelection(String? value, String key) {
|
||||
setState(() {
|
||||
if (value == '.') {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '/flutter_flow/flutter_flow_util.dart';
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.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_util.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:url_launcher/url_launcher.dart';
|
||||
|
|
|
@ -136,6 +136,7 @@ class DrawerWidget extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
Padding _buildSearchBar(BuildContext context, HomeState state) {
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final errorColor = theme.error;
|
||||
|
|
|
@ -58,7 +58,7 @@ class LocalsLocalDataSourceImpl implements LocalsLocalDataSource {
|
|||
},
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
} catch (e, s) {}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -41,10 +41,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
return;
|
||||
}
|
||||
if (response.jsonBody == null) {
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Verify your connection',
|
||||
ptText: 'Verifique sua conexão',
|
||||
);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Verify your connection',
|
||||
// ptText: 'Verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
||||
return;
|
||||
}
|
||||
|
@ -82,10 +82,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
return false;
|
||||
}
|
||||
if (response.jsonBody == null) {
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Verify your connection',
|
||||
ptText: 'Verifique sua conexão',
|
||||
);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Verify your connection',
|
||||
// ptText: 'Verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
||||
return false;
|
||||
}
|
||||
|
@ -140,10 +140,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
log('() => stack: $s');
|
||||
log('() => catch: $e', stackTrace: s);
|
||||
// return await selectLocal(context);
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error getting locals, verify your connection',
|
||||
ptText: 'Erro ao obter locais, verifique sua conexão',
|
||||
);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Error getting locals, verify your connection',
|
||||
// ptText: 'Erro ao obter locais, verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null));
|
||||
return false;
|
||||
}
|
||||
|
@ -168,10 +168,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
if (response.jsonBody == null) {
|
||||
final GetLocalsCall callback = PhpGroup.getLocalsCall;
|
||||
response = await callback.call();
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Verify your connection',
|
||||
ptText: 'Verifique sua conexão',
|
||||
);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Verify your connection',
|
||||
// ptText: 'Verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
||||
return false;
|
||||
}
|
||||
|
@ -180,8 +180,8 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
if (isError == true) {
|
||||
final GetLocalsCall callback = PhpGroup.getLocalsCall;
|
||||
response = await callback.call();
|
||||
final String errorMsg =
|
||||
response.jsonBody['error_msg'] ?? 'Local indisponível';
|
||||
// final String errorMsg =
|
||||
// response.jsonBody['error_msg'] ?? 'Local indisponível';
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
||||
return false;
|
||||
} else {
|
||||
|
@ -190,10 +190,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
}
|
||||
} catch (e, s) {
|
||||
log('() => error processData: $e', stackTrace: s);
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error getting data, verify your connection',
|
||||
ptText: 'Erro ao obter dados, verifique sua conexão',
|
||||
);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Error getting data, verify your connection',
|
||||
// ptText: 'Erro ao obter dados, verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@ class LocalsRepositoryImpl implements LocalsRepository {
|
|||
await DialogUtil.error(context, errorMsg);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
Future<void> _notifyBlocs(BuildContext context) async {
|
||||
context.read<LocalProfileBloc>().add(LocalProfileEvent());
|
||||
context.read<MenuBloc>().add(MenuEvent());
|
||||
|
|
|
@ -160,6 +160,16 @@ class MenuEntry implements BaseModule {
|
|||
route: '/acessHistoryPage',
|
||||
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(
|
||||
key: 'FRE-HUB-LIBERATIONS',
|
||||
icon: Icons.how_to_reg_outlined,
|
||||
|
|
|
@ -76,16 +76,15 @@ class _MenuButtonWidgetState extends State<ButtonMenuItem> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (widget.icon != null)
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: Icon(
|
||||
widget.icon,
|
||||
size: 24.0,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
),
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: Icon(
|
||||
widget.icon,
|
||||
size: 24.0,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 10.0),
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'module_model.dart';
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'module_model.freezed.dart';
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/flutter_flow/internationalization.dart';
|
||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||
|
||||
abstract class BaseModule {
|
||||
String get key;
|
||||
|
|
|
@ -25,7 +25,8 @@ enum LicenseKeys {
|
|||
people('FRE-HUB-PEOPLE'),
|
||||
petsHistory('FRE-HUB-PETS-HISTORY'),
|
||||
settings('FRE-HUB-SETTINGS'),
|
||||
logout('FRE-HUB-LOGOUT');
|
||||
logout('FRE-HUB-LOGOUT'),
|
||||
document('FRE-HUB-DOCUMENT');
|
||||
|
||||
final String value;
|
||||
const LicenseKeys(this.value);
|
||||
|
@ -137,6 +138,13 @@ class License {
|
|||
startDate: '',
|
||||
quantity: 0,
|
||||
),
|
||||
Module(
|
||||
key: LicenseKeys.document.value,
|
||||
display: ModuleStatus.active.key,
|
||||
expirationDate: '',
|
||||
startDate: '',
|
||||
quantity: 0,
|
||||
),
|
||||
Module(
|
||||
key: LicenseKeys.openedVisits.value,
|
||||
display: isNewVersionWithModule
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
import 'package:app_links/app_links.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:developer';
|
|||
|
||||
import 'package:hub/features/storage/constants/profile_constants.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:hub/shared/constants/index.dart';
|
||||
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@ extension SharedPreferencesKeyExtension on SharedPreferencesKey {
|
|||
switch (this) {
|
||||
case SharedPreferencesKey.isFirstRun:
|
||||
return 'fre_isFirstRun';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:developer';
|
||||
|
||||
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';
|
||||
|
||||
class StorageHelper implements StorageRepository {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
|
||||
class FFButtonOptions {
|
||||
const FFButtonOptions({
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:io';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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/home/index.dart';
|
||||
import 'package:hub/features/local/index.dart';
|
||||
|
@ -298,6 +299,13 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
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())
|
||||
].map((r) => r.toRoute(appStateNotifier)).toList(),
|
||||
);
|
||||
|
|
|
@ -218,9 +218,6 @@ dynamic deserializeParam<T>(
|
|||
|
||||
case ParamType.Enum:
|
||||
return deserializeEnum<T>(param);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
return null;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
|
@ -56,21 +54,21 @@ Future<void> _initializeSystemSettings() async {
|
|||
|
||||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
if (kDebugMode) {
|
||||
//kDebugMode
|
||||
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 {
|
||||
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);
|
||||
// if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
|
||||
FlutterError.onError = await crashlyticsInstance.recordFlutterError;
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.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/internationalization.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 'initialization.dart';
|
||||
|
||||
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 {
|
||||
await initializeApp();
|
||||
runApp(const ProviderScope(child: App()));
|
||||
|
@ -193,6 +202,7 @@ class _AppState extends State<App> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp.router(
|
||||
scrollBehavior: CustomScrollBehavior(),
|
||||
key: navigatorKey,
|
||||
title: 'FRE ACCESS HUB',
|
||||
builder: builder,
|
||||
|
|
|
@ -103,8 +103,7 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
|||
screenWidth < screenHeight ? screenWidth : screenHeight;
|
||||
double dimension = smallerDimension * 0.75;
|
||||
double totalTimeInSeconds = 100.0;
|
||||
double limitedHeaderTextSize =
|
||||
LimitedFontSizeUtil.getCalculateFontSize(context, 18, 18, 16);
|
||||
LimitedFontSizeUtil.getCalculateFontSize(context, 18, 18, 16);
|
||||
double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
|
||||
return SafeArea(
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:awesome_notifications/awesome_notifications.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
|
@ -31,9 +28,7 @@ class _ReceptionPageWidgetState extends State<ReceptionPageWidget>
|
|||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
() async {
|
||||
final lifecycle = await AwesomeNotifications().getAppLifeCycle();
|
||||
}();
|
||||
() async {}();
|
||||
|
||||
FirebaseMessagingService().updateDeviceToken();
|
||||
LocalsRepositoryImpl().validateLocal(context);
|
||||
|
|
|
@ -90,6 +90,7 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
}
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
void _scrollListener() {
|
||||
if (_visitHistoryController.position.pixels ==
|
||||
_visitHistoryController.position.maxScrollExtent) {
|
||||
|
|
|
@ -54,8 +54,8 @@ class _VisitsOnThePropertyState extends State<VisitsOnTheProperty>
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
late final limitedBodyTextSize =
|
||||
LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
// late final limitedBodyTextSize =
|
||||
// LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
late final limitedHeaderTextSize =
|
||||
LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||
|
||||
|
|
|
@ -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});
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
part of 'widgets.dart';
|
||||
|
||||
abstract class Entity<T> {}
|
|
@ -0,0 +1,11 @@
|
|||
part of 'widgets.dart';
|
||||
|
||||
class ModelWidget extends Widget {
|
||||
const ModelWidget({super.key});
|
||||
|
||||
@override
|
||||
Element createElement() {
|
||||
// TODO: implement createElement
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
|
@ -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 {}
|
|
@ -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});
|
||||
}
|
|
@ -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,
|
||||
});
|
||||
}
|
|
@ -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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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]);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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';
|
10
pubspec.yaml
10
pubspec.yaml
|
@ -13,7 +13,8 @@ dependencies:
|
|||
sdk: flutter
|
||||
flutter_localizations:
|
||||
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
|
||||
cached_network_image: ^3.4.0
|
||||
firebase_core: ^3.4.0
|
||||
|
@ -24,7 +25,7 @@ dependencies:
|
|||
app_links: ^6.3.2
|
||||
# crop_your_image: 1.1.0
|
||||
csv: 6.0.0
|
||||
device_info_plus: ^10.1.2
|
||||
device_info_plus: ^11.2.2
|
||||
firebase_messaging: ^15.1.0
|
||||
dropdown_button2: 2.3.9
|
||||
easy_debounce: 2.0.3
|
||||
|
@ -50,7 +51,7 @@ dependencies:
|
|||
from_css_color: 2.0.0
|
||||
go_router: ^14.3.0
|
||||
google_fonts: 6.2.1
|
||||
http: 1.2.1
|
||||
http: 1.3.0
|
||||
image_picker: 1.1.2
|
||||
image_picker_android: ^0.8.12+15
|
||||
image_picker_for_web: ^3.0.5
|
||||
|
@ -106,7 +107,7 @@ dependencies:
|
|||
# json_annotation: ^4.9.0
|
||||
|
||||
dependency_overrides:
|
||||
http: 1.2.1
|
||||
http: 1.3.0
|
||||
uuid: ^4.0.0
|
||||
win32: 5.5.1
|
||||
|
||||
|
@ -145,6 +146,7 @@ flutter:
|
|||
- assets/images/
|
||||
- assets/images/dark/
|
||||
- assets/images/light/
|
||||
- assets/files/
|
||||
fonts:
|
||||
- family: "SF Pro"
|
||||
fonts:
|
||||
|
|
Loading…
Reference in New Issue