Compare commits
314 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 |
@@ -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"]
|
|
||||||
|
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,92 +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>ITSAppUsesNonExemptEncryption</key>
|
|
||||||
<false/>
|
|
||||||
<key>SKAdNetworkItems</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>SKAdNetworkIdentifier</key>
|
|
||||||
<string>v9wttpbfk9.skadnetwork</string>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>SKAdNetworkIdentifier</key>
|
|
||||||
<string>n38lu8286q.skadnetwork</string>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
<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>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
|
||||||
<string>This app needs access to your location at all times to provide [Explain your specific, complete reason here, e.g., real-time tracking, background updates, etc.].</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,144 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/about_mih_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_access_controlls_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_authentication_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_banner_ad_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calculator_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_calendar_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mih_mine_sweeper_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_ai_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_directory_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_profile_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/mzansi_wallet_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_providers/patient_manager_provider.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
import 'package:provider/provider.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 MultiProvider(
|
|
||||||
providers: [
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MihAuthenticationProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MzansiProfileProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MzansiWalletProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MzansiAiProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MzansiDirectoryProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MihBannerAdProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MihCalculatorProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MihAccessControllsProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MihCalendarProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => AboutMihProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => MihMineSweeperProvider(),
|
|
||||||
),
|
|
||||||
ChangeNotifierProvider(
|
|
||||||
create: (context) => PatientManagerProvider(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: MaterialApp.router(
|
|
||||||
title: getTitle(),
|
|
||||||
themeMode: ThemeMode.dark,
|
|
||||||
theme: theme.getThemeData(),
|
|
||||||
darkTheme: theme.getThemeData(),
|
|
||||||
debugShowCheckedModeBanner: false,
|
|
||||||
routerConfig: widget.router,
|
|
||||||
builder: (context, child) {
|
|
||||||
if (child == null) {
|
|
||||||
return const Scaffold(
|
|
||||||
body: Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return UpgradeAlert(
|
|
||||||
navigatorKey: widget.router.routerDelegate.navigatorKey,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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,68 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class MihButton extends StatelessWidget {
|
|
||||||
final void Function()? onPressed;
|
|
||||||
final void Function()? onLongPressed;
|
|
||||||
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,
|
|
||||||
this.onLongPressed,
|
|
||||||
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,
|
|
||||||
onLongPress: onLongPressed,
|
|
||||||
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("Here 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,248 +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;
|
|
||||||
final Function(String?)? onSelected;
|
|
||||||
|
|
||||||
const MihDropdownField({
|
|
||||||
super.key,
|
|
||||||
required this.controller,
|
|
||||||
required this.hintText,
|
|
||||||
required this.dropdownOptions,
|
|
||||||
required this.requiredText,
|
|
||||||
required this.editable,
|
|
||||||
required this.enableSearch,
|
|
||||||
this.validator,
|
|
||||||
this.onSelected,
|
|
||||||
});
|
|
||||||
|
|
||||||
@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: widget.enableSearch
|
|
||||||
? TextInputAction.search
|
|
||||||
: TextInputAction.none,
|
|
||||||
requestFocusOnTap: widget.enableSearch,
|
|
||||||
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);
|
|
||||||
widget.onSelected?.call(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,67 +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 mineSweeper =
|
|
||||||
IconData(0xe900, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mzansiDirectory =
|
|
||||||
IconData(0xe901, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData personalProfile =
|
|
||||||
IconData(0xe902, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData aboutMih =
|
|
||||||
IconData(0xe903, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData accessControl =
|
|
||||||
IconData(0xe904, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData businessProfile =
|
|
||||||
IconData(0xe905, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData businessSetup =
|
|
||||||
IconData(0xe906, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData calculator =
|
|
||||||
IconData(0xe907, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData calendar =
|
|
||||||
IconData(0xe908, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData iDontKnow =
|
|
||||||
IconData(0xe909, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mihLogo =
|
|
||||||
IconData(0xe90a, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mihRing =
|
|
||||||
IconData(0xe90b, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mzansiAi =
|
|
||||||
IconData(0xe90c, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData mzansiWallet =
|
|
||||||
IconData(0xe90d, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData notifications =
|
|
||||||
IconData(0xe90e, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData patientManager =
|
|
||||||
IconData(0xe90f, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData patientProfile =
|
|
||||||
IconData(0xe910, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
|
|
||||||
|
|
||||||
static const IconData profileSetup =
|
|
||||||
IconData(0xe911, 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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class MihPackageAlert extends StatefulWidget {
|
|
||||||
final Widget alertIcon;
|
|
||||||
final String alertTitle;
|
|
||||||
final Widget alertBody;
|
|
||||||
final Color alertColour;
|
|
||||||
const MihPackageAlert({
|
|
||||||
super.key,
|
|
||||||
required this.alertIcon,
|
|
||||||
required this.alertTitle,
|
|
||||||
required this.alertBody,
|
|
||||||
required this.alertColour,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihPackageAlert> createState() => _MihPackageAlertState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihPackageAlertState extends State<MihPackageAlert> {
|
|
||||||
late double popUpWidth;
|
|
||||||
late double? popUpheight;
|
|
||||||
late double popUpTitleSize;
|
|
||||||
late double popUpSubtitleSize;
|
|
||||||
late double popUpBodySize;
|
|
||||||
late double popUpIconSize;
|
|
||||||
late double popUpPaddingSize;
|
|
||||||
Size? size;
|
|
||||||
|
|
||||||
void checkScreenSize() {
|
|
||||||
if (MzansiInnovationHub.of(context)!.theme.screenType == "desktop") {
|
|
||||||
setState(() {
|
|
||||||
popUpWidth = (size!.width / 4) * 2;
|
|
||||||
popUpheight = null;
|
|
||||||
popUpTitleSize = 30.0;
|
|
||||||
popUpSubtitleSize = 20.0;
|
|
||||||
popUpBodySize = 15;
|
|
||||||
popUpPaddingSize = 25.0;
|
|
||||||
popUpIconSize = 100;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setState(() {
|
|
||||||
popUpWidth = size!.width - (size!.width * 0.1);
|
|
||||||
popUpheight = null;
|
|
||||||
popUpTitleSize = 25.0;
|
|
||||||
popUpSubtitleSize = 18.0;
|
|
||||||
popUpBodySize = 15;
|
|
||||||
popUpPaddingSize = 15.0;
|
|
||||||
popUpIconSize = 100;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
size = MediaQuery.of(context).size;
|
|
||||||
checkScreenSize();
|
|
||||||
return Dialog(
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.all(popUpPaddingSize),
|
|
||||||
width: popUpWidth,
|
|
||||||
height: popUpheight,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
borderRadius: BorderRadius.circular(25.0),
|
|
||||||
border: Border.all(color: widget.alertColour, width: 5.0),
|
|
||||||
),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
widget.alertIcon,
|
|
||||||
//const SizedBox(height: 5),
|
|
||||||
Text(
|
|
||||||
widget.alertTitle,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: widget.alertColour,
|
|
||||||
fontSize: popUpTitleSize,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 15),
|
|
||||||
widget.alertBody,
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
top: 5,
|
|
||||||
right: 5,
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
child: IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
context.pop();
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
Icons.close,
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
size: 35,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,234 +0,0 @@
|
|||||||
import 'package:app_settings/app_settings.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:local_auth/local_auth.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.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_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 MihPackageTile extends StatefulWidget {
|
|
||||||
final String appName;
|
|
||||||
final String? ytVideoID;
|
|
||||||
final Widget appIcon;
|
|
||||||
final void Function() onTap;
|
|
||||||
final double iconSize;
|
|
||||||
final Color primaryColor;
|
|
||||||
final Color secondaryColor;
|
|
||||||
final bool? authenticateUser;
|
|
||||||
const MihPackageTile({
|
|
||||||
super.key,
|
|
||||||
required this.onTap,
|
|
||||||
required this.appName,
|
|
||||||
this.ytVideoID,
|
|
||||||
required this.appIcon,
|
|
||||||
required this.iconSize,
|
|
||||||
required this.primaryColor,
|
|
||||||
required this.secondaryColor,
|
|
||||||
this.authenticateUser,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihPackageTile> createState() => _MihPackageTileState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihPackageTileState extends State<MihPackageTile> {
|
|
||||||
final LocalAuthentication _auth = LocalAuthentication();
|
|
||||||
|
|
||||||
void displayHint() {
|
|
||||||
if (widget.ytVideoID != null) {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return MihPackageWindow(
|
|
||||||
fullscreen: false,
|
|
||||||
windowTitle: widget.appName,
|
|
||||||
// windowTools: const [],
|
|
||||||
onWindowTapClose: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
windowBody: MIHYTVideoPlayer(
|
|
||||||
videoYTLink: widget.ytVideoID!,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> isUserAuthenticated() async {
|
|
||||||
final bool canAuthWithBio = await _auth.canCheckBiometrics;
|
|
||||||
final bool canAuthenticate =
|
|
||||||
canAuthWithBio || await _auth.isDeviceSupported();
|
|
||||||
print("Auth Available: $canAuthenticate");
|
|
||||||
if (canAuthenticate) {
|
|
||||||
try {
|
|
||||||
final bool didBioAuth = await _auth.authenticate(
|
|
||||||
localizedReason: "Authenticate to access ${widget.appName}",
|
|
||||||
options: const AuthenticationOptions(
|
|
||||||
biometricOnly: false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (didBioAuth) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
authErrorPopUp();
|
|
||||||
}
|
|
||||||
// print("Authenticated: $didBioAuth");
|
|
||||||
} catch (error) {
|
|
||||||
print("Auth Error: $error");
|
|
||||||
authErrorPopUp();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print("Auth Error: No Biometrics Available");
|
|
||||||
authErrorPopUp();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void authErrorPopUp() {
|
|
||||||
Widget alertpopUp = MihPackageAlert(
|
|
||||||
alertIcon: Icon(
|
|
||||||
Icons.fingerprint,
|
|
||||||
color: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
size: 100,
|
|
||||||
),
|
|
||||||
alertTitle: "Biometric Authentication Required",
|
|
||||||
alertBody: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Hi there! To jump into the ${widget.appName} Package, you'll need to authenticate yourself with your devices biometrics, please set up biometric authentication (like fingerprint, face ID, pattern or pin) on your device first.\n\nIf you have already set up biometric authentication, press \"Authenticate now\" to try again or press \"Set Up Authentication\" to go to your device settings.",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Wrap(
|
|
||||||
runAlignment: WrapAlignment.center,
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
|
||||||
spacing: 10,
|
|
||||||
runSpacing: 10,
|
|
||||||
children: [
|
|
||||||
MihButton(
|
|
||||||
onPressed: () {
|
|
||||||
AppSettings.openAppSettings(
|
|
||||||
type: AppSettingsType.security,
|
|
||||||
);
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
buttonColor: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
width: 300,
|
|
||||||
child: Text(
|
|
||||||
"Set Up Authentication",
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MihButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
authenticateUser();
|
|
||||||
},
|
|
||||||
buttonColor: MihColors.getGreenColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
width: 300,
|
|
||||||
child: Text(
|
|
||||||
"Authenticate Now",
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
alertColour: MihColors.getRedColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
);
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return alertpopUp;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> authenticateUser() async {
|
|
||||||
if (widget.authenticateUser != null &&
|
|
||||||
widget.authenticateUser! &&
|
|
||||||
!kIsWeb) {
|
|
||||||
if (await isUserAuthenticated()) {
|
|
||||||
widget.onTap();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
widget.onTap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
// alignment: Alignment.topCenter,
|
|
||||||
// color: Colors.black,
|
|
||||||
// width: widget.iconSize,
|
|
||||||
// height: widget.iconSize + widget.iconSize / 3,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () async {
|
|
||||||
authenticateUser();
|
|
||||||
},
|
|
||||||
onLongPress: null, // Do this later
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Flexible(
|
|
||||||
flex: 3,
|
|
||||||
child: LayoutBuilder(
|
|
||||||
builder: (context, constraints) {
|
|
||||||
double iconHeight = constraints.maxWidth;
|
|
||||||
return Container(
|
|
||||||
width: iconHeight,
|
|
||||||
height: iconHeight,
|
|
||||||
child:
|
|
||||||
FittedBox(fit: BoxFit.fitHeight, child: widget.appIcon),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Flexible(
|
|
||||||
flex: 1,
|
|
||||||
child: FittedBox(
|
|
||||||
child: Text(
|
|
||||||
widget.appName,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
// softWrap: true,
|
|
||||||
// overflow: TextOverflow.visible,
|
|
||||||
style: TextStyle(
|
|
||||||
color: MihColors.getSecondaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
fontSize: 20.0,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
import 'package:mzansi_innovation_hub/main.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
|
||||||
|
|
||||||
class MihPackageToolBody extends StatefulWidget {
|
|
||||||
final bool borderOn;
|
|
||||||
final Widget bodyItem;
|
|
||||||
final double? innerHorizontalPadding;
|
|
||||||
const MihPackageToolBody({
|
|
||||||
super.key,
|
|
||||||
required this.borderOn,
|
|
||||||
required this.bodyItem,
|
|
||||||
this.innerHorizontalPadding,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MihPackageToolBody> createState() => _MihPackageToolBodyState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MihPackageToolBodyState extends State<MihPackageToolBody> {
|
|
||||||
late double _innerBodyPadding;
|
|
||||||
double getHorizontalPaddingSize(Size screenSize) {
|
|
||||||
if (MzansiInnovationHub.of(context)!.theme.screenType == "desktop") {
|
|
||||||
if (widget.borderOn) {
|
|
||||||
return widget.innerHorizontalPadding ?? 10;
|
|
||||||
} else {
|
|
||||||
return widget.innerHorizontalPadding ?? 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// mobile
|
|
||||||
if (widget.borderOn) {
|
|
||||||
return widget.innerHorizontalPadding ?? 10;
|
|
||||||
} else {
|
|
||||||
return widget.innerHorizontalPadding ?? 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double getVerticalPaddingSize(Size screenSize) {
|
|
||||||
// mobile
|
|
||||||
if (widget.borderOn) {
|
|
||||||
return 10;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Decoration? getBoader() {
|
|
||||||
if (widget.borderOn) {
|
|
||||||
_innerBodyPadding = 10.0;
|
|
||||||
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 {
|
|
||||||
_innerBodyPadding = 0.0;
|
|
||||||
return BoxDecoration(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
borderRadius: BorderRadius.circular(25.0),
|
|
||||||
border: Border.all(
|
|
||||||
color: MihColors.getPrimaryColor(
|
|
||||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
|
||||||
width: 3.0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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(
|
|
||||||
height: screenSize.height,
|
|
||||||
decoration: getBoader(),
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.all(_innerBodyPadding),
|
|
||||||
child: widget.bodyItem,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||