391 Commits

Author SHA1 Message Date
yasien_gmail 136760405e fix flatpak build lint issues 2026-06-10 14:57:24 +02:00
yasien_gmail 3d5f937e6a add build command file for later use 2026-06-10 14:28:58 +02:00
yasien_gmail 7d11b960c0 final flathub configs 2026-06-10 13:56:02 +02:00
yasien_gmail cfd6b8c5f4 Fix flatpak build and run issues 2026-06-10 12:16:00 +02:00
yasien_gmail 0ea3482e9a revert Dockerfile 2026-06-10 09:40:01 +02:00
yasien_gmail 0e05ce0b89 WIP:update flatpak configs 2026-06-10 09:37:57 +02:00
yasien_gmail 166328df89 updated .git to ignore flatpak build files 2026-06-10 09:35:38 +02:00
yasien_gmail 87b0ebfa27 lock mih-ai to ollama 0.30.6 2026-06-08 08:30:58 +02:00
yasien_gmail c32972ea6d add screenshots for app stores 2026-06-05 10:50:20 +02:00
yasien_gmail 76456fb530 include network to mih-legal 2026-06-05 10:05:05 +02:00
yasien_gmail 1241540bbe create seperate privacy policy server 2026-06-05 09:56:02 +02:00
yasien_gmail 21ae7d92a8 update version numer to 1.3.0 and add remaining files 2026-06-04 10:56:43 +02:00
yasien_gmail ef1f8b18cd fix deep link to privacy policy and update docker file with lastest container for ollama, portainer and api-hub 2026-06-04 10:47:27 +02:00
yasien_gmail 4b1a70f709 update mzansi ai to qwen3.5:9b 2026-06-03 14:26:47 +02:00
yasien_gmail ea3d796013 enable gpu for mzansi ai 2026-06-02 12:35:20 +02:00
yasien_gmail 5f7daadf85 fix deep link for unsigned in user 2026-06-02 10:48:11 +02:00
yasien_gmail 482dde9a72 service worker v4 2026-06-02 10:36:42 +02:00
yasien_gmail b518b9e536 service worker stuff 2026-06-02 10:06:17 +02:00
yasien_gmail a85def8156 fix service worker logic for new mih updates 2026-06-02 09:40:14 +02:00
yasien_gmail 86556e7543 fix docker file flutter 2026-06-01 15:43:32 +02:00
yasien_gmail 95511fdc99 fix font awesome icons use 2026-06-01 15:37:27 +02:00
yasien_gmail 0dc8ac49be fix font awesome icons 2026-06-01 14:44:46 +02:00
yasien_gmail 93942ff060 switch from query paramater to path paramater for profile views 2026-06-01 14:14:56 +02:00
yasien_gmail efe225b9f8 Add business profile links 2026-06-01 12:58:17 +02:00
yasien_gmail 49c7ecce1f add provider indexing for business & user views 2026-05-29 08:26:27 +02:00
yasien_gmail 39bf88356f fix I dont know logo and profile link build issues 2026-05-27 16:32:28 +02:00
yasien_gmail 052f937027 MIH Profile Links 2026-05-27 15:36:56 +02:00
yasien_gmail 33d07b1617 fix alert colors 2026-05-26 14:59:56 +02:00
yasien_gmail 806c25d7b0 fix profile link api 2026-05-26 14:59:41 +02:00
yasien_gmail aee6497ccb Fix go router to work with web and ios nav 2026-05-26 13:19:34 +02:00
yasien_gmail e85bf2d577 fix clicks cardf colors 2026-05-22 10:40:23 +02:00
yasien_gmail 2a5056e7ff profile links display enhancement 2026-04-29 14:44:00 +02:00
yasien_gmail e0a381d00e fix ios icon & fix ios navigation bug pt2 2026-04-28 15:33:21 +02:00
yasien_gmail 2be2f69f30 fix ios icon & fix ios navigation bug 2026-04-28 15:17:16 +02:00
yasien_gmail 17f7f3287d add localhost port 83 for api call 2026-04-24 13:08:04 +02:00
yasien_gmail c2353fef20 update mih ui with stable flutter and optimised docker file caching 2026-04-24 13:07:20 +02:00
yasien_gmail 3e3170b103 fix supertokens to work with lastest version of flutter 2026-04-24 13:02:12 +02:00
yasien_gmail d71f337d37 Mzansi Wallet new list display pt2 2026-04-22 11:52:54 +02:00
yasien_gmail 62c5634cf6 Mzansi Wallet new list display pt1 2026-04-22 10:45:49 +02:00
yasien_gmail 26d3638d80 remove image url print 2026-04-16 10:00:53 +02:00
yasien_gmail 6c591172df update android skd to 36 2026-04-16 10:00:21 +02:00
yasien_gmail 0a5c4a3d20 Get all user and business data on any ackage load 2026-04-15 12:47:01 +02:00
yasien_gmail c0077e532c Mzansi Wallet 2.0 update 2026-04-15 12:39:48 +02:00
yasien_gmail 379633d7f5 remove usage of user type 2026-04-15 08:40:55 +02:00
yasien_gmail c855503edd Mzansi AI model update to qwen3.5 2026-04-14 10:43:04 +02:00
yasien_gmail 0f6c6e51ab New Business Setup Flow 2026-04-08 15:47:33 +02:00
yasien_gmail e5ce03e396 migrate to mih_package_tooklit 2026-03-20 12:04:18 +02:00
yasien_gmail c67529dbac Migration to mih_package_toolkit 2026-03-18 16:42:12 +02:00
yasien_gmail 84cb6b2e83 linux icon image fix 2026-02-26 15:15:49 +02:00
yasien_gmail 6e07a55885 Flatpak linux build 2026-02-26 13:54:38 +02:00
yasien_gmail 8fb31695a8 linux flatpak config pt11 2026-02-26 12:34:01 +02:00
yasien_gmail 4fafa35888 linux flatpak config pt10 2026-02-26 12:17:14 +02:00
yasien_gmail 0cf9634c5d linux flatpak config pt9 2026-02-26 12:15:59 +02:00
yasien_gmail 787a8057b2 linux flatpak config pt8 2026-02-26 12:15:04 +02:00
yasien_gmail 5f911d51f9 linux flatpak config pt7 2026-02-26 09:31:20 +02:00
yasien_gmail 8da29792b4 linux flatpak config pt6 2026-02-26 09:28:18 +02:00
yasien_gmail 5e003a4d71 linux flatpak config pt5 2026-02-25 15:50:02 +02:00
yasien_gmail fcf1bbbb15 linux flatpak config pt4 2026-02-25 15:44:10 +02:00
yasien_gmail ff7f363983 linux flatpak config pt3 2026-02-25 15:35:45 +02:00
yasien_gmail 843997e58c linux flatpak config pt2 2026-02-25 15:09:23 +02:00
yasien_gmail 3778ebb261 linux flatpak config 2026-02-25 14:51:15 +02:00
yasien_gmail b1487839a7 linux name change 2026-02-25 13:58:42 +02:00
yasien_gmail 221030eff3 fix platform specific code not working on web pt2 2026-02-25 12:16:53 +02:00
yasien_gmail 5135629b33 fix platform specific code not working on web 2026-02-25 12:05:07 +02:00
yasien_gmail 281ea863e8 api cros fix 2026-02-25 11:54:49 +02:00
yasien_gmail 1c0dd6d328 update build number to 130 2026-02-25 10:25:28 +02:00
yasien_gmail 07d4ba4afa Support linux version of MIHpt2 2026-02-24 16:30:06 +02:00
yasien_gmail 6ad6b6ccbd Support linux version of MIH 2026-02-24 15:41:55 +02:00
yasien_gmail ce2575035f make profile picture the full height of the window 2026-02-24 12:43:34 +02:00
yasien_gmail baea2c9fdb fix file display on Dev Web & iOS 2026-02-24 12:37:31 +02:00
yasien_gmail 27639cb964 add scroll bar to dropdown fields 2026-02-24 11:05:24 +02:00
yasien_gmail 1143d11054 fix supertoken versioning error 2026-02-24 11:02:30 +02:00
yasien_gmail 213f3d418d update build number to 129 2026-02-18 15:41:37 +02:00
yasien_gmail e33a62b909 update look & feel of attribution list 2026-02-18 14:03:04 +02:00
yasien_gmail ebab9bae52 update build no to 128 2026-02-18 11:52:30 +02:00
yasien_gmail 82c25c5406 make profile picture expandable 2026-02-18 11:51:44 +02:00
yasien_gmail 3f0fc08a5c update business user edit workflow 2026-02-18 10:56:34 +02:00
yasien_gmail f137ea41ac fix loading indicator alignment for business QR code 2026-02-18 10:41:49 +02:00
yasien_gmail a7effa3576 Update profile link and business card Icons alignment 2026-02-18 10:26:41 +02:00
yasien_gmail 74341a9cc6 Enhance Mzansi Profile Look & Feel and workflow 2026-02-18 10:18:03 +02:00
yasien_gmail c5267c0540 change follow us link alignments 2026-02-16 16:27:39 +02:00
yasien_gmail d4ba3aaa03 fix short cut icon issue 2026-02-16 15:34:27 +02:00
yasien_gmail 103ccdc022 Add scroll bar to mih 2026-02-16 15:23:16 +02:00
yasien_gmail f8a722eb50 change design on profile links and add git option 2026-02-16 14:43:34 +02:00
yasien_gmail fdb28080e3 fix web cros issues with fixed dev port pt2 2026-02-16 14:42:33 +02:00
yasien_gmail 8a384921c5 fix web cros issues with fixed dev port 2026-02-16 14:41:51 +02:00
yasien_gmail 4b47bf5288 enhacne install/ update mih button to cater for huawei 2026-02-16 14:08:00 +02:00
yasien_gmail 141611b84d fix mzansi ai modal 2026-02-16 13:43:15 +02:00
yasien_gmail a29d0afeb8 update version number of mih 2026-02-16 13:25:46 +02:00
yasien_gmail eb93714022 add ds_store file to ingore file 2026-02-16 13:09:33 +02:00
yasien_gmail 071612a521 BUG: API Wildcard CROS issue 2026-02-16 13:09:33 +02:00
yasien_gmail 726a60ad25 BUG: Fix exposed ports on mih server 2026-02-16 13:09:33 +02:00
yasien_gmail b897986c1f BUG: Fix hardcoded supertoken api key 2026-02-16 13:09:33 +02:00
yasien_gmail 7d4d7fc713 BUG: Fix Security Flutter Web server 2026-02-16 13:09:33 +02:00
yasien_gmail 91075255f4 add scrolling to about package 2026-02-10 14:07:05 +02:00
yasien_gmail 5c2f19dcc4 enable linux platform & rename widnow 2026-02-10 11:58:35 +02:00
yaso_meth 58aebbeabe Merge pull request 'ruleset test' (#1) from tester-branch into main
Reviewed-on: #1
2026-02-04 11:18:21 +00:00
yasien_gmail 670480910b ruleset test 2026-02-04 13:16:15 +02:00
yasien_gmail 45c1b247d3 testing 2026-02-04 13:13:21 +02:00
yaso-meth ecd24670e9 Simplify MIH Server start/stop instructions 2026-02-03 16:43:46 +02:00
yaso-meth ab99518ff2 Fix directory name in README for navigation 2026-02-03 16:41:39 +02:00
yaso-meth 6ac6aff59e Update directory name in README for navigation 2026-02-03 16:40:59 +02:00
yasien_gmail 33ca7b613e remove old nginx 2026-02-03 16:31:10 +02:00
yaso-meth e83b0b50ae Merge pull request #265 from yaso-meth/yaso-meth-patch-1
Update README with Gitea and WordPress SQL config
2026-02-03 16:19:38 +02:00
yaso-meth bcd19de256 Update README with Gitea and WordPress SQL config
Add database configuration variables for Gitea and WordPress.
2026-02-03 16:18:48 +02:00
yaso-meth ae36879ec5 Revise title and add introduction in README
Updated project title and added introductory text.
2026-02-03 16:15:41 +02:00
yaso-meth eda609cf7e Update license information for the MIH Project 2026-02-03 15:46:42 +02:00
yaso-meth e1744b09e3 Merge pull request #264 from yaso-meth/V.1.2.5
V.1.2.5
2026-02-03 14:01:14 +02:00
yasien_gmail a3845df8bd Merge branch 'main' into V.1.2.5 2026-02-03 13:57:15 +02:00
yasien_gmail d7eebe152b test file 2026-02-03 13:52:47 +02:00
yasien_gmail d8a807b43e update build to 1.2.5+1.2.6 2026-02-03 13:29:20 +02:00
yasien_gmail 5172017a54 Update MZansi AI prod Model 2026-02-03 13:26:37 +02:00
yasien_gmail 535924691e NEW: Add Mzansi Directory Shortcut 2026-02-03 13:26:17 +02:00
yasien_gmail ca8e0f56ac Remove women4change info and revert colors 2026-02-03 10:17:56 +02:00
yasien_gmail 63071325cb favourite business load fix 2026-02-03 10:15:07 +02:00
yasien_gmail 800cd635c2 Remove profile link from personal profile for now 2026-02-03 10:05:00 +02:00
yasien_gmail f46ce36861 linux app config 2026-02-03 09:57:38 +02:00
yasien_gmail b69fd92b19 Update docker compose file for new architechure 2026-01-29 13:02:24 +02:00
yasien_gmail 9e19dc0fa4 Update API files for new architechure 2026-01-29 13:02:05 +02:00
yasien_gmail 38c40e2dfe Update launch file for new architechure 2026-01-29 13:01:41 +02:00
yasien_gmail 02bbc32d23 Update ignore file for new architechure 2026-01-29 13:01:28 +02:00
yasien_gmail 5b052a1fa9 rename container folders 2026-01-29 11:11:45 +02:00
yasien_gmail d5349d981c update architecture 2026-01-29 11:11:25 +02:00
yasien_gmail d6c28b631a ignore new mih_minio 2026-01-29 11:07:50 +02:00
yasien_gmail 74c5276c94 remove old database ignore 2026-01-29 11:06:01 +02:00
yasien_gmail d5e349d218 ignore new db folder 2026-01-29 11:04:53 +02:00
yasien_gmail 44527c8f10 Add self hosted GIT plaform 2026-01-29 10:08:44 +02:00
yasien_gmail fbb9d8573c pat man loading 2026-01-06 16:49:32 +02:00
yasien_gmail 010fc0bc74 BUG: file viewer opening bug 2025-12-17 20:12:51 +02:00
yasien_gmail 45ac3f03e6 BUG: Supertokens api fix 2025-12-14 23:36:11 +02:00
yasien_gmail eea3248525 NEW: MIH Profile Links pt1 2025-12-11 12:57:12 +02:00
yasien_gmail b945a34ad4 BUG: Profile set up bug 2025-12-10 19:42:55 +02:00
yasien_gmail e3ac1be71c BUG: Business Profile Vew pt2 2025-12-10 12:52:31 +02:00
yasien_gmail 3a955e67ef BUG: Business Profile Vew 2025-12-10 12:52:13 +02:00
yasien_gmail 777043e2ca NEW: Config firebase Cloud Messaging for Notifications 2025-12-10 10:18:57 +02:00
yasien_gmail 6a8b9c6902 QOL: Package Tile Update 2025-12-09 19:14:50 +02:00
yasien_gmail 07360dd308 QOL: only get user data if user is null 2025-12-09 11:46:16 +02:00
yasien_gmail 7c59e2a5c8 NEW: New python package added to requirements 2025-12-09 10:54:33 +02:00
yasien_gmail 0b57e10532 QOL: Button alignment 2025-12-08 19:46:21 +02:00
yasien_gmail 5681c6d73b BUG: Patient Manager Data fix pt2 2025-12-04 09:19:30 +02:00
yasien_gmail f44ff6443c BUG: Patient Manager Data fix 2025-12-03 22:01:49 +02:00
yasien_gmail fe5b61f6bc QOL: Switch from Network Image to CachedNetworkImage 2025-12-03 21:42:42 +02:00
yasien_gmail e7729a8ce8 QOL: About MIH Share button update 2025-12-03 21:35:41 +02:00
yasien_gmail 227a2f7ae7 update buiold to 125 2025-12-03 21:09:22 +02:00
yasien_gmail f26c1eb01a QOL: Mzansi Ai LLM detection 2025-12-03 12:31:21 +02:00
yasien_gmail ca0f13a6df build number update to 124 2025-12-03 11:40:29 +02:00
yasien_gmail 021a25f50c QOL: Data display load minesweeper pt1 2025-12-03 11:26:47 +02:00
yasien_gmail 0a9f0c000e QOL: Data display load Mzansi Direct pt4 2025-12-03 11:16:24 +02:00
yasien_gmail 3ff670886c QOL: Data display load Mzansi Direct pt3 2025-12-03 11:08:22 +02:00
yasien_gmail a6d5e4ad35 QOL: Data display load Mzansi Direct pt2 2025-12-03 10:51:18 +02:00
yasien_gmail 456dff6402 QOL: Data display load Mzansi Direct pt1 2025-12-03 10:32:03 +02:00
yasien_gmail d3fdc83373 BUG: incorrect code display style 2025-12-03 09:21:15 +02:00
yasien_gmail 8704d4dd64 BUG: Patient Infor Scrolling 2025-12-02 19:20:24 +02:00
yasien_gmail 37920466ac Update build to 123 2025-12-01 10:51:01 +02:00
yasien_gmail 56d54a3711 QOL: Calanedar message alingment 2025-12-01 10:49:14 +02:00
yasien_gmail aef501cd25 QOL: Cache leaderboard images 2025-12-01 10:40:29 +02:00
yasien_gmail 4f5761271c QOL: Mzansi AI Suggestion update 2025-12-01 10:37:57 +02:00
yasien_gmail 252e120b99 BUG: Business Team list view 2025-12-01 10:36:25 +02:00
yasien_gmail b5c26c3e43 BUG: Mzansi Directory person search on person press 2025-12-01 10:32:26 +02:00
yasien_gmail 74be2fc559 BUG: File list icons 2025-12-01 10:29:02 +02:00
yasien_gmail b519b99a91 QOL: Mzansi Home Scroll 2025-12-01 10:26:17 +02:00
yasien_gmail 72261af7b9 build number update to 122 2025-11-28 13:49:02 +02:00
yasien_gmail ad96725478 QOL: Mzansi Profile Package performance improvements pt2 2025-11-28 13:48:25 +02:00
yasien_gmail ef4c3102a9 QOL: MIH Authentication Package performance improvements 2025-11-28 13:43:51 +02:00
yasien_gmail 9a75bcc810 QOL: MIH Access Controls Package performance improvements pt2 2025-11-28 13:38:14 +02:00
yasien_gmail 586e67b369 QOL: MIH Mine Sweeper Package performance improvements pt2 2025-11-28 13:30:12 +02:00
yasien_gmail e8cae1a894 QOL: MIH Calendar Package performance improvements pt2 2025-11-28 13:26:32 +02:00
yasien_gmail cd8115c597 QOL: Patient Manager Package performance improvements pt2 2025-11-28 13:22:54 +02:00
yasien_gmail 730c5d2bdf QOL: MIH Package performance improvements pt2 2025-11-28 13:13:27 +02:00
yasien_gmail cea8ccab5a QOL: Mzansi Wallet Package performance improvements pt2 2025-11-28 13:02:34 +02:00
yasien_gmail 4f168c5b0e QOL: MIH About Package performance improvements 2025-11-28 12:57:19 +02:00
yasien_gmail 99f8b1a3f9 QOL: MIH Access Controls Package performance improvements 2025-11-28 12:54:31 +02:00
yasien_gmail 30c06261c8 QOL: MIH Mine Sweeper Package performance improvements 2025-11-28 12:52:33 +02:00
yasien_gmail c843c0a55d QOL: MIH Calculator Package performance improvements 2025-11-28 12:47:44 +02:00
yasien_gmail 94ac83db9e QOL: Mzansi AI Package performance improvements 2025-11-28 12:44:51 +02:00
yasien_gmail a3b8da5357 QOL: MIH Calendar Package performance improvements 2025-11-28 12:43:07 +02:00
yasien_gmail 47bc23c029 QOL: Patient Manager Package performance improvements 2025-11-28 12:41:30 +02:00
yasien_gmail c16d8b6e91 QOL: Mzansi Wallet Package performance improvements 2025-11-28 12:31:39 +02:00
yasien_gmail a6fe4499d0 QOL: Mzansi Profile Package performance improvements 2025-11-28 12:29:09 +02:00
yasien_gmail 004c2397c5 QOL: MIH Home Package performance improvements 2025-11-28 12:15:12 +02:00
yasien_gmail d64193d1f8 QOL: MIH Package performance improvements 2025-11-28 12:14:20 +02:00
yasien_gmail e330875c6f build update to 121 2025-11-28 11:43:38 +02:00
yasien_gmail 3d2addf1d6 BUG: fav bus view fix performace pt 2 2025-11-28 11:33:26 +02:00
yasien_gmail 3b6e1d22ec build update to 120 2025-11-28 10:30:33 +02:00
yasien_gmail ff913c0c54 BUG: fav bus view fix 2025-11-28 10:26:36 +02:00
yasien_gmail c45c933277 Update version and build 2025-11-27 13:16:30 +02:00
yasien_gmail 89d6999abf BUG: patient profile picture in patient manager 2025-11-27 13:14:40 +02:00
yasien_gmail 969ecf8fdc BUG: User search piture load 2025-11-27 12:57:15 +02:00
yasien_gmail ee7d3881e6 BUG: Image loading of businesses 2025-11-27 12:40:34 +02:00
yasien_gmail cc3f18f7e2 QOL: Mzansi AI Enhancement pt1 2025-11-27 09:48:42 +02:00
yasien_gmail 08bfe1d417 Update build to 118 2025-11-25 16:51:03 +02:00
yasien_gmail 3593011d6d minio storage uploud fix pt9 2025-11-25 16:47:42 +02:00
yasien_gmail 5ae11f6625 minio storage uploud fix pt8 2025-11-25 16:40:48 +02:00
yasien_gmail a61bca7d81 minio storage uploud fix pt7 2025-11-25 16:31:13 +02:00
yasien_gmail fb3b033f45 minio storage uploud fix pt6 2025-11-25 16:11:28 +02:00
yasien_gmail 91a2d0dd1e minio storage uploud fix pt5 2025-11-25 16:08:20 +02:00
yasien_gmail 04c643561b minio storage uploud fix pt4 2025-11-25 16:05:53 +02:00
yasien_gmail 526bd40255 minio storage uploud fix pt3 2025-11-25 15:53:09 +02:00
yasien_gmail 1889f6cada minio storage uploud fix pt2 2025-11-25 15:39:23 +02:00
yasien_gmail c1dd9a60f2 minio storage uploud fix pt1 2025-11-25 15:31:53 +02:00
yasien_gmail ec869c54c3 minio storage fix pt14 2025-11-25 15:29:07 +02:00
yasien_gmail b440c0a42b minio storage fix pt13 2025-11-25 15:24:02 +02:00
yasien_gmail baa826c52c minio storage fix pt12 2025-11-25 15:22:27 +02:00
yasien_gmail 6b530529e3 minio storage fix pt11 2025-11-25 15:20:58 +02:00
yasien_gmail a633b52949 minio storage fix pt10 2025-11-25 15:16:41 +02:00
yasien_gmail c103d1979c minio storage fix pt9 2025-11-25 15:12:38 +02:00
yasien_gmail 82c01cb7bf minio storage fix pt8 2025-11-25 15:05:16 +02:00
yasien_gmail 43bc552698 minio storage fix pt7 2025-11-25 15:00:20 +02:00
yasien_gmail bb6a8e3090 minio storage fix pt6 2025-11-25 14:49:56 +02:00
yasien_gmail 565e9199d4 minio storage fix pt5 2025-11-25 14:38:59 +02:00
yasien_gmail c5de46040d minio storage fix pt4 2025-11-25 14:31:37 +02:00
yasien_gmail 934b1b2301 minio storage fix pt3 2025-11-25 13:51:42 +02:00
yasien_gmail 302152449f minio storage fix pt2 2025-11-25 13:42:46 +02:00
yasien_gmail 0f591bd111 minio storage fix 2025-11-25 13:37:20 +02:00
yaso-meth ea04c000cf Merge pull request #263 from yaso-meth/V.1.2.3
V.1.2.3
2025-11-25 12:27:36 +02:00
yasien_gmail a59d2bf336 update build to 117 2025-11-25 11:40:22 +02:00
yasien_gmail d5fcad8fa5 BUG: Image display when error 2025-11-25 11:38:19 +02:00
yasien_gmail 609828a26c update build to 116 2025-11-25 11:18:46 +02:00
yasien_gmail d0a5c6c858 QOL: Mzansi AI trigger from home 2025-11-25 11:16:18 +02:00
yasien_gmail 4a293c0aa4 add toot titles to missing packages 2025-11-25 10:45:39 +02:00
yasien_gmail d51d13a685 update build to 115 2025-11-21 12:15:34 +02:00
yasien_gmail bf6bda04a6 get business data when opening mxzansi profile as standalone 2025-11-21 12:14:03 +02:00
yasien_gmail b749dc62d9 fix alert padding for desktop 2025-11-21 12:11:51 +02:00
yasien_gmail b82a5a72c7 NEW: Hide sensitive data on my business user 2025-11-21 11:59:34 +02:00
yasien_gmail 56ab6bb950 QOL: use advanced varding when adding & removing card to fav 2025-11-21 10:27:22 +02:00
yasien_gmail bb54605ddb QOL: Create advanced warning alert 2025-11-21 10:26:57 +02:00
yasien_gmail c4b3a12213 BUG: add jpeg icons 2025-11-21 10:17:24 +02:00
yasien_gmail 43d715f4f8 QOL: Reorder Minesweeper alert buttons 2025-11-21 10:16:19 +02:00
yasien_gmail a9d6ca1baa QOL: Get loaction in bg 2025-11-21 10:12:51 +02:00
yasien_gmail dfcfced28f BUG: Remove hint when keyboard is open 2025-11-21 09:57:12 +02:00
yasien_gmail d0474fed21 BUG: Social Links colour fix 2025-11-21 09:44:06 +02:00
yasien_gmail f228307859 Update Business QR code share text 2025-11-21 09:34:40 +02:00
yasien_gmail ab9cbce41c BUG: remove token text in reset password 2025-11-21 09:34:16 +02:00
yasien_gmail 70413cc294 QOL: About MIH button placement 2025-11-21 09:33:45 +02:00
yasien_gmail a4d510f023 v.1.2.4 Build Number Updated to 114 2025-11-20 11:22:24 +02:00
yasien_gmail e99388711d v.1.2.3 pt 2 Build Number Updated to 113 2025-11-20 11:05:29 +02:00
yasien_gmail 00cd5488e3 NEW: MIh Alerts 2025-11-20 10:56:15 +02:00
yasien_gmail b69a52a5a8 Mih File Structure enhancement 2025-11-18 12:42:22 +02:00
yasien_gmail f5c05d7431 remove prints 2025-11-17 12:59:19 +02:00
yasien_gmail 0403d8c4b5 fix naming convention 2025-11-17 12:58:24 +02:00
yasien_gmail fb7bf4ad65 QOL: Remove legacy layout widgets 2025-11-17 12:56:18 +02:00
yasien_gmail 3417299989 NEW: create new file viewer with MIH package 2025-11-17 12:55:34 +02:00
yasien_gmail 66887d23f8 QOL: MIH Go Router get data on package open pt2 2025-11-17 11:32:39 +02:00
yasien_gmail f064730dcf QOL: Patient Manager get data on package open pt2 2025-11-17 11:32:23 +02:00
yasien_gmail a49505c153 QOL: MIH Test Package get data on package open 2025-11-17 11:25:51 +02:00
yasien_gmail 9d898d8dff QOL: Mzansi profile Business get data on package open 2025-11-17 11:25:37 +02:00
yasien_gmail c517075197 QOL: MIH Acces Controls get data on package open 2025-11-17 11:17:16 +02:00
yasien_gmail 2dc3396fcc QOL: MIH Minesweeper get data on package open 2025-11-17 11:09:38 +02:00
yasien_gmail d318b17b18 QOL: Mzansi AI get data on package open 2025-11-17 11:05:59 +02:00
yasien_gmail 4221ae73b9 QOL: MIH Calendar get data on package open 2025-11-17 10:59:47 +02:00
yasien_gmail b49e93825e QOL: Mzansi Directory get data on package open 2025-11-17 10:53:52 +02:00
yasien_gmail 790bf0e4f8 QOL: Patient Manager get data on package open 2025-11-17 10:46:24 +02:00
yasien_gmail a0bd74b703 QOL: Mzansi Wallet get data on package open 2025-11-17 10:46:09 +02:00
yasien_gmail 96daf77b45 QOL: Mzansi profile Personal get data on package open 2025-11-17 10:45:57 +02:00
yasien_gmail 77ffd95fb6 QOL: MIH Home get data on package open 2025-11-17 10:45:31 +02:00
yasien_gmail 24cc7f64b5 QOL: Update file service 2025-11-17 09:24:32 +02:00
yasien_gmail d76512c11f BUG: dont initialise shortcuts on web 2025-11-14 14:25:32 +02:00
yasien_gmail e1e7542a6d optimisation web pt 3 2025-11-14 14:22:30 +02:00
yasien_gmail 121cde211f optimisation web pt 2 2025-11-14 14:22:30 +02:00
yasien_gmail b79decf04f cancel timeout on load 2025-11-14 14:22:30 +02:00
yasien_gmail a26b826729 increase timeut time 2025-11-14 14:22:30 +02:00
yasien_gmail cc3d1ae430 web load v2 2025-11-14 14:22:30 +02:00
yasien_gmail 329e450f5b revert 2025-11-14 14:22:30 +02:00
yasien_gmail 0a03b1c60c web loadtime 2025-11-14 14:22:30 +02:00
yasien_gmail 652d4bb2fd increase load 2025-11-14 14:22:30 +02:00
yasien_gmail 5903fcd31a reduce load speed 2025-11-14 14:22:30 +02:00
yasien_gmail b0825fe7cb optimisation web pt 3 2025-11-14 14:02:55 +02:00
yasien_gmail 8a2debcaa8 optimisation web pt 2 2025-11-14 13:53:20 +02:00
yasien_gmail 609c8d46db cancel timeout on load 2025-11-14 13:04:04 +02:00
yasien_gmail 1387fb1af5 increase timeut time 2025-11-14 12:52:11 +02:00
yasien_gmail 1f73aa3b87 web load v2 2025-11-14 12:47:15 +02:00
yasien_gmail 47ca6d7311 revert 2025-11-14 12:33:35 +02:00
yasien_gmail 64443a5076 web loadtime 2025-11-14 12:22:21 +02:00
yasien_gmail 20d5bc4004 increase load 2025-11-14 12:07:36 +02:00
yasien_gmail 9257786191 reduce load speed 2025-11-14 11:28:52 +02:00
yasien_gmail 66db154b02 user service update 2025-11-14 11:27:02 +02:00
yasien_gmail 5770f6c353 QOL: Patient Manager overhaul pt3 2025-11-14 11:27:02 +02:00
yasien_gmail c5713cf6e0 QOL: Patient Manager overhaul pt2 2025-11-14 11:27:02 +02:00
yasien_gmail 4fe544b35f QOL: Patient Manager overhaul pt1 2025-11-14 11:27:02 +02:00
yasien_gmail 6542f1c399 QOL: MIh WIndows ehnacement 2025-11-14 11:27:02 +02:00
yaso-meth 963a708ab8 Merge pull request #262 from yaso-meth/V.1.2.3
V.1.2.3
2025-11-10 17:03:44 +02:00
yaso-meth 2f0b11e5ba Merge branch 'main' into V.1.2.3 2025-11-10 17:03:31 +02:00
yasien_gmail d9b2598bca update web icoon 2025-11-10 16:59:14 +02:00
yasien_gmail 0c15bd3e90 iod svg assets 2025-11-10 16:57:49 +02:00
yasien_gmail 0daffb5041 QOL: Mzansi AI Chat Look and Feel & Startup question pt6 2025-11-10 15:36:38 +02:00
yasien_gmail 9485213d6e NEW: MIH Shortcuts pt3 2025-11-10 15:36:22 +02:00
yasien_gmail 9a8f157451 QOL: Mzansi AI Chat Look and Feel & Startup question pt5 2025-11-10 14:48:15 +02:00
yasien_gmail a6f6cdaace NEW: MIH Stands with Women For Change SA 2025-11-10 14:19:40 +02:00
yasien_gmail effbac2c91 NEW: MIH Colors W4C 2025-11-10 13:59:21 +02:00
yasien_gmail f8de726959 QOL: Mzansi AI Chat Look and Feel & Startup question pt4 2025-11-10 13:35:04 +02:00
yasien_gmail 01220144c3 NEW: MIH Loading revamp 2025-11-10 13:34:41 +02:00
yasien_gmail 3f93cc9a7a NEW: MIH Shortcuts pt2 2025-11-10 13:34:15 +02:00
yasien_gmail 83a16bad79 NEW: MIH Shortcuts pt1 2025-11-08 03:02:47 +02:00
yasien_gmail d2f93db580 include busines home 2025-11-07 15:04:52 +02:00
yasien_gmail a3c1963d30 QOL: Mzansi AI Chat Look and Feel & Startup question pt3 2025-11-07 15:03:36 +02:00
yasien_gmail 8e6ef25954 QOL: Mzansi AI Chat Look and Feel pt2 & Startup question 2025-11-07 14:44:42 +02:00
yasien_gmail 580fa027f2 QOL: Build number update to 103 2025-11-07 14:44:42 +02:00
yasien_gmail 9346cccd20 BUG: Get patient data from tile 2025-11-07 14:44:42 +02:00
yasien_gmail 51f2435c33 QOL: Update Mzansi AI System PRompt 2025-11-07 14:44:42 +02:00
yasien_gmail ba5772f3ac NFC deep linking 2025-11-07 14:44:42 +02:00
yasien_gmail 662d20617d QOL: Update build to 101 2025-11-07 14:44:42 +02:00
yasien_gmail e6d1cf0268 favourite business fix 2025-11-07 14:44:42 +02:00
yasien_gmail ed7c5a2269 IOS encryption compliance 2025-11-07 14:44:42 +02:00
yasien_gmail 98beb20827 deeplinking fix 2025-11-07 14:44:07 +02:00
yasien_gmail 76a54ce969 QOL: Update build to 100 2025-11-07 14:44:07 +02:00
yasien_gmail c53f30035d BUG: Update Appointment & Clear Coltrollers 2025-11-07 14:44:07 +02:00
yasien_gmail ec01e2212b BUG: Bookmarked businesses data load 2025-11-07 14:44:07 +02:00
yasien_gmail f840418caf BUG: back Nav from favourite business selection 2025-11-07 14:44:07 +02:00
yasien_gmail 76d24a8e2b BUG: Business Profile Tool Transitions 2025-11-07 14:44:07 +02:00
yasien_gmail 821cbc0a0d BUG: Set up patient flow 2025-11-07 14:44:07 +02:00
yasien_gmail ea25598144 QOL: update guide 2025-11-07 14:44:07 +02:00
yasien_gmail 70fc306789 QOL: Change reset game to start new game 2025-11-07 14:44:07 +02:00
yasien_gmail ba46f38497 BUG: MIH Ad Display Strategy 2025-11-07 14:44:07 +02:00
yasien_gmail 67692967c3 BUG: Add card refresh list 2025-11-07 14:44:07 +02:00
yasien_gmail cc51afadb3 BUG: Menue showing in claims in personal mode 2025-11-07 14:44:07 +02:00
yasien_gmail d9fb9dd758 QOL: Mzansi AI Chat Look and Feel pt2 & Startup question 2025-11-07 14:29:05 +02:00
yasien_gmail d75da5389a QOL: Mzansi AI Chat Look and Feel pt1 2025-11-07 12:03:44 +02:00
yaso-meth efaf9b3574 Merge pull request #261 from yaso-meth/V.1.2.2
V.1.2.2
2025-11-06 08:35:35 +02:00
yasien_gmail 763c4cdb54 QOL: Build number update to 103 2025-11-05 10:04:30 +02:00
yasien_gmail b37f0f71db BUG: Get patient data from tile 2025-11-05 09:59:58 +02:00
yasien_gmail 8ceb443964 QOL: Update Mzansi AI System PRompt 2025-11-05 09:44:54 +02:00
yasien_gmail a87e52d22c NFC deep linking 2025-11-04 12:29:55 +02:00
yasien_gmail 46c281d288 QOL: Update build to 101 2025-11-04 12:07:47 +02:00
yasien_gmail 5289cf8511 favourite business fix 2025-11-04 12:07:00 +02:00
yasien_gmail 22ae804c2d IOS encryption compliance 2025-11-04 12:06:49 +02:00
yasien_gmail 1a7293fc12 deeplinking fix 2025-11-04 11:43:47 +02:00
yasien_gmail e318e03805 QOL: Update build to 100 2025-11-04 11:36:04 +02:00
yasien_gmail 11b6ec9edb BUG: Update Appointment & Clear Coltrollers 2025-11-04 11:34:28 +02:00
yasien_gmail 2a7e3e17ce BUG: Bookmarked businesses data load 2025-11-04 11:00:29 +02:00
yasien_gmail 9cbdc849b1 BUG: back Nav from favourite business selection 2025-11-04 10:17:38 +02:00
yasien_gmail 0cabe11ab7 BUG: Business Profile Tool Transitions 2025-11-04 10:15:34 +02:00
yasien_gmail a561f4fa5f BUG: Set up patient flow 2025-11-03 19:28:52 +02:00
yasien_gmail 429e91b638 QOL: update guide 2025-11-03 13:12:16 +02:00
yasien_gmail c0d152002c QOL: Change reset game to start new game 2025-11-03 11:30:46 +02:00
yasien_gmail 1329c8aba4 BUG: MIH Ad Display Strategy 2025-11-03 11:27:44 +02:00
yasien_gmail 52f9eb7ba6 BUG: Add card refresh list 2025-11-03 10:18:29 +02:00
yasien_gmail bcff545dd7 BUG: Menue showing in claims in personal mode 2025-11-03 09:25:16 +02:00
yasien_gmail 6a5b4f7f4b QOL: Location compliance update for app store 2025-11-03 09:20:14 +02:00
yaso-meth b2b9d8f046 Merge pull request #260 from yaso-meth/V.1.2.2
V.1.2.2
2025-10-31 13:16:34 +02:00
yaso-meth 4c39e9163b Merge branch 'main' into V.1.2.2 2025-10-31 13:15:41 +02:00
yaso-meth 6541ac883f Merge pull request #259 from yaso-meth/V.1.2.1
Add Meta Add Mediation & Build Update
2025-10-31 13:14:47 +02:00
yasien_gmail ffe9f6e9fb NEW: Version Update 2025-10-31 12:53:37 +02:00
yasien_gmail 8e6f3d7d45 Android Config Changes 2025-10-31 12:52:58 +02:00
yasien_gmail abd56d5a14 Clean up 2025-10-31 12:18:13 +02:00
yasien_gmail cb25b932ba NEW: Patient Manager Provider Setup pt4 2025-10-31 11:55:49 +02:00
yasien_gmail 771d809ce2 NEW: MIH MineSweeper Package pt4 2025-10-31 11:55:31 +02:00
yasien_gmail d6f1629485 NEW: MIH MineSweeper Package Pt 3 2025-10-30 11:58:46 +02:00
yasien_gmail 39a42048c2 NEW: Patient Manager Provider Setup pt3 2025-10-29 15:43:05 +02:00
yasien_gmail 99d0fa4aa8 NEW: Patient Manager Provider Setup pt2 2025-10-29 13:59:09 +02:00
yasien_gmail 79ed959b42 BUG: Dropdown search text disabled 2025-10-29 13:17:05 +02:00
yasien_gmail 23c3cf4173 NEW: MIH MineSweeper Package pt2 2025-10-29 13:06:55 +02:00
yasien_gmail f548db7d82 NEW: Patient Manager Provider Setup pt1 2025-10-27 18:46:20 +02:00
yasien_gmail fd2f3a2138 BUG: Fix MIH Logo press on app drawer 2025-10-24 13:11:42 +02:00
yasien_gmail 1fe817919f QOL: Fix New User Setup flow 2025-10-24 13:00:19 +02:00
yasien_gmail 656e1cd3d7 QOL: reset providers on signout and signin 2025-10-24 12:59:11 +02:00
yasien_gmail a9ea3594b9 QOL: Add reset function to providers 2025-10-24 12:58:29 +02:00
yasien_gmail 7de2cb7b36 QOL: Update Alert title size 2025-10-24 12:57:49 +02:00
yasien_gmail ac22e50eca Change patient profile folder to patient manager 2025-10-23 11:01:39 +02:00
yasien_gmail 9bd039ca25 NEW: Mzansi Directory Provider Setup 2025-10-22 14:43:01 +02:00
yasien_gmail b0d38b4b11 NEW: MIH Access Controlls Provider Setup 2025-10-21 15:42:38 +02:00
yasien_gmail 926b749fa8 NEW: MIH Calendar Provider Setup 2025-10-21 13:00:52 +02:00
yasien_gmail b2ed1e0b51 NEW: About MIH Provider Setup pt2 2025-10-21 10:46:50 +02:00
yasien_gmail 3dc9ce30e6 NEW: MIH Calc Provider Setup pt2 2025-10-21 10:45:15 +02:00
yasien_gmail 91241aa399 NEW: Mzansi AI Provider Setup 2025-10-21 10:40:40 +02:00
yasien_gmail c79904d132 NEW: complete provider mzansi wallet 2025-10-21 10:22:20 +02:00
yasien_gmail 15106d0a00 NEW: fix home nav 2025-10-21 09:53:37 +02:00
yasien_gmail 2e69e1dd92 NEW: MIH Home & Mzansi Profile Provider Setup pt 2 done 2025-10-20 16:41:24 +02:00
yasien_gmail c89932755f BUG: Tab movement on password fields 2025-10-20 11:18:06 +02:00
yasien_gmail 540e13dfe0 mine sweeper pt2 2025-10-17 08:24:23 +02:00
yasien_gmail d51603ff5d NEW: MIH Home & Mzansi Profile Provider Setup pt 1 2025-10-16 10:16:18 +02:00
yasien_gmail 553d22dd6b BUG: Package Auth Loop 2025-10-16 09:59:52 +02:00
yasien_gmail 5f5107ee99 QOL: Add Long Press to mih button 2025-10-16 09:46:02 +02:00
yasien_gmail 6ecce1e9ff NEW: MIH MineSweeper Package pt1 2025-10-16 09:45:17 +02:00
yasien_gmail 22d8c64994 QOL: Change Users to People in About MIH 2025-10-16 09:03:02 +02:00
yasien_gmail ebd78eb72b NEW: MIH Authentication Provider Setup 2025-10-13 11:14:11 +02:00
yasien_gmail f828ba1786 NEW: About MIH Provider Setup 2025-10-13 10:45:30 +02:00
yasien_gmail bbadc58ab8 NEW: MIH Calculator Provider Setup 2025-10-08 15:06:04 +02:00
yasien_gmail a1b7a3ef28 NEW: MIH Banner Ads Provider Set Up 2025-10-08 14:43:03 +02:00
yasien_gmail 7373a1b8cb NEW: Mzansi Wallet Provider Setup 2025-10-08 13:35:47 +02:00
yasien_gmail 0edbfadc90 NEW: Import & Set Up Provider 2025-10-08 12:53:09 +02:00
yasien_gmail ef479b633d NEW: Add Test Device to main dev 2025-10-08 12:51:52 +02:00
yasien_gmail 081e7d5533 BUG: Special Chars in Business Type 2025-10-08 09:40:34 +02:00
yasien_gmail 18e8217ce1 NEW: Engen Card Added to Mzansi Wallet 2025-10-07 11:45:37 +02:00
yasien_gmail cadd51535e Add Meta Ads SDK 2025-10-07 10:38:26 +02:00
yasien_gmail ba394e7fea BUG: Business QR Code Picture Display 2025-10-07 10:38:04 +02:00
yasien_gmail 04c92804b8 BUG: Fix blank screen on load 2025-10-07 09:49:18 +02:00
yaso-meth a2d1bebca1 Merge pull request #258 from yaso-meth/V.1.2.1
app sign pt2
2025-10-03 09:49:37 +02:00
yaso-meth 1a448572ea Merge pull request #257 from yaso-meth/V.1.2.1
app signing
2025-10-02 15:35:25 +02:00
yaso-meth 04b247aa99 Merge pull request #256 from yaso-meth/V.1.2.1
BUG: Mzansi Wallet Card Scanner
2025-10-02 13:55:34 +02:00
yaso-meth aa0d756979 Merge pull request #255 from yaso-meth/V.1.2.1
fix docker compose alignment
2025-10-01 09:27:13 +02:00
yaso-meth 16f50f826b Merge pull request #254 from yaso-meth/V.1.2.1
V.1.2.1 First Push
2025-10-01 09:22:45 +02:00
942 changed files with 39271 additions and 36710 deletions
Vendored
BIN
View File
Binary file not shown.
+7 -9
View File
@@ -1,16 +1,14 @@
# *database/auto.cnf
# *database/binlog.index
# *database/mysql.sock
File_Storage
database/
mih_minio/
mih_db/
mih_git/
mih_nginx/
mih_monitor/
mih_wp/
certbot/
Firebase-emulator/
Mzansi_Mail/
# database/ibdata1
# database/mysql.ibd
# database/undo*
# database/#innodb_redo/#ib_redo*
.venv
google-chrome-stable_current_amd64.deb
.env
Frontend/android/app/.cxx/
.DS_Store
+14 -3
View File
@@ -6,14 +6,25 @@
"configurations": [
{
"name": "Debug",
"cwd": "Frontend",
"cwd": "mih_ui",
"request": "launch",
"type": "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",
"cwd": "Frontend",
"cwd": "mih_ui",
"request": "launch",
"type": "dart",
"flutterMode": "profile",
@@ -21,7 +32,7 @@
},
{
"name": "Release",
"cwd": "Frontend",
"cwd": "mih_ui",
"request": "launch",
"type": "dart",
"flutterMode": "release",
-45
View File
@@ -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'
-48
View File
@@ -1,48 +0,0 @@
# Install Operating system and dependencies
#FROM ubuntu:22.04
FROM debian:latest AS build-env
#ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update --fix-missing
RUN apt-get install -y curl git wget unzip gdb libstdc++6 libglu1-mesa fonts-droid-fallback
# RUN apt-get install -y curl git wget unzip libgconf-2-4 gdb libstdc++6 libglu1-mesa fonts-droid-fallback
RUN apt-get install python3 -y
# download Flutter SDK from Flutter Github repo
RUN git clone -b flutter-3.32-candidate.0 https://github.com/flutter/flutter.git /usr/local/flutter
# RUN git clone -b stable https://github.com/flutter/flutter.git /usr/local/flutter
# Set flutter environment path
ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}"
#ENV PATH "$PATH:/home/developer/flutter/bin"
RUN flutter doctor -v
# Enable flutter web
RUN flutter channel flutter-3.32-candidate.0
# RUN flutter channel stable
RUN flutter config --enable-web
# Copy files to container and build
RUN mkdir /app/
COPY . /app/
WORKDIR /app
# RUN flutter upgrade
RUN flutter build web --release -t ./lib/main_prod.dart
# RUN flutter build web --release --web-renderer canvaskit -t ./lib/main_prod.dart
# RUN cd ..
# WORKDIR /app/build/web/
EXPOSE 83
RUN ["chmod", "+x", "/app/server/server.sh"]
ENTRYPOINT [ "/app/server/server.sh"]
# RUN ["python3", "-u", "/app/server/MIH_web_server.py"]
@@ -1,5 +0,0 @@
package za.co.mzansiinnovationhub.mih
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

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>
-32
View File
@@ -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"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

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"}}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

-77
View File
@@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-4781880856775334~6935644635</string>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>MIH</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>mzansi_innovation_hub</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>sms</string>
<string>tel</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes</string>
<key>NSFaceIDUsageDescription</key>
<string>Why is my app authenticating using face id?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs to access your photo library to select images.</string>
<key>NSDownloadsFolderUsageDescription</key>
<string>This app needs to access your downloads folder to select files from there.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
-84
View File
@@ -1,84 +0,0 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:upgrader/upgrader.dart';
import 'mih_config/mih_env.dart';
import 'mih_config/mih_theme.dart';
class MzansiInnovationHub extends StatefulWidget {
final GoRouter router;
const MzansiInnovationHub({
super.key,
required this.router,
});
@override
State<MzansiInnovationHub> createState() => _MzansiInnovationHubState();
// ignore: library_private_types_in_public_api
static _MzansiInnovationHubState? of(BuildContext context) =>
context.findAncestorStateOfType<_MzansiInnovationHubState>();
}
class _MzansiInnovationHubState extends State<MzansiInnovationHub> {
late MihTheme theme;
Color getPrimany() {
return MihColors.getPrimaryColor(theme.mode == "Dark");
}
String getTitle() {
if (AppEnviroment.getEnv() == "Dev") {
return "Dev | MIH App: Mzansi Innovation Hub";
} else {
return "MIH App: Mzansi Innovation Hub";
}
}
void changeTheme(ThemeMode themeMode) {
setState(() {
if (themeMode == ThemeMode.light) {
setState(() {
theme.mode = "Light";
});
} else if (themeMode == ThemeMode.dark) {
setState(() {
theme.mode = "Dark";
});
} else {
setState(() {
theme.mode = "Dark";
});
}
});
}
@override
void initState() {
theme = MihTheme();
super.initState();
theme.mode = "Dark";
theme.platform = Theme.of(context).platform;
}
@override
Widget build(BuildContext context) {
double width = MediaQuery.sizeOf(context).width;
theme.setScreenType(width);
precacheImage(theme.loadingImage(), context);
return MaterialApp.router(
title: getTitle(),
themeMode: ThemeMode.dark,
theme: theme.getThemeData(),
darkTheme: theme.getThemeData(),
debugShowCheckedModeBanner: false,
routerConfig: widget.router,
builder: (context, child) {
return UpgradeAlert(
navigatorKey: widget.router.routerDelegate.navigatorKey,
child: child ?? const Text('Upgrade Alert'),
);
},
);
}
}
@@ -1,38 +0,0 @@
import 'package:flutter/material.dart';
class MIHAction extends StatefulWidget {
final void Function()? onTap;
final double iconSize;
final Widget icon;
const MIHAction({
super.key,
required this.icon,
required this.iconSize,
required this.onTap,
});
@override
State<MIHAction> createState() => _MIHActionState();
}
class _MIHActionState extends State<MIHAction> {
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return IconButton(
iconSize: widget.iconSize,
padding: const EdgeInsets.all(0),
onPressed: widget.onTap,
icon: widget.icon,
);
}
}
@@ -1,106 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import '../../main.dart';
class MIHBody extends StatefulWidget {
final bool borderOn;
final List<Widget> bodyItems;
const MIHBody({
super.key,
required this.borderOn,
required this.bodyItems,
});
@override
State<MIHBody> createState() => _MIHBodyState();
}
class _MIHBodyState extends State<MIHBody> {
//double paddingSize = 10;
double getHorizontalPaddingSize(Size screenSize) {
if (MzansiInnovationHub.of(context)!.theme.screenType == "desktop") {
if (widget.borderOn) {
return 10;
} else {
return 0;
}
} else {
// mobile
if (widget.borderOn) {
return 10;
} else {
return 0;
}
}
}
double getVerticalPaddingSize(Size screenSize) {
// mobile
if (widget.borderOn) {
return 10;
} else {
return 0;
}
}
Decoration? getBoader() {
if (widget.borderOn) {
return BoxDecoration(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
borderRadius: BorderRadius.circular(25.0),
border: Border.all(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
width: 3.0),
);
} else {
return null;
}
}
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
Size screenSize = MediaQuery.sizeOf(context);
return Padding(
padding: EdgeInsets.only(
left: getHorizontalPaddingSize(screenSize),
right: getHorizontalPaddingSize(screenSize),
bottom: getVerticalPaddingSize(screenSize),
top: 0,
),
child: Container(
padding: EdgeInsets.only(
left: 10,
right: 10,
bottom: 10,
top: getVerticalPaddingSize(screenSize),
),
width: screenSize.width,
height: screenSize.height,
decoration: getBoader(),
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: widget.bodyItems,
),
),
),
),
);
}
}
@@ -1,39 +0,0 @@
import 'package:flutter/material.dart';
class MIHHeader extends StatefulWidget {
final MainAxisAlignment headerAlignment;
final List<Widget> headerItems;
const MIHHeader({
super.key,
required this.headerAlignment,
required this.headerItems,
});
@override
State<MIHHeader> createState() => _MIHHeaderState();
}
class _MIHHeaderState extends State<MIHHeader> {
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: 50,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: widget.headerAlignment,
mainAxisSize: MainAxisSize.max,
children: widget.headerItems,
),
);
}
}
@@ -1,152 +0,0 @@
import 'package:flutter/material.dart';
import '../../mih_packages/mih_home/components/mih_app_drawer.dart';
import 'mih_body.dart';
import 'mih_header.dart';
class MIHLayoutBuilder extends StatefulWidget {
final Widget actionButton;
final Widget? secondaryActionButton;
final MIHHeader header;
final MIHBody body;
final MIHAppDrawer? actionDrawer;
final Widget? secondaryActionDrawer;
final Widget? bottomNavBar;
final bool pullDownToRefresh;
final Future<void> Function() onPullDown;
//final String type;
const MIHLayoutBuilder({
super.key,
required this.actionButton,
required this.header,
required this.secondaryActionButton,
required this.body,
required this.actionDrawer,
required this.secondaryActionDrawer,
required this.bottomNavBar,
required this.pullDownToRefresh,
required this.onPullDown,
});
@override
State<MIHLayoutBuilder> createState() => _MIHLayoutBuilderState();
}
class _MIHLayoutBuilderState extends State<MIHLayoutBuilder> {
List<Widget> getList() {
List<Widget> temp = [];
temp.add(widget.header);
temp.add(widget.body);
return temp;
}
// openTheDrawer() {
// _scaffoldKey.currentState!.openEndDrawer();
// }
Widget getLayoutHeader() {
List<Widget> temp = [];
temp.add(widget.actionButton);
temp.add(Flexible(child: widget.header));
if (widget.secondaryActionButton != null) {
temp.add(widget.secondaryActionButton!);
} else {
//print(widget.header.headerItems.length);
if (widget.header.headerItems.length == 1) {
temp.add(const SizedBox(
width: 50,
));
}
}
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: temp,
);
}
Widget getBody(double width, double height) {
if (widget.pullDownToRefresh == true) {
return SafeArea(
child: LayoutBuilder(builder: (context, BoxConstraints constraints) {
double newheight = constraints.maxHeight;
//print(newheight);
return RefreshIndicator(
onRefresh: widget.onPullDown,
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return SafeArea(
child: SizedBox(
width: width,
height: newheight,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 5),
getLayoutHeader(),
const SizedBox(height: 5),
Expanded(child: widget.body),
],
),
),
);
},
// child: SafeArea(
// child: SizedBox(
// width: width,
// height: height,
// child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// getLayoutHeader(),
// Expanded(child: widget.body),
// ],
// ),
// ),
// ),
),
);
}),
);
} else {
return SafeArea(
child: SizedBox(
width: width,
height: height,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 5),
getLayoutHeader(),
const SizedBox(height: 5),
Expanded(child: widget.body),
],
),
),
);
}
}
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
Size screenSize = MediaQuery.sizeOf(context);
return Scaffold(
//drawerEnableOpenDragGesture: true,
drawer: widget.actionDrawer,
endDrawer: widget.secondaryActionDrawer,
body: getBody(screenSize.width, screenSize.height),
bottomNavigationBar: widget.bottomNavBar,
);
}
}
@@ -1,126 +0,0 @@
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_yt_video_player.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MIHTile extends StatefulWidget {
final String tileName;
final String? videoID;
final Widget tileIcon;
final void Function() onTap;
// final Widget tileIcon;
final Color p;
final Color s;
const MIHTile({
super.key,
required this.onTap,
required this.tileName,
this.videoID,
required this.tileIcon,
required this.p,
required this.s,
});
@override
State<MIHTile> createState() => _MIHTileState();
}
class _MIHTileState extends State<MIHTile> {
late Color mainC;
late Color secondC;
@override
void dispose() {
super.dispose();
}
@override
void initState() {
mainC = widget.p;
secondC = widget.s;
super.initState();
}
void displayHint() {
if (widget.videoID != null) {
showDialog(
context: context,
builder: (context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: widget.tileName,
onWindowTapClose: () {
Navigator.pop(context);
},
windowBody: Column(
children: [
MIHYTVideoPlayer(videoYTLink: widget.videoID!),
],
),
);
},
);
}
}
@override
Widget build(BuildContext context) {
// print(
// "Tile Name: ${widget.tileName}\nTitle Type: ${widget.tileIcon.runtimeType.toString()}");
return FittedBox(
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AnimatedContainer(
//alignment: Alignment.center,
width: 250,
height: 250,
duration: const Duration(seconds: 2),
child: Material(
color: mainC,
// shadowColor:
// MihColors.getSecondaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// elevation: 5,
borderRadius: BorderRadius.circular(80),
child: InkWell(
borderRadius: BorderRadius.circular(80),
// ho
onTap: widget.onTap,
onLongPress: () {
displayHint();
},
// hoverDuration: ,
splashColor: MihColors.getHighlightColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
highlightColor: MihColors.getHighlightColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
child: widget.tileIcon,
),
),
),
const SizedBox(height: 10),
SizedBox(
width: 300,
child: Text(
widget.tileName,
textAlign: TextAlign.center,
softWrap: true,
overflow: TextOverflow.visible,
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
)
],
),
);
}
}
@@ -1,164 +0,0 @@
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_tools/package_tool_one.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_tools/package_tool_two.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class PackageTest extends StatefulWidget {
// final AppUser user;
// final Business business;
final TestArguments arguments;
const PackageTest({
super.key,
required this.arguments,
// required this.user,
// required this.business,
});
@override
State<PackageTest> createState() => _PackageTestState();
}
class _PackageTestState extends State<PackageTest> {
int _selcetedIndex = 0;
MihPackageAction getAction() {
return MihPackageAction(
icon: const Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
context.goNamed(
'mihHome',
extra: true,
);
FocusScope.of(context).unfocus();
// Navigator.of(context).pop();
// Navigator.of(context).popAndPushNamed(
// '/',
// arguments: AuthArguments(true, false),
// );
},
);
}
MihPackageTools getTools() {
Map<Widget, void Function()?> temp = Map();
temp[const Icon(Icons.inbox)] = () {
setState(() {
_selcetedIndex = 0;
});
};
temp[const Icon(Icons.outbond)] = () {
setState(() {
_selcetedIndex = 1;
});
};
return MihPackageTools(
tools: temp,
selcetedIndex: _selcetedIndex,
);
}
void showAlert() {
showDialog(
context: context,
builder: (context) {
return MihPackageAlert(
alertIcon: Icon(
Icons.warning_amber_rounded,
size: 100,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
alertTitle: "Oops! Looks like some fields are missing.",
alertBody: Column(
children: [
Text(
"We noticed that some required fields are still empty. To ensure your request is processed smoothly, please fill out all the highlighted fields before submitting the form again.",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 25),
RichText(
text: TextSpan(
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 15,
fontWeight: FontWeight.bold,
),
children: <TextSpan>[
TextSpan(
text: "Here's a quick tip: ",
style: TextStyle(
fontStyle: FontStyle.italic,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"))),
const TextSpan(text: "Look for fields with an asterisk ("),
TextSpan(
text: "*",
style: TextStyle(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"))),
const TextSpan(
text: ") next to them, as these are mandatory."),
],
),
),
],
),
alertColour: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
},
);
}
List<Widget> getToolBody() {
List<Widget> toolBodies = [
PackageToolOne(
user: widget.arguments.user,
business: widget.arguments.business,
),
const PackageToolTwo(),
];
return toolBodies;
}
List<String> getToolTitle() {
List<String> toolTitles = [
"Tool One",
"Tool Two",
];
return toolTitles;
}
@override
Widget build(BuildContext context) {
return MihPackage(
appActionButton: getAction(),
appTools: getTools(),
appBody: getToolBody(),
appToolTitles: getToolTitle(),
selectedbodyIndex: _selcetedIndex,
onIndexChange: (newValue) {
setState(() {
_selcetedIndex = newValue;
});
print("Index: $_selcetedIndex");
},
);
}
}
@@ -1,58 +0,0 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tile.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class TestPackageTile extends StatefulWidget {
final AppUser signedInUser;
final Business? business;
final double packageSize;
const TestPackageTile({
super.key,
required this.signedInUser,
required this.business,
required this.packageSize,
});
@override
State<TestPackageTile> createState() => _TestPackageTileState();
}
class _TestPackageTileState extends State<TestPackageTile> {
@override
Widget build(BuildContext context) {
return MihPackageTile(
onTap: () {
context.goNamed(
'testPackage',
extra: TestArguments(
widget.signedInUser,
widget.business,
),
);
// Navigator.of(context).pushNamed(
// '/package-dev',
// arguments: TestArguments(
// widget.signedInUser,
// widget.business,
// ),
// );
},
appName: "Test",
appIcon: Icon(
Icons.warning_amber_rounded,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
iconSize: widget.packageSize,
primaryColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
secondaryColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

@@ -1,75 +0,0 @@
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
class MihBannerAd extends StatefulWidget {
const MihBannerAd({super.key});
@override
State<MihBannerAd> createState() => _MihBannerAdState();
}
class _MihBannerAdState extends State<MihBannerAd> {
BannerAd? _bannerAd;
bool _isBannerAdLoaded = false;
final adUnitId = AppEnviroment.bannerAdUnitId;
String errorMessage = '';
void _loadBannerAd() {
_bannerAd = BannerAd(
adUnitId: adUnitId,
request: const AdRequest(),
size: AdSize.banner,
listener: BannerAdListener(
onAdLoaded: (ad) {
debugPrint('$ad loaded.');
setState(() {
_isBannerAdLoaded = true;
});
},
onAdFailedToLoad: (ad, err) {
debugPrint('BannerAd failed to load: $err');
setState(() {
errorMessage =
'Failed to load ad- Message: ${err.message} Code :${err.code}';
});
ad.dispose(); // Dispose the ad to free resources
},
onAdOpened: (Ad ad) => debugPrint('$ad opened.'),
onAdClosed: (Ad ad) => debugPrint('$ad closed.'),
onAdImpression: (Ad ad) => debugPrint('$ad impression.'),
),
);
_bannerAd!.load();
}
@override
void dispose() {
_bannerAd?.dispose(); // Dispose the ad when the widget is removed
super.dispose();
}
@override
void initState() {
super.initState();
_loadBannerAd();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
_bannerAd != null && _isBannerAdLoaded
? SizedBox(
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!))
: SizedBox(
child:
Text(AppEnviroment.getEnv() == "Dev" ? errorMessage : ""),
),
],
);
}
}
@@ -1,120 +0,0 @@
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_location_services.dart';
class MihBusinessProfilePreview extends StatefulWidget {
final Business business;
final String? myLocation;
const MihBusinessProfilePreview({
super.key,
required this.business,
required this.myLocation,
});
@override
State<MihBusinessProfilePreview> createState() =>
_MihBusinessProfilePreviewState();
}
class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
late Future<String> futureImageUrl;
PlatformFile? file;
String calculateDistance() {
try {
double distanceInKm = MIHLocationAPI().getDistanceInMeaters(
widget.myLocation!, widget.business.gps_location) /
1000;
return "${distanceInKm.toStringAsFixed(2)} km";
} catch (error) {
print(error);
return "*.** km";
}
}
@override
void initState() {
super.initState();
futureImageUrl =
MihFileApi.getMinioFileUrl(widget.business.logo_path, context);
}
@override
Widget build(BuildContext context) {
double profilePictureWidth = 60;
return Row(
children: [
FutureBuilder(
future: futureImageUrl,
builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState == ConnectionState.done &&
asyncSnapshot.hasData) {
if (asyncSnapshot.requireData != "") {
return MihCircleAvatar(
imageFile: NetworkImage(asyncSnapshot.requireData),
width: profilePictureWidth,
editable: false,
fileNameController: TextEditingController(),
userSelectedfile: file,
frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
onChange: () {},
);
} else {
return Icon(
MihIcons.iDontKnow,
size: profilePictureWidth,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
}
} else {
return Icon(
MihIcons.mihRing,
size: profilePictureWidth,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
}
}),
const SizedBox(width: 15),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.business.Name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
Text(
widget.business.type,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
Text(
widget.myLocation != null || widget.myLocation!.isEmpty
? calculateDistance()
: "0.00 km",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 10,
),
),
],
)
],
);
}
}
@@ -1,65 +0,0 @@
import 'package:flutter/material.dart';
class MihButton extends StatelessWidget {
final void Function()? onPressed;
final Color buttonColor;
final double? width;
final double? height;
final double? borderRadius;
final double? elevation; // 0 = flat, higher = more shadow
final Widget child;
const MihButton({
super.key,
required this.onPressed,
required this.buttonColor,
this.width,
this.height,
this.borderRadius,
this.elevation,
required this.child,
});
Color _darkerColor(Color color, [double amount = .1]) {
final hsl = HSLColor.fromColor(color);
final hslDark = hsl.withLightness((hsl.lightness - amount).clamp(0.0, 1.0));
return hslDark.toColor();
}
@override
Widget build(BuildContext context) {
final Color effectiveButtonColor = onPressed == null
? buttonColor.withValues(alpha: 0.6) // Example disabled color
: buttonColor;
final Color rippleColor = _darkerColor(effectiveButtonColor, 0.1);
final double radius = borderRadius ?? 25.0;
final double effectiveElevation =
onPressed == null ? 0.0 : (elevation ?? 4.0);
return MouseRegion(
cursor: onPressed == null
? SystemMouseCursors.basic
: SystemMouseCursors.click,
child: Material(
color: effectiveButtonColor,
borderRadius: BorderRadius.circular(radius),
elevation: effectiveElevation,
shadowColor: Colors.black,
child: InkWell(
borderRadius: BorderRadius.circular(radius),
splashColor: rippleColor,
highlightColor: rippleColor.withValues(alpha: 0.2),
hoverColor: rippleColor.withValues(alpha: 0.3),
onTap: onPressed,
child: Container(
width: width,
height: height,
padding: (width == null || height == null)
? const EdgeInsets.symmetric(horizontal: 24, vertical: 12)
: null,
alignment: Alignment.center,
child: child,
),
),
),
);
}
}
@@ -1,173 +0,0 @@
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MihCircleAvatar extends StatefulWidget {
final ImageProvider<Object>? imageFile;
final double width;
final bool editable;
final TextEditingController fileNameController;
final onChange;
final PlatformFile? userSelectedfile;
final Color frameColor;
final Color? backgroundColor;
const MihCircleAvatar({
super.key,
required this.imageFile,
required this.width,
required this.editable,
required this.fileNameController,
required this.userSelectedfile,
required this.frameColor,
required this.backgroundColor,
required this.onChange,
});
@override
State<MihCircleAvatar> createState() => _MihCircleAvatarState();
}
class _MihCircleAvatarState extends State<MihCircleAvatar> {
late ImageProvider<Object>? imagePreview;
ImageProvider<Object>? getAvatar() {
// Color dark = const Color(0XFF3A4454);
if (widget.imageFile == null) {
return null;
// if (widget.backgroundColor == dark) {
// print("here in light icon");
// return const AssetImage(
// 'lib/mih_components/mih_package_components/assets/images/i-dont-know-light.png');
// } else {
// print("here in dark icon");
// return const AssetImage(
// 'lib/mih_components/mih_package_components/assets/images/i-dont-know-dark.png');
// }
} else {
return widget.imageFile;
}
}
@override
void initState() {
super.initState();
setState(() {
imagePreview = getAvatar();
});
}
@override
Widget build(BuildContext context) {
return Container(
// color: Colors.white,
alignment: Alignment.center,
width: widget.width,
height: widget.width,
child: Stack(
alignment: Alignment.center,
children: [
Visibility(
visible: imagePreview != null,
child: Positioned(
right: widget.width * 0.03,
child: CircleAvatar(
radius: widget.width / 2.2,
backgroundColor: widget.backgroundColor,
backgroundImage: imagePreview,
),
),
),
Visibility(
visible: imagePreview != null,
child: Icon(
size: widget.width,
MihIcons.mihRing,
color: widget.frameColor,
),
),
Visibility(
visible: imagePreview == null,
child: Icon(
MihIcons.iDontKnow,
size: widget.width,
color: widget.frameColor,
),
),
Visibility(
visible: widget.editable,
child: Positioned(
bottom: 0,
right: 0,
child: IconButton.filled(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
),
onPressed: () async {
try {
FilePickerResult? result =
await FilePicker.platform.pickFiles(
type: FileType.image,
);
// print("Here 1");
if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Web") {
// print("Here 2");
if (result == null) return;
// print("Here 3");
PlatformFile? selectedFile = result.files.first;
setState(() {
// print("Here 4");
widget.onChange(selectedFile);
// print("Here 5");
imagePreview = MemoryImage(selectedFile.bytes!);
});
setState(() {
widget.fileNameController.text = selectedFile.name;
});
} else {
if (result != null) {
File file = File(result.files.single.path!);
PlatformFile? androidFile = PlatformFile(
path: file.path,
name: file.path.split('/').last,
size: file.lengthSync(),
bytes: await file.readAsBytes(), // Read file bytes
//extension: fileExtension,
);
setState(() {
widget.onChange(androidFile);
imagePreview = FileImage(file);
});
setState(() {
widget.fileNameController.text =
file.path.split('/').last;
});
} else {
print("here in else");
// User canceled the picker
}
}
} catch (e) {
print("Error: $e");
}
},
icon: Icon(
Icons.edit,
),
),
),
),
],
),
);
}
}
@@ -1,207 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MihDateField extends StatefulWidget {
final TextEditingController controller;
final String labelText;
final bool required;
final double? width;
final double? height;
final double? borderRadius;
final double? elevation;
final FormFieldValidator<String>? validator;
const MihDateField({
super.key,
required this.controller,
required this.labelText,
required this.required,
this.width,
this.height,
this.borderRadius,
this.elevation,
this.validator,
});
@override
State<MihDateField> createState() => _MihDateFieldState();
}
class _MihDateFieldState extends State<MihDateField> {
FormFieldState<String>? _formFieldState;
Future<void> _selectDate(BuildContext context) async {
DateTime? picked = await showDatePicker(
context: context,
initialDate: widget.controller.text.isNotEmpty
? DateTime.tryParse(widget.controller.text) ?? DateTime.now()
: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2100),
);
if (picked != null) {
widget.controller.text = picked.toString().split(" ")[0];
_formFieldState?.didChange(widget.controller.text);
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return Center(
child: SizedBox(
width: widget.width,
height: widget.height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.labelText,
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
if (!widget.required)
Text(
"(Optional)",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 4),
FormField<String>(
initialValue: widget.controller.text,
validator: widget.validator,
autovalidateMode: AutovalidateMode.onUserInteraction,
builder: (field) {
_formFieldState = field;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Material(
elevation: widget.elevation ?? 4.0,
borderRadius:
BorderRadius.circular(widget.borderRadius ?? 8.0),
child: TextFormField(
controller: widget.controller,
readOnly: true,
onTap: () => _selectDate(context),
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.w500,
),
decoration: InputDecoration(
suffixIcon: Icon(
Icons.calendar_today,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
errorStyle: const TextStyle(height: 0, fontSize: 0),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10.0, vertical: 8.0),
filled: true,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
widget.borderRadius ?? 8.0),
borderSide: field.hasError
? BorderSide(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
width: 2.0,
)
: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
widget.borderRadius ?? 8.0),
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
widget.borderRadius ?? 8.0),
borderSide: BorderSide(
color: field.hasError
? MihColors.getRedColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark")
: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
width: 3.0,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
widget.borderRadius ?? 8.0),
borderSide: BorderSide(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 3.0,
),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
widget.borderRadius ?? 8.0),
borderSide: BorderSide(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 3.0,
),
),
),
onChanged: (value) {
field.didChange(value);
},
),
),
if (field.hasError)
Padding(
padding: const EdgeInsets.only(left: 8.0, top: 4.0),
child: Text(
field.errorText ?? '',
style: TextStyle(
fontSize: 12,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
),
),
),
],
);
},
),
],
),
),
);
}
}
@@ -1,243 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MihDropdownField extends StatefulWidget {
final TextEditingController controller;
final String hintText;
final bool requiredText;
final List<String> dropdownOptions;
final bool editable;
final bool enableSearch;
final FormFieldValidator<String>? validator;
const MihDropdownField({
super.key,
required this.controller,
required this.hintText,
required this.dropdownOptions,
required this.requiredText,
required this.editable,
required this.enableSearch,
this.validator,
});
@override
State<MihDropdownField> createState() => _MihDropdownFieldState();
}
class _MihDropdownFieldState extends State<MihDropdownField> {
late List<DropdownMenuEntry<String>> menu;
List<DropdownMenuEntry<String>> buildMenuOptions(List<String> options) {
List<DropdownMenuEntry<String>> menuList = [];
for (final i in options) {
menuList.add(DropdownMenuEntry(
value: i,
label: i,
style: ButtonStyle(
foregroundColor: WidgetStatePropertyAll(MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark")),
),
));
}
return menuList;
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
menu = buildMenuOptions(widget.dropdownOptions);
}
@override
void initState() {
super.initState();
menu = widget.dropdownOptions
.map((e) => DropdownMenuEntry(value: e, label: e))
.toList();
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.hintText,
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
if (!widget.requiredText)
Text(
"(Optional)",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 4),
FormField<String>(
validator: widget.validator,
autovalidateMode: AutovalidateMode.onUserInteraction,
initialValue: widget.controller.text,
builder: (field) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Theme(
data: Theme.of(context).copyWith(
textSelectionTheme: TextSelectionThemeData(
cursorColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
selectionColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark")
.withValues(alpha: 0.3),
selectionHandleColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
child: DropdownMenu(
controller: widget.controller,
dropdownMenuEntries: menu,
enableSearch: widget.enableSearch,
enableFilter: widget.enableSearch,
enabled: widget.editable,
textInputAction: TextInputAction.search,
requestFocusOnTap: true,
menuHeight: 400,
expandedInsets: EdgeInsets.zero,
textStyle: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.w500,
),
trailingIcon: Icon(
Icons.arrow_drop_down,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
selectedTrailingIcon: Icon(
Icons.arrow_drop_up,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
leadingIcon: IconButton(
onPressed: () {
widget.controller.clear();
field.didChange('');
},
icon: Icon(
Icons.delete_outline_rounded,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
onSelected: (String? selectedValue) {
field.didChange(selectedValue);
},
menuStyle: MenuStyle(
backgroundColor: WidgetStatePropertyAll(
MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark")),
side: WidgetStatePropertyAll(
BorderSide(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 1.0),
),
shape: WidgetStatePropertyAll(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
10), // Increase for more roundness
),
),
),
inputDecorationTheme: InputDecorationTheme(
errorStyle: const TextStyle(height: 0, fontSize: 0),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10.0, vertical: 8.0),
filled: true,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: field.hasError
? MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark")
: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 3.0,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 3.0,
),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 3.0,
),
),
),
),
),
if (field.hasError)
Padding(
padding: const EdgeInsets.only(left: 8.0, top: 4.0),
child: Text(
field.errorText ?? '',
style: TextStyle(
fontSize: 12,
color: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontWeight: FontWeight.bold,
),
),
),
],
);
},
),
],
);
}
}
@@ -1,47 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
class MihFloatingMenu extends StatefulWidget {
final IconData? icon;
final double? iconSize;
final AnimatedIconData? animatedIcon;
final SpeedDialDirection? direction;
final List<SpeedDialChild> children;
const MihFloatingMenu({
super.key,
this.icon,
this.iconSize,
this.animatedIcon,
this.direction,
required this.children,
});
@override
State<MihFloatingMenu> createState() => _MihFloatingMenuState();
}
class _MihFloatingMenuState extends State<MihFloatingMenu> {
@override
Widget build(BuildContext context) {
return SpeedDial(
icon: widget.icon,
buttonSize: Size(widget.iconSize ?? 56.0, widget.iconSize ?? 56.0),
animatedIcon: widget.animatedIcon,
direction: widget.direction ?? SpeedDialDirection.up,
activeIcon: Icons.close,
backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
activeBackgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
foregroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
overlayColor: Colors.black,
overlayOpacity: 0.5,
children: widget.children,
onOpen: () => debugPrint('OPENING DIAL'),
onClose: () => debugPrint('DIAL CLOSED'),
);
}
}
@@ -1,27 +0,0 @@
import 'package:flutter/material.dart';
class MihForm extends StatefulWidget {
final GlobalKey<FormState> formKey;
final List<Widget> formFields;
const MihForm({
super.key,
required this.formKey,
required this.formFields,
});
@override
State<MihForm> createState() => _MihFormState();
}
class _MihFormState extends State<MihForm> {
@override
Widget build(BuildContext context) {
return Form(
key: widget.formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: widget.formFields,
),
);
}
}
@@ -1,64 +0,0 @@
import 'package:flutter/widgets.dart'; // You need this import for IconData
class MihIcons {
MihIcons._(); // This makes the class non-instantiable (good practice for utility classes)
// This MUST match the 'family' name you specify in pubspec.yaml
static const _mihFontFam = 'MihIcons';
// Set to your package name ONLY if this font is part of a separate package you created
static const String? _mihFontPkg = null;
// IconData constants based on your style.css file
// Note: We convert the hex code from CSS (\eXXX) to an integer (0xeXXX)
static const IconData mzansiDirectory =
IconData(0xe900, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData personalProfile =
IconData(0xe901, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData aboutMih =
IconData(0xe902, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData accessControl =
IconData(0xe903, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData businessProfile =
IconData(0xe904, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData businessSetup =
IconData(0xe905, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData iDontKnow =
IconData(0xe906, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData mihLogo =
IconData(0xe907, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData mihRing =
IconData(0xe908, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData mzansiAi =
IconData(0xe909, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData mzansiWallet =
IconData(0xe90a, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData notifications =
IconData(0xe90b, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData patientManager =
IconData(0xe90c, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData patientProfile =
IconData(0xe90d, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData profileSetup =
IconData(0xe90e, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData calculator =
IconData(0xe940, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
static const IconData calendar =
IconData(0xe953, fontFamily: _mihFontFam, fontPackage: _mihFontPkg);
}
@@ -1,238 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
class MihNumericStepper extends StatefulWidget {
final TextEditingController controller;
final Color fillColor;
final Color inputColor;
final String hintText;
final bool requiredText;
final double? width;
final int? minValue;
final int? maxValue;
final bool validationOn;
const MihNumericStepper({
super.key,
required this.controller,
required this.fillColor,
required this.inputColor,
required this.hintText,
required this.requiredText,
this.width,
this.minValue,
this.maxValue,
required this.validationOn,
});
@override
State<MihNumericStepper> createState() => _MihNumericStepperState();
}
class _MihNumericStepperState extends State<MihNumericStepper> {
late int _currentValue;
late bool error;
@override
void dispose() {
widget.controller.removeListener(_syncCurrentValue);
super.dispose();
}
@override
void initState() {
super.initState();
_currentValue =
int.tryParse(widget.controller.text) ?? widget.minValue ?? 0;
widget.controller.text = _currentValue.toString();
int.tryParse(widget.controller.text) ?? widget.minValue ?? 0;
widget.controller.addListener(_syncCurrentValue);
// print("Current Value: $_currentValue");
}
void _syncCurrentValue() {
final newValue =
int.tryParse(widget.controller.text) ?? widget.minValue ?? 0;
if (newValue != _currentValue) {
setState(() {
_currentValue = newValue;
});
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
Text(
widget.hintText,
style: TextStyle(
fontWeight: FontWeight.bold,
color: widget.fillColor,
fontSize: 18,
),
),
],
),
const SizedBox(height: 4),
Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Column(
children: [
Container(
// color: Colors.white,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
25), // Optional: rounds the corners
boxShadow: const [
BoxShadow(
color: Color.fromARGB(60, 0, 0,
0), // 0.2 opacity = 51 in alpha (255 * 0.2)
spreadRadius: -2,
blurRadius: 10,
offset: Offset(0, 5),
),
],
),
child: Padding(
padding: const EdgeInsets.only(
top: 2.0,
left: 5.0,
),
child: SizedBox(
width: 40,
child: IconButton.filled(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark")),
),
color: widget.inputColor,
iconSize: 20,
onPressed: () {
print("Current Value: $_currentValue");
if (_currentValue >= (widget.minValue ?? 0)) {
setState(() {
widget.controller.text =
(_currentValue - 1).toString();
_currentValue =
int.tryParse(widget.controller.text)!;
});
}
print("New Current Value: $_currentValue");
},
icon: const Icon(
Icons.remove,
),
),
),
),
),
Visibility(
visible: _currentValue < (widget.minValue ?? 0) ||
(widget.maxValue != null &&
_currentValue > widget.maxValue!),
child: const SizedBox(
height: 21,
),
),
],
),
const SizedBox(width: 15),
Expanded(
child: MihTextFormField(
width: widget.width,
fillColor: widget.fillColor,
inputColor: widget.inputColor,
controller: widget.controller,
hintText: null,
requiredText: widget.requiredText,
readOnly: true,
numberMode: true,
textIputAlignment: TextAlign.center,
validator: (value) {
if (widget.validationOn) {
return MihValidationServices().validateNumber(
value, widget.minValue, widget.maxValue);
}
return null;
},
),
),
const SizedBox(width: 10),
Column(
children: [
Container(
// color: Colors.white,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
25), // Optional: rounds the corners
boxShadow: const [
BoxShadow(
color: Color.fromARGB(60, 0, 0,
0), // 0.2 opacity = 51 in alpha (255 * 0.2)
spreadRadius: -2,
blurRadius: 10,
offset: Offset(0, 5),
),
],
),
child: Padding(
padding: const EdgeInsets.only(
top: 2.0,
left: 5.0,
),
child: SizedBox(
width: 40,
child: IconButton.filled(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark")),
),
color: widget.inputColor,
iconSize: 20,
onPressed: () {
print("Current Value: $_currentValue");
if (widget.maxValue == null ||
_currentValue <= widget.maxValue!) {
setState(() {
widget.controller.text =
(_currentValue + 1).toString();
_currentValue =
int.tryParse(widget.controller.text)!;
});
}
print("New Current Value: $_currentValue");
},
icon: const Icon(
Icons.add,
),
),
),
),
),
Visibility(
visible: _currentValue < (widget.minValue ?? 0) ||
(widget.maxValue != null &&
_currentValue > widget.maxValue!),
child: const SizedBox(
height: 21,
),
),
],
),
],
),
],
);
}
}
@@ -1,217 +0,0 @@
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_scack_bar.dart';
import 'package:mzansi_innovation_hub/mih_packages/mih_home/components/mih_app_drawer.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class MihPackage extends StatefulWidget {
final Widget appActionButton;
final MihPackageTools appTools;
final List<Widget> appBody;
final List<String>? appToolTitles;
final MIHAppDrawer? actionDrawer;
int selectedbodyIndex;
final Function(int) onIndexChange;
MihPackage({
super.key,
required this.appActionButton,
required this.appTools,
required this.appBody,
this.appToolTitles,
this.actionDrawer,
required this.selectedbodyIndex,
required this.onIndexChange,
});
@override
State<MihPackage> createState() => _MihPackageState();
}
class _MihPackageState extends State<MihPackage>
with SingleTickerProviderStateMixin {
late PageController _pageController;
late AnimationController _animationController;
DateTime? lastPressedAt;
void unfocusAll() {
FocusScope.of(context).unfocus();
}
Future<void> _peakAnimation() async {
int currentPage = widget.selectedbodyIndex;
double peakOffset = _pageController.position.viewportDimension * 0.075;
double currentOffset =
_pageController.page! * _pageController.position.viewportDimension;
int nextPage =
currentPage + 1 < widget.appBody.length ? currentPage + 1 : currentPage;
if (nextPage != currentPage) {
await Future.delayed(const Duration(milliseconds: 100));
await _pageController.animateTo(
currentOffset + peakOffset,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
// await Future.delayed(const Duration(milliseconds: 100));
await _pageController.animateTo(
currentPage * _pageController.position.viewportDimension,
duration: const Duration(milliseconds: 300),
curve: Curves.easeIn,
);
}
}
@override
void dispose() {
super.dispose();
_pageController.dispose();
_animationController.dispose();
}
@override
void didUpdateWidget(covariant MihPackage oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.selectedbodyIndex != widget.selectedbodyIndex) {
_pageController.animateToPage(
widget.selectedbodyIndex,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
}
@override
void initState() {
super.initState();
_pageController = PageController(initialPage: widget.selectedbodyIndex);
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
);
// if (!MzansiInnovationHub.of(context)!.theme.kIsWeb) {
// // Trigger the peak animation on start (or call this elsewhere)
// WidgetsBinding.instance.addPostFrameCallback((_) {
// _peakAnimation();
// });
// }
if (!MzansiInnovationHub.of(context)!.theme.kIsWeb) {
// Trigger the peak animation only AFTER the route transition is complete
WidgetsBinding.instance.addPostFrameCallback((_) {
final ModalRoute? currentRoute = ModalRoute.of(context);
if (currentRoute != null) {
currentRoute.animation?.addStatusListener((status) {
if (status == AnimationStatus.completed && mounted) {
// Ensure the widget is still mounted and the animation is completed
_peakAnimation();
}
});
}
});
}
}
@override
Widget build(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;
return GestureDetector(
onTap: unfocusAll,
child: PopScope(
canPop: false,
onPopInvokedWithResult: (bool didPop, Object? result) {
if (GoRouterState.of(context).name == 'mihHome' ||
GoRouterState.of(context).name == 'mihAuthentication') {
if (lastPressedAt == null ||
DateTime.now().difference(lastPressedAt!) >
const Duration(seconds: 2)) {
// First press: show a message and update the timestamp.
lastPressedAt = DateTime.now();
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text("Press back again to exit"),
),
);
} else {
// Second press within 2 seconds: exit the app.
KenLogger.warning('Exiting app...'); // Your custom logger
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}
} else {
context.goNamed(
'mihHome',
extra: true,
);
}
},
child: Scaffold(
drawer: widget.actionDrawer,
body: SafeArea(
bottom: false,
minimum: EdgeInsets.only(bottom: 0),
child: Container(
width: screenSize.width,
height: screenSize.height,
//color: Colors.black,
padding: const EdgeInsets.only(top: 5),
child: Column(
children: [
Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
widget.appActionButton,
const SizedBox(
width: 10,
),
Expanded(
child: Container(
// alignment: Alignment.center,
// alignment: Alignment.centerRight,
alignment: Alignment.centerLeft,
// color: Colors.black,
child: FittedBox(
child: Text(
widget.appToolTitles != null
? widget
.appToolTitles![widget.selectedbodyIndex]
: "",
style: const TextStyle(
fontSize: 23,
fontWeight: FontWeight.w600,
),
),
),
),
),
const SizedBox(width: 5),
widget.appTools,
const SizedBox(width: 5),
],
),
const SizedBox(height: 5),
Expanded(
child: PageView.builder(
controller: _pageController,
itemCount: widget.appBody.length,
itemBuilder: (context, index) {
return widget.appBody[index];
},
onPageChanged: (index) {
setState(() {
widget.selectedbodyIndex = index;
widget.onIndexChange(widget.selectedbodyIndex);
});
},
),
),
],
),
),
),
),
),
);
}
}
@@ -1,38 +0,0 @@
import 'package:flutter/material.dart';
class MihPackageAction extends StatefulWidget {
final void Function()? onTap;
final double iconSize;
final Widget icon;
const MihPackageAction({
super.key,
required this.icon,
required this.iconSize,
required this.onTap,
});
@override
State<MihPackageAction> createState() => _MihPackageActionState();
}
class _MihPackageActionState extends State<MihPackageAction> {
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return IconButton(
iconSize: widget.iconSize,
padding: const EdgeInsets.all(0),
onPressed: widget.onTap,
icon: widget.icon,
);
}
}

Some files were not shown because too many files have changed in this diff Show More