diff --git a/assets/fonts/Roboto-Black.ttf b/assets/fonts/Roboto-Black.ttf new file mode 100644 index 0000000..71f01ac Binary files /dev/null and b/assets/fonts/Roboto-Black.ttf differ diff --git a/assets/fonts/Roboto-Bold.ttf b/assets/fonts/Roboto-Bold.ttf new file mode 100644 index 0000000..aaf374d Binary files /dev/null and b/assets/fonts/Roboto-Bold.ttf differ diff --git a/assets/fonts/Roboto-Light.ttf b/assets/fonts/Roboto-Light.ttf new file mode 100644 index 0000000..664e1b2 Binary files /dev/null and b/assets/fonts/Roboto-Light.ttf differ diff --git a/assets/fonts/Roboto-Medium.ttf b/assets/fonts/Roboto-Medium.ttf new file mode 100644 index 0000000..aa00de0 Binary files /dev/null and b/assets/fonts/Roboto-Medium.ttf differ diff --git a/assets/fonts/Roboto-Regular.ttf b/assets/fonts/Roboto-Regular.ttf new file mode 100644 index 0000000..3e6e2e7 Binary files /dev/null and b/assets/fonts/Roboto-Regular.ttf differ diff --git a/assets/fonts/Roboto-Thin.ttf b/assets/fonts/Roboto-Thin.ttf new file mode 100644 index 0000000..d262d14 Binary files /dev/null and b/assets/fonts/Roboto-Thin.ttf differ diff --git a/lib/core/providers/home_provider.dart b/lib/core/providers/home_provider.dart index 01a37d1..9d142c9 100644 --- a/lib/core/providers/home_provider.dart +++ b/lib/core/providers/home_provider.dart @@ -9,6 +9,7 @@ import '../../view_models/home_view_model.dart'; /// Wraps screens that need HomeViewModel Widget homeProvider({required Widget child}) { return ChangeNotifierProvider( + lazy: true, create: (context) => HomeViewModel( homeRepository: context.read(), diff --git a/lib/data/services/tenders_service.dart b/lib/data/services/tenders_service.dart index 1c1c668..703813b 100644 --- a/lib/data/services/tenders_service.dart +++ b/lib/data/services/tenders_service.dart @@ -37,6 +37,7 @@ class TendersService { method: 'GET', (json) => TendersResponse.fromJson(json), ); + print(result); return result; } diff --git a/lib/view_models/home_view_model.dart b/lib/view_models/home_view_model.dart index d6940bf..a157e46 100644 --- a/lib/view_models/home_view_model.dart +++ b/lib/view_models/home_view_model.dart @@ -159,7 +159,7 @@ class HomeViewModel with ChangeNotifier { ); _currentPage++; - if (metadata != null && (_currentPage >= metadata.pages!)) { + if (metadata != null && (_currentPage >= (metadata.pages ?? 0))) { _hasMore = false; } } else { diff --git a/lib/views/home/pages/d_home_page.dart b/lib/views/home/pages/d_home_page.dart index 4a91180..12c5048 100644 --- a/lib/views/home/pages/d_home_page.dart +++ b/lib/views/home/pages/d_home_page.dart @@ -128,10 +128,11 @@ class DesktopHomePage extends StatelessWidget { iconPath: AssetsManager.arrows, title: HomeStrings.tenderSubmitted, amount: - homeViewModel - .tenderApprovalsStateResponse! - .data! - .submittedTenders + (homeViewModel + .tenderApprovalsStateResponse + ?.data + ?.submittedTenders ?? + 0) .toString(), textColor: AppColors.mainBlue, @@ -195,7 +196,7 @@ class DesktopHomePage extends StatelessWidget { Widget _yourTenderText(HomeViewModel homeViewModel) { final isYourTenders = - homeViewModel.data?.data?.tenders!.isNotEmpty ?? false; + (homeViewModel.data?.data?.tenders?.isNotEmpty ?? false); return ConstrainedBox( constraints: const BoxConstraints(maxWidth: 740), child: Align( @@ -244,7 +245,7 @@ class DesktopHomePage extends StatelessWidget { tender: homeViewModel.tenders[index], onTap: () { TenderDetailRouteData( - tenderId: homeViewModel.tenders[index].id!, + tenderId: homeViewModel.tenders[index].id ?? '', ).push(context); }, ); diff --git a/lib/views/home/pages/m_home_page.dart b/lib/views/home/pages/m_home_page.dart index f394768..c3ae3ad 100644 --- a/lib/views/home/pages/m_home_page.dart +++ b/lib/views/home/pages/m_home_page.dart @@ -105,7 +105,8 @@ class MobileHomePage extends StatelessWidget { iconPath: AssetsManager.arrows, title: HomeStrings.tenderSubmitted, amount: - tenderApprovalsStateResponse.data!.submittedTenders.toString(), + (tenderApprovalsStateResponse.data?.submittedTenders ?? 0) + .toString(), textColor: AppColors.mainBlue, enableTap: true, onTap: () { @@ -171,7 +172,7 @@ class MobileHomePage extends StatelessWidget { Widget _yourTenderText(HomeViewModel homeViewModel) { final isYourTenders = - homeViewModel.data?.data?.tenders!.isNotEmpty ?? false; + (homeViewModel.data?.data?.tenders?.isNotEmpty ?? false); return Padding( padding: EdgeInsets.symmetric(horizontal: 24.0.w()), child: Text( @@ -220,7 +221,7 @@ class MobileHomePage extends StatelessWidget { tender: homeViewModel.tenders[index], onTap: () { TenderDetailRouteData( - tenderId: homeViewModel.tenders[index].id!, + tenderId: homeViewModel.tenders[index].id ?? '', ).push(context); }, ); diff --git a/lib/views/home/pages/t_home_page.dart b/lib/views/home/pages/t_home_page.dart index 4f624e4..666ad91 100644 --- a/lib/views/home/pages/t_home_page.dart +++ b/lib/views/home/pages/t_home_page.dart @@ -124,7 +124,8 @@ class TabletHomePage extends StatelessWidget { iconPath: AssetsManager.arrows, title: HomeStrings.tenderSubmitted, amount: - tenderApprovalsStateResponse.data!.submittedTenders.toString(), + (tenderApprovalsStateResponse.data?.submittedTenders ?? 0) + .toString(), textColor: AppColors.mainBlue, enableTap: true, @@ -201,7 +202,7 @@ class TabletHomePage extends StatelessWidget { Widget _yourTenderText(HomeViewModel homeViewModel) { final isYourTenders = - homeViewModel.data?.data?.tenders!.isNotEmpty ?? false; + (homeViewModel.data?.data?.tenders?.isNotEmpty ?? false); return Text( isYourTenders ? HomeStrings.yourTenders : HomeStrings.recommendedTenders, style: TextStyle( @@ -241,7 +242,7 @@ class TabletHomePage extends StatelessWidget { tender: homeViewModel.tenders[index], onTap: () { TenderDetailRouteData( - tenderId: homeViewModel.tenders[index].id!, + tenderId: homeViewModel.tenders[index].id ?? '', ).push(context); }, ); diff --git a/lib/views/home/tenders_list_item.dart b/lib/views/home/tenders_list_item.dart index 9e152cc..fd708dd 100644 --- a/lib/views/home/tenders_list_item.dart +++ b/lib/views/home/tenders_list_item.dart @@ -34,7 +34,7 @@ class TendersListItem extends StatelessWidget { SizedBox( width: double.infinity, child: Text( - timeConvertor(tender.publicationDate!), + timeConvertor(tender.publicationDate ?? 0), style: TextStyle( fontSize: 12.0.sp(), fontWeight: FontWeight.w400, @@ -64,7 +64,7 @@ class TendersListItem extends StatelessWidget { ), ), Text( - timeConvertor(tender.tenderDeadline!), + timeConvertor(tender.tenderDeadline ?? 0), style: TextStyle( fontSize: 14.0.sp(), fontWeight: FontWeight.w500, @@ -76,7 +76,7 @@ class TendersListItem extends StatelessWidget { ), SizedBox(height: 12.0.h()), Text( - tender.title!, + tender.title ?? '', style: TextStyle( overflow: TextOverflow.ellipsis, fontSize: 16.0.sp(), @@ -88,7 +88,7 @@ class TendersListItem extends StatelessWidget { SizedBox( width: double.infinity, child: Text( - tender.description!, + tender.description ?? '', textAlign: TextAlign.start, maxLines: 4, overflow: TextOverflow.ellipsis, @@ -110,7 +110,7 @@ class TendersListItem extends StatelessWidget { SvgPicture.asset(AssetsManager.location), SizedBox(width: 1.0.w()), Text( - tender.countryCode!, + tender.countryCode ?? '', style: TextStyle( fontSize: 12.0.sp(), fontWeight: FontWeight.w400, diff --git a/pubspec.lock b/pubspec.lock index 386acf0..70c03ee 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -125,10 +125,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" checked_yaml: dependency: transitive description: @@ -269,10 +269,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" ffi: dependency: transitive description: @@ -572,26 +572,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "11.0.2" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -620,26 +620,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.18" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -961,10 +961,10 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.9" time: dependency: transitive description: @@ -1041,10 +1041,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -1118,5 +1118,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.7.2 <4.0.0" + dart: ">=3.9.0-0 <4.0.0" flutter: ">=3.29.0" diff --git a/pubspec.yaml b/pubspec.yaml index bc878f5..0728f45 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -58,18 +58,19 @@ flutter: - assets/icons/ - assets/svgs/ - assets/pngs/ + - assets/fonts/ - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/to/font-from-package + fonts: + - family: Roboto + fonts: + - asset: assets/fonts/Roboto-Black.ttf + weight: 900 + - asset: assets/fonts/Roboto-Bold.ttf + weight: 700 + - asset: assets/fonts/Roboto-Medium.ttf + weight: 500 + - asset: assets/fonts/Roboto-Regular.ttf + weight: 400 + - asset: assets/fonts/Roboto-Light.ttf + weight: 300 + - asset: assets/fonts/Roboto-Thin.ttf diff --git a/web/flutter_bootstrap.js b/web/flutter_bootstrap.js new file mode 100644 index 0000000..dd050c5 --- /dev/null +++ b/web/flutter_bootstrap.js @@ -0,0 +1,24 @@ +(() => { + var P = () => navigator.vendor === "Google Inc." || navigator.agent === "Edg/", E = () => typeof ImageDecoder > "u" ? !1 : P(), L = () => typeof Intl.v8BreakIterator < "u" && typeof Intl.Segmenter < "u", W = () => { let n = [0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 95, 1, 120, 0]; return WebAssembly.validate(new Uint8Array(n)) }, w = { hasImageCodecs: E(), hasChromiumBreakIterators: L(), supportsWasmGC: W(), crossOriginIsolated: window.crossOriginIsolated }; function l(...n) { return new URL(C(...n), document.baseURI).toString() } function C(...n) { return n.filter(t => !!t).map((t, i) => i === 0 ? _(t) : j(_(t))).filter(t => t.length).join("/") } function j(n) { let t = 0; for (; t < n.length && n.charAt(t) === "/";)t++; return n.substring(t) } function _(n) { let t = n.length; for (; t > 0 && n.charAt(t - 1) === "/";)t--; return n.substring(0, t) } function T(n, t) { return n.canvasKitBaseUrl ? n.canvasKitBaseUrl : t.engineRevision && !t.useLocalCanvasKit ? C("https://www.gstatic.com/flutter-canvaskit", t.engineRevision) : "canvaskit" } var v = class { constructor() { this._scriptLoaded = !1 } setTrustedTypesPolicy(t) { this._ttPolicy = t } async loadEntrypoint(t) { let { entrypointUrl: i = l("main.dart.js"), onEntrypointLoaded: r, nonce: e } = t || {}; return this._loadJSEntrypoint(i, r, e) } async load(t, i, r, e, a) { a ??= o => { o.initializeEngine(r).then(c => c.runApp()) }; let { entryPointBaseUrl: s } = r; if (t.compileTarget === "dart2wasm") return this._loadWasmEntrypoint(t, i, s, a); { let o = t.mainJsPath ?? "main.dart.js", c = l(s, o); return this._loadJSEntrypoint(c, a, e) } } didCreateEngineInitializer(t) { typeof this._didCreateEngineInitializerResolve == "function" && (this._didCreateEngineInitializerResolve(t), this._didCreateEngineInitializerResolve = null, delete _flutter.loader.didCreateEngineInitializer), typeof this._onEntrypointLoaded == "function" && this._onEntrypointLoaded(t) } _loadJSEntrypoint(t, i, r) { let e = typeof i == "function"; if (!this._scriptLoaded) { this._scriptLoaded = !0; let a = this._createScriptTag(t, r); if (e) console.debug("Injecting