Compare commits
391 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 136760405e | |||
| 3d5f937e6a | |||
| 7d11b960c0 | |||
| cfd6b8c5f4 | |||
| 0ea3482e9a | |||
| 0e05ce0b89 | |||
| 166328df89 | |||
| 87b0ebfa27 | |||
| c32972ea6d | |||
| 76456fb530 | |||
| 1241540bbe | |||
| 21ae7d92a8 | |||
| ef1f8b18cd | |||
| 4b1a70f709 | |||
| ea3d796013 | |||
| 5f7daadf85 | |||
| 482dde9a72 | |||
| b518b9e536 | |||
| a85def8156 | |||
| 86556e7543 | |||
| 95511fdc99 | |||
| 0dc8ac49be | |||
| 93942ff060 | |||
| efe225b9f8 | |||
| 49c7ecce1f | |||
| 39bf88356f | |||
| 052f937027 | |||
| 33d07b1617 | |||
| 806c25d7b0 | |||
| aee6497ccb | |||
| e85bf2d577 | |||
| 2a5056e7ff | |||
| e0a381d00e | |||
| 2be2f69f30 | |||
| 17f7f3287d | |||
| c2353fef20 | |||
| 3e3170b103 | |||
| d71f337d37 | |||
| 62c5634cf6 | |||
| 26d3638d80 | |||
| 6c591172df | |||
| 0a5c4a3d20 | |||
| c0077e532c | |||
| 379633d7f5 | |||
| c855503edd | |||
| 0f6c6e51ab | |||
| e5ce03e396 | |||
| c67529dbac | |||
| 84cb6b2e83 | |||
| 6e07a55885 | |||
| 8fb31695a8 | |||
| 4fafa35888 | |||
| 0cf9634c5d | |||
| 787a8057b2 | |||
| 5f911d51f9 | |||
| 8da29792b4 | |||
| 5e003a4d71 | |||
| fcf1bbbb15 | |||
| ff7f363983 | |||
| 843997e58c | |||
| 3778ebb261 | |||
| b1487839a7 | |||
| 221030eff3 | |||
| 5135629b33 | |||
| 281ea863e8 | |||
| 1c0dd6d328 | |||
| 07d4ba4afa | |||
| 6ad6b6ccbd | |||
| ce2575035f | |||
| baea2c9fdb | |||
| 27639cb964 | |||
| 1143d11054 | |||
| 213f3d418d | |||
| e33a62b909 | |||
| ebab9bae52 | |||
| 82c25c5406 | |||
| 3f0fc08a5c | |||
| f137ea41ac | |||
| a7effa3576 | |||
| 74341a9cc6 | |||
| c5267c0540 | |||
| d4ba3aaa03 | |||
| 103ccdc022 | |||
| f8a722eb50 | |||
| fdb28080e3 | |||
| 8a384921c5 | |||
| 4b47bf5288 | |||
| 141611b84d | |||
| a29d0afeb8 | |||
| eb93714022 | |||
| 071612a521 | |||
| 726a60ad25 | |||
| b897986c1f | |||
| 7d4d7fc713 | |||
| 91075255f4 | |||
| 5c2f19dcc4 | |||
| 58aebbeabe | |||
| 670480910b | |||
| 45c1b247d3 | |||
| ecd24670e9 | |||
| ab99518ff2 | |||
| 6ac6aff59e | |||
| 33ca7b613e | |||
| e83b0b50ae | |||
| bcd19de256 | |||
| ae36879ec5 | |||
| eda609cf7e | |||
| e1744b09e3 | |||
| a3845df8bd | |||
| d7eebe152b | |||
| d8a807b43e | |||
| 5172017a54 | |||
| 535924691e | |||
| ca8e0f56ac | |||
| 63071325cb | |||
| 800cd635c2 | |||
| f46ce36861 | |||
| b69fd92b19 | |||
| 9e19dc0fa4 | |||
| 38c40e2dfe | |||
| 02bbc32d23 | |||
| 5b052a1fa9 | |||
| d5349d981c | |||
| d6c28b631a | |||
| 74c5276c94 | |||
| d5e349d218 | |||
| 44527c8f10 | |||
| fbb9d8573c | |||
| 010fc0bc74 | |||
| 45ac3f03e6 | |||
| eea3248525 | |||
| b945a34ad4 | |||
| e3ac1be71c | |||
| 3a955e67ef | |||
| 777043e2ca | |||
| 6a8b9c6902 | |||
| 07360dd308 | |||
| 7c59e2a5c8 | |||
| 0b57e10532 | |||
| 5681c6d73b | |||
| f44ff6443c | |||
| fe5b61f6bc | |||
| e7729a8ce8 | |||
| 227a2f7ae7 | |||
| f26c1eb01a | |||
| ca0f13a6df | |||
| 021a25f50c | |||
| 0a9f0c000e | |||
| 3ff670886c | |||
| a6d5e4ad35 | |||
| 456dff6402 | |||
| d3fdc83373 | |||
| 8704d4dd64 | |||
| 37920466ac | |||
| 56d54a3711 | |||
| aef501cd25 | |||
| 4f5761271c | |||
| 252e120b99 | |||
| b5c26c3e43 | |||
| 74be2fc559 | |||
| b519b99a91 | |||
| 72261af7b9 | |||
| ad96725478 | |||
| ef4c3102a9 | |||
| 9a75bcc810 | |||
| 586e67b369 | |||
| e8cae1a894 | |||
| cd8115c597 | |||
| 730c5d2bdf | |||
| cea8ccab5a | |||
| 4f168c5b0e | |||
| 99f8b1a3f9 | |||
| 30c06261c8 | |||
| c843c0a55d | |||
| 94ac83db9e | |||
| a3b8da5357 | |||
| 47bc23c029 | |||
| c16d8b6e91 | |||
| a6fe4499d0 | |||
| 004c2397c5 | |||
| d64193d1f8 | |||
| e330875c6f | |||
| 3d2addf1d6 | |||
| 3b6e1d22ec | |||
| ff913c0c54 | |||
| c45c933277 | |||
| 89d6999abf | |||
| 969ecf8fdc | |||
| ee7d3881e6 | |||
| cc3f18f7e2 | |||
| 08bfe1d417 | |||
| 3593011d6d | |||
| 5ae11f6625 | |||
| a61bca7d81 | |||
| fb3b033f45 | |||
| 91a2d0dd1e | |||
| 04c643561b | |||
| 526bd40255 | |||
| 1889f6cada | |||
| c1dd9a60f2 | |||
| ec869c54c3 | |||
| b440c0a42b | |||
| baa826c52c | |||
| 6b530529e3 | |||
| a633b52949 | |||
| c103d1979c | |||
| 82c01cb7bf | |||
| 43bc552698 | |||
| bb6a8e3090 | |||
| 565e9199d4 | |||
| c5de46040d | |||
| 934b1b2301 | |||
| 302152449f | |||
| 0f591bd111 | |||
| ea04c000cf | |||
| a59d2bf336 | |||
| d5fcad8fa5 | |||
| 609828a26c | |||
| d0a5c6c858 | |||
| 4a293c0aa4 | |||
| d51d13a685 | |||
| bf6bda04a6 | |||
| b749dc62d9 | |||
| b82a5a72c7 | |||
| 56ab6bb950 | |||
| bb54605ddb | |||
| c4b3a12213 | |||
| 43d715f4f8 | |||
| a9d6ca1baa | |||
| dfcfced28f | |||
| d0474fed21 | |||
| f228307859 | |||
| ab9cbce41c | |||
| 70413cc294 | |||
| a4d510f023 | |||
| e99388711d | |||
| 00cd5488e3 | |||
| b69a52a5a8 | |||
| f5c05d7431 | |||
| 0403d8c4b5 | |||
| fb7bf4ad65 | |||
| 3417299989 | |||
| 66887d23f8 | |||
| f064730dcf | |||
| a49505c153 | |||
| 9d898d8dff | |||
| c517075197 | |||
| 2dc3396fcc | |||
| d318b17b18 | |||
| 4221ae73b9 | |||
| b49e93825e | |||
| 790bf0e4f8 | |||
| a0bd74b703 | |||
| 96daf77b45 | |||
| 77ffd95fb6 | |||
| 24cc7f64b5 | |||
| d76512c11f | |||
| e1e7542a6d | |||
| 121cde211f | |||
| b79decf04f | |||
| a26b826729 | |||
| cc3d1ae430 | |||
| 329e450f5b | |||
| 0a03b1c60c | |||
| 652d4bb2fd | |||
| 5903fcd31a | |||
| b0825fe7cb | |||
| 8a2debcaa8 | |||
| 609c8d46db | |||
| 1387fb1af5 | |||
| 1f73aa3b87 | |||
| 47ca6d7311 | |||
| 64443a5076 | |||
| 20d5bc4004 | |||
| 9257786191 | |||
| 66db154b02 | |||
| 5770f6c353 | |||
| c5713cf6e0 | |||
| 4fe544b35f | |||
| 6542f1c399 | |||
| 963a708ab8 | |||
| 2f0b11e5ba | |||
| d9b2598bca | |||
| 0c15bd3e90 | |||
| 0daffb5041 | |||
| 9485213d6e | |||
| 9a8f157451 | |||
| a6f6cdaace | |||
| effbac2c91 | |||
| f8de726959 | |||
| 01220144c3 | |||
| 3f93cc9a7a | |||
| 83a16bad79 | |||
| d2f93db580 | |||
| a3c1963d30 | |||
| 8e6ef25954 | |||
| 580fa027f2 | |||
| 9346cccd20 | |||
| 51f2435c33 | |||
| ba5772f3ac | |||
| 662d20617d | |||
| e6d1cf0268 | |||
| ed7c5a2269 | |||
| 98beb20827 | |||
| 76a54ce969 | |||
| c53f30035d | |||
| ec01e2212b | |||
| f840418caf | |||
| 76d24a8e2b | |||
| 821cbc0a0d | |||
| ea25598144 | |||
| 70fc306789 | |||
| ba46f38497 | |||
| 67692967c3 | |||
| cc51afadb3 | |||
| d9fb9dd758 | |||
| d75da5389a | |||
| efaf9b3574 | |||
| 763c4cdb54 | |||
| b37f0f71db | |||
| 8ceb443964 | |||
| a87e52d22c | |||
| 46c281d288 | |||
| 5289cf8511 | |||
| 22ae804c2d | |||
| 1a7293fc12 | |||
| e318e03805 | |||
| 11b6ec9edb | |||
| 2a7e3e17ce | |||
| 9cbdc849b1 | |||
| 0cabe11ab7 | |||
| a561f4fa5f | |||
| 429e91b638 | |||
| c0d152002c | |||
| 1329c8aba4 | |||
| 52f9eb7ba6 | |||
| bcff545dd7 | |||
| 6a5b4f7f4b | |||
| b2b9d8f046 | |||
| 4c39e9163b | |||
| 6541ac883f | |||
| ffe9f6e9fb | |||
| 8e6f3d7d45 | |||
| abd56d5a14 | |||
| cb25b932ba | |||
| 771d809ce2 | |||
| d6f1629485 | |||
| 39a42048c2 | |||
| 99d0fa4aa8 | |||
| 79ed959b42 | |||
| 23c3cf4173 | |||
| f548db7d82 | |||
| fd2f3a2138 | |||
| 1fe817919f | |||
| 656e1cd3d7 | |||
| a9ea3594b9 | |||
| 7de2cb7b36 | |||
| ac22e50eca | |||
| 9bd039ca25 | |||
| b0d38b4b11 | |||
| 926b749fa8 | |||
| b2ed1e0b51 | |||
| 3dc9ce30e6 | |||
| 91241aa399 | |||
| c79904d132 | |||
| 15106d0a00 | |||
| 2e69e1dd92 | |||
| c89932755f | |||
| 540e13dfe0 | |||
| d51603ff5d | |||
| 553d22dd6b | |||
| 5f5107ee99 | |||
| 6ecce1e9ff | |||
| 22d8c64994 | |||
| ebd78eb72b | |||
| f828ba1786 | |||
| bbadc58ab8 | |||
| a1b7a3ef28 | |||
| 7373a1b8cb | |||
| 0edbfadc90 | |||
| ef479b633d | |||
| 081e7d5533 | |||
| 18e8217ce1 | |||
| cadd51535e | |||
| ba394e7fea | |||
| 04c92804b8 | |||
| a2d1bebca1 | |||
| 1a448572ea | |||
| 04b247aa99 | |||
| aa0d756979 | |||
| 16f50f826b |
@@ -1,16 +1,14 @@
|
|||||||
# *database/auto.cnf
|
mih_minio/
|
||||||
# *database/binlog.index
|
mih_db/
|
||||||
# *database/mysql.sock
|
mih_git/
|
||||||
File_Storage
|
mih_nginx/
|
||||||
database/
|
mih_monitor/
|
||||||
|
mih_wp/
|
||||||
certbot/
|
certbot/
|
||||||
Firebase-emulator/
|
Firebase-emulator/
|
||||||
Mzansi_Mail/
|
Mzansi_Mail/
|
||||||
# database/ibdata1
|
|
||||||
# database/mysql.ibd
|
|
||||||
# database/undo*
|
|
||||||
# database/#innodb_redo/#ib_redo*
|
|
||||||
.venv
|
.venv
|
||||||
google-chrome-stable_current_amd64.deb
|
google-chrome-stable_current_amd64.deb
|
||||||
.env
|
.env
|
||||||
Frontend/android/app/.cxx/
|
Frontend/android/app/.cxx/
|
||||||
|
.DS_Store
|
||||||
@@ -6,14 +6,25 @@
|
|||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Debug",
|
"name": "Debug",
|
||||||
"cwd": "Frontend",
|
"cwd": "mih_ui",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "dart",
|
"type": "dart",
|
||||||
"program": "lib/main_dev.dart"
|
"program": "lib/main_dev.dart"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Debug (web)",
|
||||||
|
"cwd": "mih_ui",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"program": "lib/main_dev.dart",
|
||||||
|
"args": [
|
||||||
|
"--web-port",
|
||||||
|
"1995"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Profile",
|
"name": "Profile",
|
||||||
"cwd": "Frontend",
|
"cwd": "mih_ui",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "dart",
|
"type": "dart",
|
||||||
"flutterMode": "profile",
|
"flutterMode": "profile",
|
||||||
@@ -21,7 +32,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Release",
|
"name": "Release",
|
||||||
"cwd": "Frontend",
|
"cwd": "mih_ui",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "dart",
|
"type": "dart",
|
||||||
"flutterMode": "release",
|
"flutterMode": "release",
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
# This file tracks properties of this Flutter project.
|
|
||||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
|
||||||
#
|
|
||||||
# This file should be version controlled and should not be manually edited.
|
|
||||||
|
|
||||||
version:
|
|
||||||
revision: "8defaa71a77c16e8547abdbfad2053ce3a6e2d5b"
|
|
||||||
channel: "stable"
|
|
||||||
|
|
||||||
project_type: app
|
|
||||||
|
|
||||||
# Tracks metadata for the flutter migrate command
|
|
||||||
migration:
|
|
||||||
platforms:
|
|
||||||
- platform: root
|
|
||||||
create_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
base_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
- platform: android
|
|
||||||
create_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
base_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
- platform: ios
|
|
||||||
create_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
base_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
- platform: linux
|
|
||||||
create_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
base_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
- platform: macos
|
|
||||||
create_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
base_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
- platform: web
|
|
||||||
create_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
base_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
- platform: windows
|
|
||||||
create_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
base_revision: 8defaa71a77c16e8547abdbfad2053ce3a6e2d5b
|
|
||||||
|
|
||||||
# User provided section
|
|
||||||
|
|
||||||
# List of Local paths (relative to this file) that should be
|
|
||||||
# ignored by the migrate tool.
|
|
||||||
#
|
|
||||||
# Files that are not part of the templates will be ignored by default.
|
|
||||||
unmanaged_files:
|
|
||||||
- 'lib/main.dart'
|
|
||||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# Install Operating system and dependencies
|
|
||||||
#FROM ubuntu:22.04
|
|
||||||
FROM debian:latest AS build-env
|
|
||||||
|
|
||||||
#ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
|
|
||||||
RUN apt-get update --fix-missing
|
|
||||||
|
|
||||||
RUN apt-get install -y curl git wget unzip gdb libstdc++6 libglu1-mesa fonts-droid-fallback
|
|
||||||
# RUN apt-get install -y curl git wget unzip libgconf-2-4 gdb libstdc++6 libglu1-mesa fonts-droid-fallback
|
|
||||||
RUN apt-get install python3 -y
|
|
||||||
|
|
||||||
# download Flutter SDK from Flutter Github repo
|
|
||||||
RUN git clone -b flutter-3.32-candidate.0 https://github.com/flutter/flutter.git /usr/local/flutter
|
|
||||||
# RUN git clone -b stable https://github.com/flutter/flutter.git /usr/local/flutter
|
|
||||||
|
|
||||||
# Set flutter environment path
|
|
||||||
ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}"
|
|
||||||
#ENV PATH "$PATH:/home/developer/flutter/bin"
|
|
||||||
|
|
||||||
RUN flutter doctor -v
|
|
||||||
|
|
||||||
# Enable flutter web
|
|
||||||
RUN flutter channel flutter-3.32-candidate.0
|
|
||||||
# RUN flutter channel stable
|
|
||||||
RUN flutter config --enable-web
|
|
||||||
|
|
||||||
# Copy files to container and build
|
|
||||||
RUN mkdir /app/
|
|
||||||
COPY . /app/
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
# RUN flutter upgrade
|
|
||||||
RUN flutter build web --release -t ./lib/main_prod.dart
|
|
||||||
# RUN flutter build web --release --web-renderer canvaskit -t ./lib/main_prod.dart
|
|
||||||
|
|
||||||
|
|
||||||
# RUN cd ..
|
|
||||||
|
|
||||||
# WORKDIR /app/build/web/
|
|
||||||
|
|
||||||
EXPOSE 83
|
|
||||||
|
|
||||||
RUN ["chmod", "+x", "/app/server/server.sh"]
|
|
||||||
|
|
||||||
ENTRYPOINT [ "/app/server/server.sh"]
|
|
||||||
|
|
||||||
# RUN ["python3", "-u", "/app/server/MIH_web_server.py"]
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package za.co.mzansiinnovationhub.mih
|
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
|
||||||
|
|
||||||
class MainActivity : FlutterActivity()
|
|
||||||
|
Before Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="ic_launcher_background">#3A4454</color>
|
|
||||||
</resources>
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# flutter pub run flutter_launcher_icons
|
|
||||||
flutter_launcher_icons:
|
|
||||||
image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_app_icon.png"
|
|
||||||
|
|
||||||
android: "launcher_icon"
|
|
||||||
# image_path_android: "assets/icon/icon.png"
|
|
||||||
min_sdk_android: 21 # android min sdk min:16, default 21
|
|
||||||
adaptive_icon_background: "#3A4454"
|
|
||||||
adaptive_icon_foreground: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_app_icon.png"
|
|
||||||
# adaptive_icon_monochrome: "assets/icon/monochrome.png"
|
|
||||||
|
|
||||||
ios: true
|
|
||||||
image_path_ios: "lib/mih_components/mih_package_components/assets/images/app_icon/mih_app_icon.png"
|
|
||||||
remove_alpha_channel_ios: true
|
|
||||||
# image_path_ios_dark_transparent: "assets/icon/icon_dark.png"
|
|
||||||
# image_path_ios_tinted_grayscale: "assets/icon/icon_tinted.png"
|
|
||||||
# desaturate_tinted_to_grayscale_ios: true
|
|
||||||
|
|
||||||
web:
|
|
||||||
generate: true
|
|
||||||
image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/circle_logo.png"
|
|
||||||
background_color: "#3A4454"
|
|
||||||
theme_color: "#3A4454"
|
|
||||||
|
|
||||||
windows:
|
|
||||||
generate: true
|
|
||||||
image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/circle_logo.png"
|
|
||||||
icon_size: 48 # min:48, max:256, default: 48
|
|
||||||
|
|
||||||
macos:
|
|
||||||
generate: true
|
|
||||||
image_path: "lib/mih_components/mih_package_components/assets/images/app_icon/circle_logo.png"
|
|
||||||
|
Before Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
@@ -1 +0,0 @@
|
|||||||
{"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}
|
|
||||||
|
Before Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 10 KiB |
@@ -1,77 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>GADApplicationIdentifier</key>
|
|
||||||
<string>ca-app-pub-4781880856775334~6935644635</string>
|
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
|
||||||
<true/>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
||||||
<key>CFBundleDisplayName</key>
|
|
||||||
<string>MIH</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>mzansi_innovation_hub</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>????</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
|
||||||
<key>LSApplicationQueriesSchemes</key>
|
|
||||||
<array>
|
|
||||||
<string>sms</string>
|
|
||||||
<string>tel</string>
|
|
||||||
</array>
|
|
||||||
<key>LSRequiresIPhoneOS</key>
|
|
||||||
<true/>
|
|
||||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSCameraUsageDescription</key>
|
|
||||||
<string>This app needs camera access to scan QR codes</string>
|
|
||||||
<key>NSFaceIDUsageDescription</key>
|
|
||||||
<string>Why is my app authenticating using face id?</string>
|
|
||||||
<key>NSLocationWhenInUseUsageDescription</key>
|
|
||||||
<string>This app needs access to location when open.</string>
|
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
|
||||||
<string>This app needs to access your photo library to select images.</string>
|
|
||||||
<key>NSDownloadsFolderUsageDescription</key>
|
|
||||||
<string>This app needs to access your downloads folder to select files from there.</string>
|
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
|
||||||
<true/>
|
|
||||||
<key>UIBackgroundModes</key>
|
|
||||||
<array>
|
|
||||||
<string>fetch</string>
|
|
||||||
<string>remote-notification</string>
|
|
||||||
</array>
|
|
||||||
<key>UIFileSharingEnabled</key>
|
|
||||||
<true/>
|
|
||||||
<key>UILaunchStoryboardName</key>
|
|
||||||
<string>LaunchScreen</string>
|
|
||||||
<key>UIMainStoryboardFile</key>
|
|
||||||
<string>Main</string>
|
|
||||||
<key>UIStatusBarHidden</key>
|
|
||||||
<false/>
|
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
|
||||||
<array>
|
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
|
||||||
</array>
|
|
||||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
|
||||||
<array>
|
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
import 'package:upgrader/upgrader.dart';
|
|
||||||
import 'mih_config/mih_env.dart';
|
|
||||||
import 'mih_config/mih_theme.dart';
|
|
||||||
|
|
||||||
class MzansiInnovationHub extends StatefulWidget {
|
|
||||||
final GoRouter router;
|
|
||||||
const MzansiInnovationHub({
|
|
||||||
super.key,
|
|
||||||
required this.router,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MzansiInnovationHub> createState() => _MzansiInnovationHubState();
|
|
||||||
|
|
||||||
// ignore: library_private_types_in_public_api
|
|
||||||
static _MzansiInnovationHubState? of(BuildContext context) =>
|
|
||||||
context.findAncestorStateOfType<_MzansiInnovationHubState>();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MzansiInnovationHubState extends State<MzansiInnovationHub> {
|
|
||||||
late MihTheme theme;
|
|
||||||
|
|
||||||
Color getPrimany() {
|
|
||||||
return MihColors.getPrimaryColor(theme.mode == "Dark");
|
|
||||||
}
|
|
||||||
|
|
||||||
String getTitle() {
|
|
||||||
if (AppEnviroment.getEnv() == "Dev") {
|
|
||||||
return "Dev | MIH App: Mzansi Innovation Hub";
|
|
||||||
} else {
|
|
||||||
return "MIH App: Mzansi Innovation Hub";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeTheme(ThemeMode themeMode) {
|
|
||||||
setState(() {
|
|
||||||
if (themeMode == ThemeMode.light) {
|
|
||||||
setState(() {
|
|
||||||
theme.mode = "Light";
|
|
||||||
});
|
|
||||||
} else if (themeMode == ThemeMode.dark) {
|
|
||||||
setState(() {
|
|
||||||
theme.mode = "Dark";
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setState(() {
|
|
||||||
theme.mode = "Dark";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
theme = MihTheme();
|
|
||||||
super.initState();
|
|
||||||
theme.mode = "Dark";
|
|
||||||
theme.platform = Theme.of(context).platform;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
double width = MediaQuery.sizeOf(context).width;
|
|
||||||
theme.setScreenType(width);
|
|
||||||
precacheImage(theme.loadingImage(), context);
|
|
||||||
return MaterialApp.router(
|
|
||||||
title: getTitle(),
|
|
||||||
themeMode: ThemeMode.dark,
|
|
||||||
theme: theme.getThemeData(),
|
|
||||||
darkTheme: theme.getThemeData(),
|
|
||||||
debugShowCheckedModeBanner: false,
|
|
||||||
routerConfig: widget.router,
|
|
||||||
builder: (context, child) {
|
|
||||||
return UpgradeAlert(
|
|
||||||
navigatorKey: widget.router.routerDelegate.navigatorKey,
|
|
||||||
child: child ?? const Text('Upgrade Alert'),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class MIHAction extends StatefulWidget {
|
|
||||||
final void Function()? onTap;
|
|
||||||
final double iconSize;
|
|
||||||
final Widget icon;
|
|
||||||
const MIHAction({
|
|
||||||
super.key,
|
|
||||||
required this.icon,
|
|
||||||
required this.iconSize,
|
|
||||||
required this.onTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MIHAction> createState() => _MIHActionState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MIHActionState extends State<MIHAction> {
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return IconButton(
|
|
||||||
iconSize: widget.iconSize,
|
|
||||||
padding: const EdgeInsets.all(0),
|
|
||||||
onPressed: widget.onTap,
|
|
||||||
icon: widget.icon,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
import '../../main.dart';
|
|
||||||
|
|
||||||
class MIHBody extends StatefulWidget {
|
|
||||||
final bool borderOn;
|
|
||||||
final List<Widget> bodyItems;
|
|
||||||
const MIHBody({
|
|
||||||
super.key,
|
|
||||||
required this.borderOn,
|
|
||||||
required this.bodyItems,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MIHBody> createState() => _MIHBodyState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MIHBodyState extends State<MIHBody> {
|
|
||||||
//double paddingSize = 10;
|
|
||||||
|
|
||||||
double getHorizontalPaddingSize(Size screenSize) {
|
|
||||||
if (MzansiInnovationHub.of(context)!.theme.screenType == "desktop") {
|
|
||||||
if (widget.borderOn) {
|
|
||||||
return 10;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// mobile
|
|
||||||
if (widget.borderOn) {
|
|
||||||
return 10;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double getVerticalPaddingSize(Size screenSize) {
|
|
||||||
// mobile
|
|
||||||
if (widget.borderOn) {
|
|
||||||
return 10;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Decoration? getBoader() {
|
|
||||||
if (widget.borderOn) {
|
|
||||||
return BoxDecoration(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
borderRadius: BorderRadius.circular(25.0),
|
|
||||||
border: Border.all(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
width: 3.0),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Size screenSize = MediaQuery.sizeOf(context);
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.only(
|
|
||||||
left: getHorizontalPaddingSize(screenSize),
|
|
||||||
right: getHorizontalPaddingSize(screenSize),
|
|
||||||
bottom: getVerticalPaddingSize(screenSize),
|
|
||||||
top: 0,
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.only(
|
|
||||||
left: 10,
|
|
||||||
right: 10,
|
|
||||||
bottom: 10,
|
|
||||||
top: getVerticalPaddingSize(screenSize),
|
|
||||||
),
|
|
||||||
width: screenSize.width,
|
|
||||||
height: screenSize.height,
|
|
||||||
decoration: getBoader(),
|
|
||||||
child: ScrollConfiguration(
|
|
||||||
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: widget.bodyItems,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class MIHHeader extends StatefulWidget {
|
|
||||||
final MainAxisAlignment headerAlignment;
|
|
||||||
final List<Widget> headerItems;
|
|
||||||
const MIHHeader({
|
|
||||||
super.key,
|
|
||||||
required this.headerAlignment,
|
|
||||||
required this.headerItems,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MIHHeader> createState() => _MIHHeaderState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MIHHeaderState extends State<MIHHeader> {
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedBox(
|
|
||||||
height: 50,
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: widget.headerAlignment,
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: widget.headerItems,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../mih_packages/mih_home/components/mih_app_drawer.dart';
|
|
||||||
import 'mih_body.dart';
|
|
||||||
import 'mih_header.dart';
|
|
||||||
|
|
||||||
class MIHLayoutBuilder extends StatefulWidget {
|
|
||||||
final Widget actionButton;
|
|
||||||
final Widget? secondaryActionButton;
|
|
||||||
final MIHHeader header;
|
|
||||||
final MIHBody body;
|
|
||||||
final MIHAppDrawer? actionDrawer;
|
|
||||||
final Widget? secondaryActionDrawer;
|
|
||||||
final Widget? bottomNavBar;
|
|
||||||
final bool pullDownToRefresh;
|
|
||||||
final Future<void> Function() onPullDown;
|
|
||||||
//final String type;
|
|
||||||
const MIHLayoutBuilder({
|
|
||||||
super.key,
|
|
||||||
required this.actionButton,
|
|
||||||
required this.header,
|
|
||||||
required this.secondaryActionButton,
|
|
||||||
required this.body,
|
|
||||||
required this.actionDrawer,
|
|
||||||
required this.secondaryActionDrawer,
|
|
||||||
required this.bottomNavBar,
|
|
||||||
required this.pullDownToRefresh,
|
|
||||||
required this.onPullDown,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MIHLayoutBuilder> createState() => _MIHLayoutBuilderState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MIHLayoutBuilderState extends State<MIHLayoutBuilder> {
|
|
||||||
List<Widget> getList() {
|
|
||||||
List<Widget> temp = [];
|
|
||||||
temp.add(widget.header);
|
|
||||||
temp.add(widget.body);
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// openTheDrawer() {
|
|
||||||
// _scaffoldKey.currentState!.openEndDrawer();
|
|
||||||
// }
|
|
||||||
|
|
||||||
Widget getLayoutHeader() {
|
|
||||||
List<Widget> temp = [];
|
|
||||||
temp.add(widget.actionButton);
|
|
||||||
temp.add(Flexible(child: widget.header));
|
|
||||||
if (widget.secondaryActionButton != null) {
|
|
||||||
temp.add(widget.secondaryActionButton!);
|
|
||||||
} else {
|
|
||||||
//print(widget.header.headerItems.length);
|
|
||||||
if (widget.header.headerItems.length == 1) {
|
|
||||||
temp.add(const SizedBox(
|
|
||||||
width: 50,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: temp,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget getBody(double width, double height) {
|
|
||||||
if (widget.pullDownToRefresh == true) {
|
|
||||||
return SafeArea(
|
|
||||||
child: LayoutBuilder(builder: (context, BoxConstraints constraints) {
|
|
||||||
double newheight = constraints.maxHeight;
|
|
||||||
//print(newheight);
|
|
||||||
return RefreshIndicator(
|
|
||||||
onRefresh: widget.onPullDown,
|
|
||||||
child: ListView.builder(
|
|
||||||
itemCount: 1,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return SafeArea(
|
|
||||||
child: SizedBox(
|
|
||||||
width: width,
|
|
||||||
height: newheight,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
getLayoutHeader(),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
Expanded(child: widget.body),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
// child: SafeArea(
|
|
||||||
// child: SizedBox(
|
|
||||||
// width: width,
|
|
||||||
// height: height,
|
|
||||||
// child: Column(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
// children: [
|
|
||||||
// getLayoutHeader(),
|
|
||||||
// Expanded(child: widget.body),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return SafeArea(
|
|
||||||
child: SizedBox(
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
getLayoutHeader(),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
Expanded(child: widget.body),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Size screenSize = MediaQuery.sizeOf(context);
|
|
||||||
return Scaffold(
|
|
||||||
//drawerEnableOpenDragGesture: true,
|
|
||||||
drawer: widget.actionDrawer,
|
|
||||||
endDrawer: widget.secondaryActionDrawer,
|
|
||||||
body: getBody(screenSize.width, screenSize.height),
|
|
||||||
bottomNavigationBar: widget.bottomNavBar,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_yt_video_player.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class MIHTile extends StatefulWidget {
|
|
||||||
final String tileName;
|
|
||||||
final String? videoID;
|
|
||||||
final Widget tileIcon;
|
|
||||||
final void Function() onTap;
|
|
||||||
// final Widget tileIcon;
|
|
||||||
final Color p;
|
|
||||||
final Color s;
|
|
||||||
|
|
||||||
const MIHTile({
|
|
||||||
super.key,
|
|
||||||
required this.onTap,
|
|
||||||
required this.tileName,
|
|
||||||
this.videoID,
|
|
||||||
required this.tileIcon,
|
|
||||||
required this.p,
|
|
||||||
required this.s,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MIHTile> createState() => _MIHTileState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MIHTileState extends State<MIHTile> {
|
|
||||||
late Color mainC;
|
|
||||||
late Color secondC;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
mainC = widget.p;
|
|
||||||
secondC = widget.s;
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
void displayHint() {
|
|
||||||
if (widget.videoID != null) {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return MihPackageWindow(
|
|
||||||
fullscreen: false,
|
|
||||||
windowTitle: widget.tileName,
|
|
||||||
onWindowTapClose: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
windowBody: Column(
|
|
||||||
children: [
|
|
||||||
MIHYTVideoPlayer(videoYTLink: widget.videoID!),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
// print(
|
|
||||||
// "Tile Name: ${widget.tileName}\nTitle Type: ${widget.tileIcon.runtimeType.toString()}");
|
|
||||||
return FittedBox(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
AnimatedContainer(
|
|
||||||
//alignment: Alignment.center,
|
|
||||||
width: 250,
|
|
||||||
height: 250,
|
|
||||||
duration: const Duration(seconds: 2),
|
|
||||||
child: Material(
|
|
||||||
color: mainC,
|
|
||||||
// shadowColor:
|
|
||||||
// MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
// elevation: 5,
|
|
||||||
borderRadius: BorderRadius.circular(80),
|
|
||||||
child: InkWell(
|
|
||||||
borderRadius: BorderRadius.circular(80),
|
|
||||||
// ho
|
|
||||||
onTap: widget.onTap,
|
|
||||||
onLongPress: () {
|
|
||||||
displayHint();
|
|
||||||
},
|
|
||||||
// hoverDuration: ,
|
|
||||||
splashColor: MihColors.getHighlightColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
highlightColor: MihColors.getHighlightColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
child: widget.tileIcon,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
SizedBox(
|
|
||||||
width: 300,
|
|
||||||
child: Text(
|
|
||||||
widget.tileName,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
softWrap: true,
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 40.0,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_tools/package_tool_two.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class PackageTest extends StatefulWidget {
|
|
||||||
// final AppUser user;
|
|
||||||
// final Business business;
|
|
||||||
final TestArguments arguments;
|
|
||||||
const PackageTest({
|
|
||||||
super.key,
|
|
||||||
required this.arguments,
|
|
||||||
// required this.user,
|
|
||||||
// required this.business,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<PackageTest> createState() => _PackageTestState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _PackageTestState extends State<PackageTest> {
|
|
||||||
int _selcetedIndex = 0;
|
|
||||||
|
|
||||||
MihPackageAction getAction() {
|
|
||||||
return MihPackageAction(
|
|
||||||
icon: const Icon(Icons.arrow_back),
|
|
||||||
iconSize: 35,
|
|
||||||
onTap: () {
|
|
||||||
context.goNamed(
|
|
||||||
'mihHome',
|
|
||||||
extra: true,
|
|
||||||
);
|
|
||||||
FocusScope.of(context).unfocus();
|
|
||||||
// Navigator.of(context).pop();
|
|
||||||
// Navigator.of(context).popAndPushNamed(
|
|
||||||
// '/',
|
|
||||||
// arguments: AuthArguments(true, false),
|
|
||||||
// );
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
MihPackageTools getTools() {
|
|
||||||
Map<Widget, void Function()?> temp = Map();
|
|
||||||
temp[const Icon(Icons.inbox)] = () {
|
|
||||||
setState(() {
|
|
||||||
_selcetedIndex = 0;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
temp[const Icon(Icons.outbond)] = () {
|
|
||||||
setState(() {
|
|
||||||
_selcetedIndex = 1;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return MihPackageTools(
|
|
||||||
tools: temp,
|
|
||||||
selcetedIndex: _selcetedIndex,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void showAlert() {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return MihPackageAlert(
|
|
||||||
alertIcon: Icon(
|
|
||||||
Icons.warning_amber_rounded,
|
|
||||||
size: 100,
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
),
|
|
||||||
alertTitle: "Oops! Looks like some fields are missing.",
|
|
||||||
alertBody: Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"We noticed that some required fields are still empty. To ensure your request is processed smoothly, please fill out all the highlighted fields before submitting the form again.",
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 25),
|
|
||||||
RichText(
|
|
||||||
text: TextSpan(
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
children: <TextSpan>[
|
|
||||||
TextSpan(
|
|
||||||
text: "Here's a quick tip: ",
|
|
||||||
style: TextStyle(
|
|
||||||
fontStyle: FontStyle.italic,
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"))),
|
|
||||||
const TextSpan(text: "Look for fields with an asterisk ("),
|
|
||||||
TextSpan(
|
|
||||||
text: "*",
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"))),
|
|
||||||
const TextSpan(
|
|
||||||
text: ") next to them, as these are mandatory."),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
alertColour: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> getToolBody() {
|
|
||||||
List<Widget> toolBodies = [
|
|
||||||
PackageToolOne(
|
|
||||||
user: widget.arguments.user,
|
|
||||||
business: widget.arguments.business,
|
|
||||||
),
|
|
||||||
const PackageToolTwo(),
|
|
||||||
];
|
|
||||||
return toolBodies;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> getToolTitle() {
|
|
||||||
List<String> toolTitles = [
|
|
||||||
"Tool One",
|
|
||||||
"Tool Two",
|
|
||||||
];
|
|
||||||
return toolTitles;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MihPackage(
|
|
||||||
appActionButton: getAction(),
|
|
||||||
appTools: getTools(),
|
|
||||||
appBody: getToolBody(),
|
|
||||||
appToolTitles: getToolTitle(),
|
|
||||||
selectedbodyIndex: _selcetedIndex,
|
|
||||||
onIndexChange: (newValue) {
|
|
||||||
setState(() {
|
|
||||||
_selcetedIndex = newValue;
|
|
||||||
});
|
|
||||||
print("Index: $_selcetedIndex");
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tile.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class TestPackageTile extends StatefulWidget {
|
|
||||||
final AppUser signedInUser;
|
|
||||||
final Business? business;
|
|
||||||
final double packageSize;
|
|
||||||
const TestPackageTile({
|
|
||||||
super.key,
|
|
||||||
required this.signedInUser,
|
|
||||||
required this.business,
|
|
||||||
required this.packageSize,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<TestPackageTile> createState() => _TestPackageTileState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _TestPackageTileState extends State<TestPackageTile> {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MihPackageTile(
|
|
||||||
onTap: () {
|
|
||||||
context.goNamed(
|
|
||||||
'testPackage',
|
|
||||||
extra: TestArguments(
|
|
||||||
widget.signedInUser,
|
|
||||||
widget.business,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
// Navigator.of(context).pushNamed(
|
|
||||||
// '/package-dev',
|
|
||||||
// arguments: TestArguments(
|
|
||||||
// widget.signedInUser,
|
|
||||||
// widget.business,
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
},
|
|
||||||
appName: "Test",
|
|
||||||
appIcon: Icon(
|
|
||||||
Icons.warning_amber_rounded,
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
),
|
|
||||||
iconSize: widget.packageSize,
|
|
||||||
primaryColor: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
secondaryColor: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 41 KiB |
@@ -1,75 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:google_mobile_ads/google_mobile_ads.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
|
|
||||||
|
|
||||||
class MihBannerAd extends StatefulWidget {
|
|
||||||
const MihBannerAd({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihBannerAd> createState() => _MihBannerAdState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihBannerAdState extends State<MihBannerAd> {
|
|
||||||
BannerAd? _bannerAd;
|
|
||||||
bool _isBannerAdLoaded = false;
|
|
||||||
final adUnitId = AppEnviroment.bannerAdUnitId;
|
|
||||||
String errorMessage = '';
|
|
||||||
|
|
||||||
void _loadBannerAd() {
|
|
||||||
_bannerAd = BannerAd(
|
|
||||||
adUnitId: adUnitId,
|
|
||||||
request: const AdRequest(),
|
|
||||||
size: AdSize.banner,
|
|
||||||
listener: BannerAdListener(
|
|
||||||
onAdLoaded: (ad) {
|
|
||||||
debugPrint('$ad loaded.');
|
|
||||||
setState(() {
|
|
||||||
_isBannerAdLoaded = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onAdFailedToLoad: (ad, err) {
|
|
||||||
debugPrint('BannerAd failed to load: $err');
|
|
||||||
setState(() {
|
|
||||||
errorMessage =
|
|
||||||
'Failed to load ad- Message: ${err.message} Code :${err.code}';
|
|
||||||
});
|
|
||||||
ad.dispose(); // Dispose the ad to free resources
|
|
||||||
},
|
|
||||||
onAdOpened: (Ad ad) => debugPrint('$ad opened.'),
|
|
||||||
onAdClosed: (Ad ad) => debugPrint('$ad closed.'),
|
|
||||||
onAdImpression: (Ad ad) => debugPrint('$ad impression.'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
_bannerAd!.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_bannerAd?.dispose(); // Dispose the ad when the widget is removed
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_loadBannerAd();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
_bannerAd != null && _isBannerAdLoaded
|
|
||||||
? SizedBox(
|
|
||||||
width: _bannerAd!.size.width.toDouble(),
|
|
||||||
height: _bannerAd!.size.height.toDouble(),
|
|
||||||
child: AdWidget(ad: _bannerAd!))
|
|
||||||
: SizedBox(
|
|
||||||
child:
|
|
||||||
Text(AppEnviroment.getEnv() == "Dev" ? errorMessage : ""),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
import 'package:file_picker/file_picker.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
|
|
||||||
|
|
||||||
class MihBusinessProfilePreview extends StatefulWidget {
|
|
||||||
final Business business;
|
|
||||||
final String? myLocation;
|
|
||||||
const MihBusinessProfilePreview({
|
|
||||||
super.key,
|
|
||||||
required this.business,
|
|
||||||
required this.myLocation,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihBusinessProfilePreview> createState() =>
|
|
||||||
_MihBusinessProfilePreviewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
|
|
||||||
late Future<String> futureImageUrl;
|
|
||||||
PlatformFile? file;
|
|
||||||
|
|
||||||
String calculateDistance() {
|
|
||||||
try {
|
|
||||||
double distanceInKm = MIHLocationAPI().getDistanceInMeaters(
|
|
||||||
widget.myLocation!, widget.business.gps_location) /
|
|
||||||
1000;
|
|
||||||
return "${distanceInKm.toStringAsFixed(2)} km";
|
|
||||||
} catch (error) {
|
|
||||||
print(error);
|
|
||||||
return "*.** km";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
futureImageUrl =
|
|
||||||
MihFileApi.getMinioFileUrl(widget.business.logo_path, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
double profilePictureWidth = 60;
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
FutureBuilder(
|
|
||||||
future: futureImageUrl,
|
|
||||||
builder: (context, asyncSnapshot) {
|
|
||||||
if (asyncSnapshot.connectionState == ConnectionState.done &&
|
|
||||||
asyncSnapshot.hasData) {
|
|
||||||
if (asyncSnapshot.requireData != "") {
|
|
||||||
return MihCircleAvatar(
|
|
||||||
imageFile: NetworkImage(asyncSnapshot.requireData),
|
|
||||||
width: profilePictureWidth,
|
|
||||||
editable: false,
|
|
||||||
fileNameController: TextEditingController(),
|
|
||||||
userSelectedfile: file,
|
|
||||||
frameColor: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
backgroundColor: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
onChange: () {},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Icon(
|
|
||||||
MihIcons.iDontKnow,
|
|
||||||
size: profilePictureWidth,
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Icon(
|
|
||||||
MihIcons.mihRing,
|
|
||||||
size: profilePictureWidth,
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
const SizedBox(width: 15),
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.business.Name,
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
widget.business.type,
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 15,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
widget.myLocation != null || widget.myLocation!.isEmpty
|
|
||||||
? calculateDistance()
|
|
||||||
: "0.00 km",
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 10,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class MihButton extends StatelessWidget {
|
|
||||||
final void Function()? onPressed;
|
|
||||||
final Color buttonColor;
|
|
||||||
final double? width;
|
|
||||||
final double? height;
|
|
||||||
final double? borderRadius;
|
|
||||||
final double? elevation; // 0 = flat, higher = more shadow
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
const MihButton({
|
|
||||||
super.key,
|
|
||||||
required this.onPressed,
|
|
||||||
required this.buttonColor,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.borderRadius,
|
|
||||||
this.elevation,
|
|
||||||
required this.child,
|
|
||||||
});
|
|
||||||
Color _darkerColor(Color color, [double amount = .1]) {
|
|
||||||
final hsl = HSLColor.fromColor(color);
|
|
||||||
final hslDark = hsl.withLightness((hsl.lightness - amount).clamp(0.0, 1.0));
|
|
||||||
return hslDark.toColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final Color effectiveButtonColor = onPressed == null
|
|
||||||
? buttonColor.withValues(alpha: 0.6) // Example disabled color
|
|
||||||
: buttonColor;
|
|
||||||
final Color rippleColor = _darkerColor(effectiveButtonColor, 0.1);
|
|
||||||
final double radius = borderRadius ?? 25.0;
|
|
||||||
final double effectiveElevation =
|
|
||||||
onPressed == null ? 0.0 : (elevation ?? 4.0);
|
|
||||||
return MouseRegion(
|
|
||||||
cursor: onPressed == null
|
|
||||||
? SystemMouseCursors.basic
|
|
||||||
: SystemMouseCursors.click,
|
|
||||||
child: Material(
|
|
||||||
color: effectiveButtonColor,
|
|
||||||
borderRadius: BorderRadius.circular(radius),
|
|
||||||
elevation: effectiveElevation,
|
|
||||||
shadowColor: Colors.black,
|
|
||||||
child: InkWell(
|
|
||||||
borderRadius: BorderRadius.circular(radius),
|
|
||||||
splashColor: rippleColor,
|
|
||||||
highlightColor: rippleColor.withValues(alpha: 0.2),
|
|
||||||
hoverColor: rippleColor.withValues(alpha: 0.3),
|
|
||||||
onTap: onPressed,
|
|
||||||
child: Container(
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
padding: (width == null || height == null)
|
|
||||||
? const EdgeInsets.symmetric(horizontal: 24, vertical: 12)
|
|
||||||
: null,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:file_picker/file_picker.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class MihCircleAvatar extends StatefulWidget {
|
|
||||||
final ImageProvider<Object>? imageFile;
|
|
||||||
final double width;
|
|
||||||
final bool editable;
|
|
||||||
final TextEditingController fileNameController;
|
|
||||||
final onChange;
|
|
||||||
final PlatformFile? userSelectedfile;
|
|
||||||
final Color frameColor;
|
|
||||||
final Color? backgroundColor;
|
|
||||||
const MihCircleAvatar({
|
|
||||||
super.key,
|
|
||||||
required this.imageFile,
|
|
||||||
required this.width,
|
|
||||||
required this.editable,
|
|
||||||
required this.fileNameController,
|
|
||||||
required this.userSelectedfile,
|
|
||||||
required this.frameColor,
|
|
||||||
required this.backgroundColor,
|
|
||||||
required this.onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihCircleAvatar> createState() => _MihCircleAvatarState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihCircleAvatarState extends State<MihCircleAvatar> {
|
|
||||||
late ImageProvider<Object>? imagePreview;
|
|
||||||
|
|
||||||
ImageProvider<Object>? getAvatar() {
|
|
||||||
// Color dark = const Color(0XFF3A4454);
|
|
||||||
if (widget.imageFile == null) {
|
|
||||||
return null;
|
|
||||||
// if (widget.backgroundColor == dark) {
|
|
||||||
// print("here in light icon");
|
|
||||||
// return const AssetImage(
|
|
||||||
// 'lib/mih_components/mih_package_components/assets/images/i-dont-know-light.png');
|
|
||||||
// } else {
|
|
||||||
// print("here in dark icon");
|
|
||||||
// return const AssetImage(
|
|
||||||
// 'lib/mih_components/mih_package_components/assets/images/i-dont-know-dark.png');
|
|
||||||
// }
|
|
||||||
} else {
|
|
||||||
return widget.imageFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
setState(() {
|
|
||||||
imagePreview = getAvatar();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
// color: Colors.white,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
width: widget.width,
|
|
||||||
height: widget.width,
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
Visibility(
|
|
||||||
visible: imagePreview != null,
|
|
||||||
child: Positioned(
|
|
||||||
right: widget.width * 0.03,
|
|
||||||
child: CircleAvatar(
|
|
||||||
radius: widget.width / 2.2,
|
|
||||||
backgroundColor: widget.backgroundColor,
|
|
||||||
backgroundImage: imagePreview,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: imagePreview != null,
|
|
||||||
child: Icon(
|
|
||||||
size: widget.width,
|
|
||||||
MihIcons.mihRing,
|
|
||||||
color: widget.frameColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: imagePreview == null,
|
|
||||||
child: Icon(
|
|
||||||
MihIcons.iDontKnow,
|
|
||||||
size: widget.width,
|
|
||||||
color: widget.frameColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: widget.editable,
|
|
||||||
child: Positioned(
|
|
||||||
bottom: 0,
|
|
||||||
right: 0,
|
|
||||||
child: IconButton.filled(
|
|
||||||
style: ButtonStyle(
|
|
||||||
backgroundColor: WidgetStateProperty.all<Color>(
|
|
||||||
MihColors.getGreenColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
try {
|
|
||||||
FilePickerResult? result =
|
|
||||||
await FilePicker.platform.pickFiles(
|
|
||||||
type: FileType.image,
|
|
||||||
);
|
|
||||||
// print("Here 1");
|
|
||||||
if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
|
|
||||||
"Web") {
|
|
||||||
// print("Here 2");
|
|
||||||
if (result == null) return;
|
|
||||||
// print("Here 3");
|
|
||||||
PlatformFile? selectedFile = result.files.first;
|
|
||||||
setState(() {
|
|
||||||
// print("Here 4");
|
|
||||||
widget.onChange(selectedFile);
|
|
||||||
// print("Here 5");
|
|
||||||
imagePreview = MemoryImage(selectedFile.bytes!);
|
|
||||||
});
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
widget.fileNameController.text = selectedFile.name;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (result != null) {
|
|
||||||
File file = File(result.files.single.path!);
|
|
||||||
PlatformFile? androidFile = PlatformFile(
|
|
||||||
path: file.path,
|
|
||||||
name: file.path.split('/').last,
|
|
||||||
size: file.lengthSync(),
|
|
||||||
bytes: await file.readAsBytes(), // Read file bytes
|
|
||||||
//extension: fileExtension,
|
|
||||||
);
|
|
||||||
setState(() {
|
|
||||||
widget.onChange(androidFile);
|
|
||||||
imagePreview = FileImage(file);
|
|
||||||
});
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
widget.fileNameController.text =
|
|
||||||
file.path.split('/').last;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
print("here in else");
|
|
||||||
// User canceled the picker
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
print("Error: $e");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
Icons.edit,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class MihDateField extends StatefulWidget {
|
|
||||||
final TextEditingController controller;
|
|
||||||
final String labelText;
|
|
||||||
final bool required;
|
|
||||||
final double? width;
|
|
||||||
final double? height;
|
|
||||||
final double? borderRadius;
|
|
||||||
final double? elevation;
|
|
||||||
final FormFieldValidator<String>? validator;
|
|
||||||
const MihDateField({
|
|
||||||
super.key,
|
|
||||||
required this.controller,
|
|
||||||
required this.labelText,
|
|
||||||
required this.required,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.borderRadius,
|
|
||||||
this.elevation,
|
|
||||||
this.validator,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihDateField> createState() => _MihDateFieldState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihDateFieldState extends State<MihDateField> {
|
|
||||||
FormFieldState<String>? _formFieldState;
|
|
||||||
|
|
||||||
Future<void> _selectDate(BuildContext context) async {
|
|
||||||
DateTime? picked = await showDatePicker(
|
|
||||||
context: context,
|
|
||||||
initialDate: widget.controller.text.isNotEmpty
|
|
||||||
? DateTime.tryParse(widget.controller.text) ?? DateTime.now()
|
|
||||||
: DateTime.now(),
|
|
||||||
firstDate: DateTime(2000),
|
|
||||||
lastDate: DateTime(2100),
|
|
||||||
);
|
|
||||||
if (picked != null) {
|
|
||||||
widget.controller.text = picked.toString().split(" ")[0];
|
|
||||||
_formFieldState?.didChange(widget.controller.text);
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: widget.width,
|
|
||||||
height: widget.height,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.labelText,
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!widget.required)
|
|
||||||
Text(
|
|
||||||
"(Optional)",
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
FormField<String>(
|
|
||||||
initialValue: widget.controller.text,
|
|
||||||
validator: widget.validator,
|
|
||||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
|
||||||
builder: (field) {
|
|
||||||
_formFieldState = field;
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Material(
|
|
||||||
elevation: widget.elevation ?? 4.0,
|
|
||||||
borderRadius:
|
|
||||||
BorderRadius.circular(widget.borderRadius ?? 8.0),
|
|
||||||
child: TextFormField(
|
|
||||||
controller: widget.controller,
|
|
||||||
readOnly: true,
|
|
||||||
onTap: () => _selectDate(context),
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
suffixIcon: Icon(
|
|
||||||
Icons.calendar_today,
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
),
|
|
||||||
errorStyle: const TextStyle(height: 0, fontSize: 0),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 10.0, vertical: 8.0),
|
|
||||||
filled: true,
|
|
||||||
fillColor: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
widget.borderRadius ?? 8.0),
|
|
||||||
borderSide: field.hasError
|
|
||||||
? BorderSide(
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!
|
|
||||||
.theme
|
|
||||||
.mode ==
|
|
||||||
"Dark"),
|
|
||||||
width: 2.0,
|
|
||||||
)
|
|
||||||
: BorderSide.none,
|
|
||||||
),
|
|
||||||
enabledBorder: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
widget.borderRadius ?? 8.0),
|
|
||||||
borderSide: BorderSide.none,
|
|
||||||
),
|
|
||||||
focusedBorder: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
widget.borderRadius ?? 8.0),
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: field.hasError
|
|
||||||
? MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!
|
|
||||||
.theme
|
|
||||||
.mode ==
|
|
||||||
"Dark")
|
|
||||||
: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!
|
|
||||||
.theme
|
|
||||||
.mode ==
|
|
||||||
"Dark"),
|
|
||||||
width: 3.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
errorBorder: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
widget.borderRadius ?? 8.0),
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
width: 3.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
focusedErrorBorder: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
widget.borderRadius ?? 8.0),
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
width: 3.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onChanged: (value) {
|
|
||||||
field.didChange(value);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (field.hasError)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 8.0, top: 4.0),
|
|
||||||
child: Text(
|
|
||||||
field.errorText ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,243 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class MihDropdownField extends StatefulWidget {
|
|
||||||
final TextEditingController controller;
|
|
||||||
final String hintText;
|
|
||||||
final bool requiredText;
|
|
||||||
final List<String> dropdownOptions;
|
|
||||||
final bool editable;
|
|
||||||
final bool enableSearch;
|
|
||||||
final FormFieldValidator<String>? validator;
|
|
||||||
|
|
||||||
const MihDropdownField({
|
|
||||||
super.key,
|
|
||||||
required this.controller,
|
|
||||||
required this.hintText,
|
|
||||||
required this.dropdownOptions,
|
|
||||||
required this.requiredText,
|
|
||||||
required this.editable,
|
|
||||||
required this.enableSearch,
|
|
||||||
this.validator,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihDropdownField> createState() => _MihDropdownFieldState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihDropdownFieldState extends State<MihDropdownField> {
|
|
||||||
late List<DropdownMenuEntry<String>> menu;
|
|
||||||
|
|
||||||
List<DropdownMenuEntry<String>> buildMenuOptions(List<String> options) {
|
|
||||||
List<DropdownMenuEntry<String>> menuList = [];
|
|
||||||
for (final i in options) {
|
|
||||||
menuList.add(DropdownMenuEntry(
|
|
||||||
value: i,
|
|
||||||
label: i,
|
|
||||||
style: ButtonStyle(
|
|
||||||
foregroundColor: WidgetStatePropertyAll(MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark")),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return menuList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
menu = buildMenuOptions(widget.dropdownOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
menu = widget.dropdownOptions
|
|
||||||
.map((e) => DropdownMenuEntry(value: e, label: e))
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.hintText,
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!widget.requiredText)
|
|
||||||
Text(
|
|
||||||
"(Optional)",
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
FormField<String>(
|
|
||||||
validator: widget.validator,
|
|
||||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
|
||||||
initialValue: widget.controller.text,
|
|
||||||
builder: (field) {
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Theme(
|
|
||||||
data: Theme.of(context).copyWith(
|
|
||||||
textSelectionTheme: TextSelectionThemeData(
|
|
||||||
cursorColor: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
selectionColor: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark")
|
|
||||||
.withValues(alpha: 0.3),
|
|
||||||
selectionHandleColor: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: DropdownMenu(
|
|
||||||
controller: widget.controller,
|
|
||||||
dropdownMenuEntries: menu,
|
|
||||||
enableSearch: widget.enableSearch,
|
|
||||||
enableFilter: widget.enableSearch,
|
|
||||||
enabled: widget.editable,
|
|
||||||
textInputAction: TextInputAction.search,
|
|
||||||
requestFocusOnTap: true,
|
|
||||||
menuHeight: 400,
|
|
||||||
expandedInsets: EdgeInsets.zero,
|
|
||||||
textStyle: TextStyle(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
trailingIcon: Icon(
|
|
||||||
Icons.arrow_drop_down,
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
),
|
|
||||||
selectedTrailingIcon: Icon(
|
|
||||||
Icons.arrow_drop_up,
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
),
|
|
||||||
leadingIcon: IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
widget.controller.clear();
|
|
||||||
field.didChange('');
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
Icons.delete_outline_rounded,
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onSelected: (String? selectedValue) {
|
|
||||||
field.didChange(selectedValue);
|
|
||||||
},
|
|
||||||
menuStyle: MenuStyle(
|
|
||||||
backgroundColor: WidgetStatePropertyAll(
|
|
||||||
MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark")),
|
|
||||||
side: WidgetStatePropertyAll(
|
|
||||||
BorderSide(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
width: 1.0),
|
|
||||||
),
|
|
||||||
shape: WidgetStatePropertyAll(
|
|
||||||
RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
10), // Increase for more roundness
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
inputDecorationTheme: InputDecorationTheme(
|
|
||||||
errorStyle: const TextStyle(height: 0, fontSize: 0),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 10.0, vertical: 8.0),
|
|
||||||
filled: true,
|
|
||||||
fillColor: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
enabledBorder: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
borderSide: BorderSide.none,
|
|
||||||
),
|
|
||||||
focusedBorder: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: field.hasError
|
|
||||||
? MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark")
|
|
||||||
: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
width: 3.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
errorBorder: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
width: 3.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
focusedErrorBorder: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
width: 3.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (field.hasError)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 8.0, top: 4.0),
|
|
||||||
child: Text(
|
|
||||||
field.errorText ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark"),
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class MihFloatingMenu extends StatefulWidget {
|
|
||||||
final IconData? icon;
|
|
||||||
final double? iconSize;
|
|
||||||
final AnimatedIconData? animatedIcon;
|
|
||||||
final SpeedDialDirection? direction;
|
|
||||||
final List<SpeedDialChild> children;
|
|
||||||
const MihFloatingMenu({
|
|
||||||
super.key,
|
|
||||||
this.icon,
|
|
||||||
this.iconSize,
|
|
||||||
this.animatedIcon,
|
|
||||||
this.direction,
|
|
||||||
required this.children,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihFloatingMenu> createState() => _MihFloatingMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihFloatingMenuState extends State<MihFloatingMenu> {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SpeedDial(
|
|
||||||
icon: widget.icon,
|
|
||||||
buttonSize: Size(widget.iconSize ?? 56.0, widget.iconSize ?? 56.0),
|
|
||||||
animatedIcon: widget.animatedIcon,
|
|
||||||
direction: widget.direction ?? SpeedDialDirection.up,
|
|
||||||
activeIcon: Icons.close,
|
|
||||||
backgroundColor: MihColors.getGreenColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
activeBackgroundColor: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
foregroundColor: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
overlayColor: Colors.black,
|
|
||||||
overlayOpacity: 0.5,
|
|
||||||
children: widget.children,
|
|
||||||
onOpen: () => debugPrint('OPENING DIAL'),
|
|
||||||
onClose: () => debugPrint('DIAL CLOSED'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class MihForm extends StatefulWidget {
|
|
||||||
final GlobalKey<FormState> formKey;
|
|
||||||
final List<Widget> formFields;
|
|
||||||
const MihForm({
|
|
||||||
super.key,
|
|
||||||
required this.formKey,
|
|
||||||
required this.formFields,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihForm> createState() => _MihFormState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihFormState extends State<MihForm> {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Form(
|
|
||||||
key: widget.formKey,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: widget.formFields,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import 'package:flutter/widgets.dart'; // You need this import for IconData
|
|
||||||
|
|
||||||
class MihIcons {
|
|
||||||
MihIcons._(); // This makes the class non-instantiable (good practice for utility classes)
|
|
||||||
|
|
||||||
// This MUST match the 'family' name you specify in pubspec.yaml
|
|
||||||
static const _mihFontFam = 'MihIcons';
|
|
||||||
// Set to your package name ONLY if this font is part of a separate package you created
|
|
||||||
static const String? _mihFontPkg = null;
|
|
||||||
|
|
||||||
// IconData constants based on your style.css file
|
|
||||||
// Note: We convert the hex code from CSS (\eXXX) to an integer (0xeXXX)
|
|
||||||
|
|
||||||
static const IconData mzansiDirectory =
|
|
||||||
IconData(0xe900, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData personalProfile =
|
|
||||||
IconData(0xe901, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData aboutMih =
|
|
||||||
IconData(0xe902, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData accessControl =
|
|
||||||
IconData(0xe903, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData businessProfile =
|
|
||||||
IconData(0xe904, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData businessSetup =
|
|
||||||
IconData(0xe905, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData iDontKnow =
|
|
||||||
IconData(0xe906, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mihLogo =
|
|
||||||
IconData(0xe907, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mihRing =
|
|
||||||
IconData(0xe908, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mzansiAi =
|
|
||||||
IconData(0xe909, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mzansiWallet =
|
|
||||||
IconData(0xe90a, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData notifications =
|
|
||||||
IconData(0xe90b, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData patientManager =
|
|
||||||
IconData(0xe90c, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData patientProfile =
|
|
||||||
IconData(0xe90d, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData profileSetup =
|
|
||||||
IconData(0xe90e, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData calculator =
|
|
||||||
IconData(0xe940, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData calendar =
|
|
||||||
IconData(0xe953, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
}
|
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
|
||||||
|
|
||||||
class MihNumericStepper extends StatefulWidget {
|
|
||||||
final TextEditingController controller;
|
|
||||||
final Color fillColor;
|
|
||||||
final Color inputColor;
|
|
||||||
final String hintText;
|
|
||||||
final bool requiredText;
|
|
||||||
final double? width;
|
|
||||||
final int? minValue;
|
|
||||||
final int? maxValue;
|
|
||||||
final bool validationOn;
|
|
||||||
const MihNumericStepper({
|
|
||||||
super.key,
|
|
||||||
required this.controller,
|
|
||||||
required this.fillColor,
|
|
||||||
required this.inputColor,
|
|
||||||
required this.hintText,
|
|
||||||
required this.requiredText,
|
|
||||||
this.width,
|
|
||||||
this.minValue,
|
|
||||||
this.maxValue,
|
|
||||||
required this.validationOn,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihNumericStepper> createState() => _MihNumericStepperState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihNumericStepperState extends State<MihNumericStepper> {
|
|
||||||
late int _currentValue;
|
|
||||||
late bool error;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
widget.controller.removeListener(_syncCurrentValue);
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_currentValue =
|
|
||||||
int.tryParse(widget.controller.text) ?? widget.minValue ?? 0;
|
|
||||||
widget.controller.text = _currentValue.toString();
|
|
||||||
int.tryParse(widget.controller.text) ?? widget.minValue ?? 0;
|
|
||||||
widget.controller.addListener(_syncCurrentValue);
|
|
||||||
// print("Current Value: $_currentValue");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _syncCurrentValue() {
|
|
||||||
final newValue =
|
|
||||||
int.tryParse(widget.controller.text) ?? widget.minValue ?? 0;
|
|
||||||
if (newValue != _currentValue) {
|
|
||||||
setState(() {
|
|
||||||
_currentValue = newValue;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.hintText,
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: widget.fillColor,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
// color: Colors.white,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
25), // Optional: rounds the corners
|
|
||||||
boxShadow: const [
|
|
||||||
BoxShadow(
|
|
||||||
color: Color.fromARGB(60, 0, 0,
|
|
||||||
0), // 0.2 opacity = 51 in alpha (255 * 0.2)
|
|
||||||
spreadRadius: -2,
|
|
||||||
blurRadius: 10,
|
|
||||||
offset: Offset(0, 5),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
top: 2.0,
|
|
||||||
left: 5.0,
|
|
||||||
),
|
|
||||||
child: SizedBox(
|
|
||||||
width: 40,
|
|
||||||
child: IconButton.filled(
|
|
||||||
style: ButtonStyle(
|
|
||||||
backgroundColor: WidgetStateProperty.all<Color>(
|
|
||||||
MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark")),
|
|
||||||
),
|
|
||||||
color: widget.inputColor,
|
|
||||||
iconSize: 20,
|
|
||||||
onPressed: () {
|
|
||||||
print("Current Value: $_currentValue");
|
|
||||||
if (_currentValue >= (widget.minValue ?? 0)) {
|
|
||||||
setState(() {
|
|
||||||
widget.controller.text =
|
|
||||||
(_currentValue - 1).toString();
|
|
||||||
_currentValue =
|
|
||||||
int.tryParse(widget.controller.text)!;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
print("New Current Value: $_currentValue");
|
|
||||||
},
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.remove,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: _currentValue < (widget.minValue ?? 0) ||
|
|
||||||
(widget.maxValue != null &&
|
|
||||||
_currentValue > widget.maxValue!),
|
|
||||||
child: const SizedBox(
|
|
||||||
height: 21,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(width: 15),
|
|
||||||
Expanded(
|
|
||||||
child: MihTextFormField(
|
|
||||||
width: widget.width,
|
|
||||||
fillColor: widget.fillColor,
|
|
||||||
inputColor: widget.inputColor,
|
|
||||||
controller: widget.controller,
|
|
||||||
hintText: null,
|
|
||||||
requiredText: widget.requiredText,
|
|
||||||
readOnly: true,
|
|
||||||
numberMode: true,
|
|
||||||
textIputAlignment: TextAlign.center,
|
|
||||||
validator: (value) {
|
|
||||||
if (widget.validationOn) {
|
|
||||||
return MihValidationServices().validateNumber(
|
|
||||||
value, widget.minValue, widget.maxValue);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
// color: Colors.white,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
25), // Optional: rounds the corners
|
|
||||||
boxShadow: const [
|
|
||||||
BoxShadow(
|
|
||||||
color: Color.fromARGB(60, 0, 0,
|
|
||||||
0), // 0.2 opacity = 51 in alpha (255 * 0.2)
|
|
||||||
spreadRadius: -2,
|
|
||||||
blurRadius: 10,
|
|
||||||
offset: Offset(0, 5),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
top: 2.0,
|
|
||||||
left: 5.0,
|
|
||||||
),
|
|
||||||
child: SizedBox(
|
|
||||||
width: 40,
|
|
||||||
child: IconButton.filled(
|
|
||||||
style: ButtonStyle(
|
|
||||||
backgroundColor: WidgetStateProperty.all<Color>(
|
|
||||||
MihColors.getGreenColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
|
||||||
"Dark")),
|
|
||||||
),
|
|
||||||
color: widget.inputColor,
|
|
||||||
iconSize: 20,
|
|
||||||
onPressed: () {
|
|
||||||
print("Current Value: $_currentValue");
|
|
||||||
if (widget.maxValue == null ||
|
|
||||||
_currentValue <= widget.maxValue!) {
|
|
||||||
setState(() {
|
|
||||||
widget.controller.text =
|
|
||||||
(_currentValue + 1).toString();
|
|
||||||
_currentValue =
|
|
||||||
int.tryParse(widget.controller.text)!;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
print("New Current Value: $_currentValue");
|
|
||||||
},
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.add,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: _currentValue < (widget.minValue ?? 0) ||
|
|
||||||
(widget.maxValue != null &&
|
|
||||||
_currentValue > widget.maxValue!),
|
|
||||||
child: const SizedBox(
|
|
||||||
height: 21,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:ken_logger/ken_logger.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_scack_bar.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_packages/mih_home/components/mih_app_drawer.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
|
||||||
class MihPackage extends StatefulWidget {
|
|
||||||
final Widget appActionButton;
|
|
||||||
final MihPackageTools appTools;
|
|
||||||
final List<Widget> appBody;
|
|
||||||
final List<String>? appToolTitles;
|
|
||||||
final MIHAppDrawer? actionDrawer;
|
|
||||||
int selectedbodyIndex;
|
|
||||||
final Function(int) onIndexChange;
|
|
||||||
MihPackage({
|
|
||||||
super.key,
|
|
||||||
required this.appActionButton,
|
|
||||||
required this.appTools,
|
|
||||||
required this.appBody,
|
|
||||||
this.appToolTitles,
|
|
||||||
this.actionDrawer,
|
|
||||||
required this.selectedbodyIndex,
|
|
||||||
required this.onIndexChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihPackage> createState() => _MihPackageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihPackageState extends State<MihPackage>
|
|
||||||
with SingleTickerProviderStateMixin {
|
|
||||||
late PageController _pageController;
|
|
||||||
late AnimationController _animationController;
|
|
||||||
DateTime? lastPressedAt;
|
|
||||||
|
|
||||||
void unfocusAll() {
|
|
||||||
FocusScope.of(context).unfocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _peakAnimation() async {
|
|
||||||
int currentPage = widget.selectedbodyIndex;
|
|
||||||
double peakOffset = _pageController.position.viewportDimension * 0.075;
|
|
||||||
double currentOffset =
|
|
||||||
_pageController.page! * _pageController.position.viewportDimension;
|
|
||||||
int nextPage =
|
|
||||||
currentPage + 1 < widget.appBody.length ? currentPage + 1 : currentPage;
|
|
||||||
if (nextPage != currentPage) {
|
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
|
||||||
await _pageController.animateTo(
|
|
||||||
currentOffset + peakOffset,
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeOut,
|
|
||||||
);
|
|
||||||
// await Future.delayed(const Duration(milliseconds: 100));
|
|
||||||
await _pageController.animateTo(
|
|
||||||
currentPage * _pageController.position.viewportDimension,
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeIn,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
_pageController.dispose();
|
|
||||||
_animationController.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(covariant MihPackage oldWidget) {
|
|
||||||
super.didUpdateWidget(oldWidget);
|
|
||||||
if (oldWidget.selectedbodyIndex != widget.selectedbodyIndex) {
|
|
||||||
_pageController.animateToPage(
|
|
||||||
widget.selectedbodyIndex,
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_pageController = PageController(initialPage: widget.selectedbodyIndex);
|
|
||||||
_animationController = AnimationController(
|
|
||||||
vsync: this,
|
|
||||||
duration: const Duration(milliseconds: 400),
|
|
||||||
);
|
|
||||||
// if (!MzansiInnovationHub.of(context)!.theme.kIsWeb) {
|
|
||||||
// // Trigger the peak animation on start (or call this elsewhere)
|
|
||||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
// _peakAnimation();
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
if (!MzansiInnovationHub.of(context)!.theme.kIsWeb) {
|
|
||||||
// Trigger the peak animation only AFTER the route transition is complete
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
final ModalRoute? currentRoute = ModalRoute.of(context);
|
|
||||||
if (currentRoute != null) {
|
|
||||||
currentRoute.animation?.addStatusListener((status) {
|
|
||||||
if (status == AnimationStatus.completed && mounted) {
|
|
||||||
// Ensure the widget is still mounted and the animation is completed
|
|
||||||
_peakAnimation();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
Size screenSize = MediaQuery.of(context).size;
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: unfocusAll,
|
|
||||||
child: PopScope(
|
|
||||||
canPop: false,
|
|
||||||
onPopInvokedWithResult: (bool didPop, Object? result) {
|
|
||||||
if (GoRouterState.of(context).name == 'mihHome' ||
|
|
||||||
GoRouterState.of(context).name == 'mihAuthentication') {
|
|
||||||
if (lastPressedAt == null ||
|
|
||||||
DateTime.now().difference(lastPressedAt!) >
|
|
||||||
const Duration(seconds: 2)) {
|
|
||||||
// First press: show a message and update the timestamp.
|
|
||||||
lastPressedAt = DateTime.now();
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
MihSnackBar(
|
|
||||||
child: Text("Press back again to exit"),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Second press within 2 seconds: exit the app.
|
|
||||||
KenLogger.warning('Exiting app...'); // Your custom logger
|
|
||||||
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
context.goNamed(
|
|
||||||
'mihHome',
|
|
||||||
extra: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Scaffold(
|
|
||||||
drawer: widget.actionDrawer,
|
|
||||||
body: SafeArea(
|
|
||||||
bottom: false,
|
|
||||||
minimum: EdgeInsets.only(bottom: 0),
|
|
||||||
child: Container(
|
|
||||||
width: screenSize.width,
|
|
||||||
height: screenSize.height,
|
|
||||||
//color: Colors.black,
|
|
||||||
padding: const EdgeInsets.only(top: 5),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
widget.appActionButton,
|
|
||||||
const SizedBox(
|
|
||||||
width: 10,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
// alignment: Alignment.center,
|
|
||||||
// alignment: Alignment.centerRight,
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
// color: Colors.black,
|
|
||||||
child: FittedBox(
|
|
||||||
child: Text(
|
|
||||||
widget.appToolTitles != null
|
|
||||||
? widget
|
|
||||||
.appToolTitles![widget.selectedbodyIndex]
|
|
||||||
: "",
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 23,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 5),
|
|
||||||
widget.appTools,
|
|
||||||
const SizedBox(width: 5),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
Expanded(
|
|
||||||
child: PageView.builder(
|
|
||||||
controller: _pageController,
|
|
||||||
itemCount: widget.appBody.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return widget.appBody[index];
|
|
||||||
},
|
|
||||||
onPageChanged: (index) {
|
|
||||||
setState(() {
|
|
||||||
widget.selectedbodyIndex = index;
|
|
||||||
widget.onIndexChange(widget.selectedbodyIndex);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class MihPackageAction extends StatefulWidget {
|
|
||||||
final void Function()? onTap;
|
|
||||||
final double iconSize;
|
|
||||||
final Widget icon;
|
|
||||||
const MihPackageAction({
|
|
||||||
super.key,
|
|
||||||
required this.icon,
|
|
||||||
required this.iconSize,
|
|
||||||
required this.onTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihPackageAction> createState() => _MihPackageActionState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihPackageActionState extends State<MihPackageAction> {
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return IconButton(
|
|
||||||
iconSize: widget.iconSize,
|
|
||||||
padding: const EdgeInsets.all(0),
|
|
||||||
onPressed: widget.onTap,
|
|
||||||
icon: widget.icon,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||