18 Commits

Author SHA1 Message Date
74341a9cc6 Enhance Mzansi Profile Look & Feel and workflow 2026-02-18 10:18:03 +02:00
c5267c0540 change follow us link alignments 2026-02-16 16:27:39 +02:00
d4ba3aaa03 fix short cut icon issue 2026-02-16 15:34:27 +02:00
103ccdc022 Add scroll bar to mih 2026-02-16 15:23:16 +02:00
f8a722eb50 change design on profile links and add git option 2026-02-16 14:43:34 +02:00
fdb28080e3 fix web cros issues with fixed dev port pt2 2026-02-16 14:42:33 +02:00
8a384921c5 fix web cros issues with fixed dev port 2026-02-16 14:41:51 +02:00
4b47bf5288 enhacne install/ update mih button to cater for huawei 2026-02-16 14:08:00 +02:00
141611b84d fix mzansi ai modal 2026-02-16 13:43:15 +02:00
a29d0afeb8 update version number of mih 2026-02-16 13:25:46 +02:00
eb93714022 add ds_store file to ingore file 2026-02-16 13:09:33 +02:00
071612a521 BUG: API Wildcard CROS issue 2026-02-16 13:09:33 +02:00
726a60ad25 BUG: Fix exposed ports on mih server 2026-02-16 13:09:33 +02:00
b897986c1f BUG: Fix hardcoded supertoken api key 2026-02-16 13:09:33 +02:00
7d4d7fc713 BUG: Fix Security Flutter Web server 2026-02-16 13:09:33 +02:00
91075255f4 add scrolling to about package 2026-02-10 14:07:05 +02:00
5c2f19dcc4 enable linux platform & rename widnow 2026-02-10 11:58:35 +02:00
58aebbeabe Merge pull request 'ruleset test' (#1) from tester-branch into main
Reviewed-on: #1
2026-02-04 11:18:21 +00:00
58 changed files with 2053 additions and 1207 deletions

BIN
.DS_Store vendored

Binary file not shown.

1
.gitignore vendored
View File

@@ -11,3 +11,4 @@ Mzansi_Mail/
google-chrome-stable_current_amd64.deb google-chrome-stable_current_amd64.deb
.env .env
Frontend/android/app/.cxx/ Frontend/android/app/.cxx/
.DS_Store

11
.vscode/launch.json vendored
View File

@@ -11,6 +11,17 @@
"type": "dart", "type": "dart",
"program": "lib/main_dev.dart" "program": "lib/main_dev.dart"
}, },
{
"name": "Debug (web)",
"cwd": "mih_ui",
"request": "launch",
"type": "dart",
"program": "lib/main_dev.dart",
"args": [
"--web-port",
"1995"
]
},
{ {
"name": "Profile", "name": "Profile",
"cwd": "mih_ui", "cwd": "mih_ui",

View File

@@ -4,37 +4,6 @@ networks:
driver: bridge driver: bridge
#============== MIH Containers ==================================================================== #============== MIH Containers ====================================================================
services: services:
#============== Nginx Proxy Server Old ====================================================================
# nginx:
# container_name: nginx
# restart: unless-stopped
# image: nginx
# ports:
# - 80:80
# - 443:443
# volumes:
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf
# - certbotConf:/etc/letsencrypt
# - certbotChall:/var/www/certbot
# depends_on:
# - mih-ux
# networks:
# - mih-network
# profiles: [ 'prod' ]
#============== Cert Bot Old ====================================================================
# certbot:
# image: certbot/certbot
# container_name: certbot
# volumes:
# - certbotConf:/etc/letsencrypt
# - certbotChall:/var/www/certbot
# #command: certonly --test-cert --webroot -w /var/www/certbot --force-renewal --email yasienmeth@gmail.com -d mzansi-innovation-hub.co.za -d www.mzansi-innovation-hub.co.za --agree-tos
# command: certonly --webroot -w /var/www/certbot --force-renewal --email ${CERTBOT_EMAIL} -d ${CERTBOT_APP_DOMAIN} -d ${CERTBOT_API_DOMAIN} -d ${CERTBOT_STORAGE_DOMAIN} -d ${CERTBOT_MONITOR_DOMAIN} -d ${CERTBOT_AI_DOMAIN} --agree-tos
# networks:
# - mih-network
# depends_on:
# - nginx
# profiles: [ 'withCert' ]
#============== Nginx Proxy Manager ==================================================================== #============== Nginx Proxy Manager ====================================================================
mih-nginx: mih-nginx:
container_name: mih-nginx container_name: mih-nginx
@@ -43,7 +12,7 @@ services:
ports: ports:
- '80:80' # Public HTTP - '80:80' # Public HTTP
- '443:443' # Public HTTPS - '443:443' # Public HTTPS
- '81:81' # Admin Web Port - '127.0.0.1:81:81' # Admin Web Port
volumes: volumes:
- ./mih_nginx/data:/data - ./mih_nginx/data:/data
- ./mih_nginx/letsencrypt:/etc/letsencrypt - ./mih_nginx/letsencrypt:/etc/letsencrypt
@@ -69,8 +38,8 @@ services:
- /etc/timezone:/etc/timezone:ro - /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro - /etc/localtime:/etc/localtime:ro
ports: ports:
- "3000:3000" - "127.0.0.1:3000:3000"
- "222:22" - "127.0.0.1:222:22"
depends_on: depends_on:
mih-gitea-db: mih-gitea-db:
condition: service_healthy condition: service_healthy
@@ -99,7 +68,7 @@ services:
depends_on: depends_on:
- mih-db - mih-db
ports: ports:
- 3567:3567 - '127.0.0.1:3567:3567'
environment: environment:
REFRESH_TOKEN_VALIDITY: '604800' REFRESH_TOKEN_VALIDITY: '604800'
ACCESS_TOKEN_VALIDITY: '86400' ACCESS_TOKEN_VALIDITY: '86400'
@@ -125,7 +94,7 @@ services:
image: wordpress image: wordpress
restart: always restart: always
ports: ports:
- 8081:80 - '127.0.0.1:8081:80'
environment: environment:
WORDPRESS_DB_HOST: mih-wp-db WORDPRESS_DB_HOST: mih-wp-db
WORDPRESS_DB_USER: ${WP_SQL_USER} WORDPRESS_DB_USER: ${WP_SQL_USER}
@@ -154,7 +123,7 @@ services:
build: build:
context: ./mih_ui context: ./mih_ui
ports: ports:
- "83:83" - "127.0.0.1:83:83"
networks: networks:
- mih-network - mih-network
depends_on: depends_on:
@@ -166,7 +135,7 @@ services:
target: builder target: builder
container_name: mih-api-hub container_name: mih-api-hub
ports: ports:
- 8080:80 - "127.0.0.1:8080:80"
volumes: volumes:
- ./mih_api_hub:/app - ./mih_api_hub:/app
networks: networks:
@@ -187,7 +156,7 @@ services:
networks: networks:
- mih-network - mih-network
ports: ports:
- '3306:3306' - '127.0.0.1:3306:3306'
volumes: volumes:
- ./mih_db:/var/lib/mysql - ./mih_db:/var/lib/mysql
#============== PHP My Admin ==================================================================== #============== PHP My Admin ====================================================================
@@ -213,8 +182,8 @@ services:
hostname: mih-minio hostname: mih-minio
image: minio/minio image: minio/minio
ports: ports:
- '9000:9000' - '127.0.0.1:9000:9000'
- '9001:9001' - '127.0.0.1:9001:9001'
volumes: volumes:
- './mih_minio:/data' - './mih_minio:/data'
environment: environment:
@@ -228,7 +197,7 @@ services:
container_name: mih-monitor container_name: mih-monitor
image: portainer/portainer-ce:2.20.3 image: portainer/portainer-ce:2.20.3
ports: ports:
- 9444:9443 - '127.0.0.1:9444:9443'
volumes: volumes:
- ./mih_monitor/data:/data - ./mih_monitor/data:/data
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
@@ -240,7 +209,7 @@ services:
container_name: mih-ai container_name: mih-ai
image: ollama/ollama:latest image: ollama/ollama:latest
ports: ports:
- 11434:11434 - '127.0.0.1:11434:11434'
volumes: volumes:
- ./mih_ai/ollama/ollama:/root/.ollama - ./mih_ai/ollama/ollama:/root/.ollama
pull_policy: always pull_policy: always

View File

@@ -1,3 +1,4 @@
.env .env
__pycache__/ __pycache__/
temp*.pdf temp*.pdf
.DS_Store

View File

@@ -1,28 +0,0 @@
# from supertokens_python import init, InputAppInfo, SupertokensConfig
# from supertokens_python.recipe import emailpassword, session, dashboard
# init(
# app_info=InputAppInfo(
# app_name="MIH_API_HUB",
# api_domain="http://localhost:8080/",
# website_domain="http://mzansi-innovation-hub.co.za",
# api_base_path="/auth",
# website_base_path="/auth"
# ),
# supertokens_config=SupertokensConfig(
# # https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
# connection_uri="supertokens:3567/",
# api_key="leatucczyixqwkqqdrhayiwzeofkltds"
# ),
# framework='fastapi',
# recipe_list=[
# # SuperTokens.init(),
# session.init(), # initializes session features
# emailpassword.init(),
# dashboard.init(admins=[
# "yasienmeth@gmail.com",
# ],
# )
# ],
# mode='wsgi' # use wsgi instead of asgi if you are running using gunicorn
# )

View File

@@ -34,14 +34,20 @@ from supertokens_python.recipe.session.framework.fastapi import verify_session
from supertokens_python.recipe.emailverification import EmailVerificationClaim from supertokens_python.recipe.emailverification import EmailVerificationClaim
from supertokens_python.recipe.session import SessionContainer from supertokens_python.recipe.session import SessionContainer
import os
from dotenv import load_dotenv
load_dotenv()
st_api_key = os.getenv("SUPERTOKENS_API_KEY")
origins = [ origins = [
"http://localhost", "http://localhost",
"http://localhost:80", "http://localhost:80",
"http://localhost:1995",
"http://localhost:8080", "http://localhost:8080",
"http://MIH-API-Hub:80", "http://MIH-API-Hub:80",
"http://MIH-API-Hub", "http://MIH-API-Hub",
"http://api.mzansi-innovation-hub.co.za", "http://api.mzansi-innovation-hub.co.za",
"*", "http://app.mzansi-innovation-hub.co.za",
] ]
init( init(
@@ -55,7 +61,7 @@ init(
supertokens_config=SupertokensConfig( supertokens_config=SupertokensConfig(
# https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core. # https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
connection_uri="http://mih-supertokens:3567/", connection_uri="http://mih-supertokens:3567/",
api_key="leatucczyixqwkqqdrhayiwzeofkltds" api_key=st_api_key
), ),
framework='fastapi', framework='fastapi',
recipe_list=[ recipe_list=[

2
mih_ui/.gitignore vendored
View File

@@ -1,3 +1,5 @@
.env
# Miscellaneous # Miscellaneous
*.class *.class
*.log *.log

View File

@@ -1,48 +1,36 @@
# Install Operating system and dependencies # --- STAGE 1: The Builder ---
#FROM ubuntu:22.04
FROM debian:latest AS build-env FROM debian:latest AS build-env
#ENV DEBIAN_FRONTEND=noninteractive # Install necessary dependencies for Flutter
RUN apt-get update && apt-get install -y \
curl git wget unzip libglu1-mesa fonts-droid-fallback python3 \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update --fix-missing # Clone Flutter SDK
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 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="/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/
# Build the Flutter web app
WORKDIR /app WORKDIR /app
# RUN flutter upgrade COPY . .
RUN flutter config --enable-web
RUN flutter build web --release -t ./lib/main_prod.dart RUN flutter build web --release -t ./lib/main_prod.dart
# RUN flutter build web --release --web-renderer canvaskit -t ./lib/main_prod.dart
# --- STAGE 2: The Final Production Image ---
FROM nginx:alpine
# RUN cd .. # Copy built files from the first stage
COPY --from=build-env /app/build/web /usr/share/nginx/html
# WORKDIR /app/build/web/ # Create the Nginx config inside the Dockerfile to handle SPA routing
RUN echo 'server { \
listen 83; \
location / { \
root /usr/share/nginx/html; \
index index.html; \
try_files $uri $uri/ /index.html; \
} \
}' > /etc/nginx/conf.d/default.conf
EXPOSE 83 EXPOSE 83
CMD ["nginx", "-g", "daemon off;"]
RUN ["chmod", "+x", "/app/server/server.sh"]
ENTRYPOINT [ "/app/server/server.sh"]
# RUN ["python3", "-u", "/app/server/MIH_web_server.py"]

File diff suppressed because one or more lines are too long

View File

@@ -5,5 +5,6 @@
<item>@drawable/mzansi_wallet_sc</item> <item>@drawable/mzansi_wallet_sc</item>
<item>@drawable/mzansi_ai_sc</item> <item>@drawable/mzansi_ai_sc</item>
<item>@drawable/mih_calculator_sc</item> <item>@drawable/mih_calculator_sc</item>
<item>@drawable/mzansi_directory_sc</item>
</array> </array>
</resources> </resources>

View File

@@ -2,6 +2,7 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:flutter_web_plugins/url_strategy.dart' import 'package:flutter_web_plugins/url_strategy.dart'
if (dart.library.html) 'package:flutter_web_plugins/url_strategy.dart'; if (dart.library.html) 'package:flutter_web_plugins/url_strategy.dart';
@@ -42,6 +43,7 @@ void main() async {
debugPrint('APP INSTALLED!'); debugPrint('APP INSTALLED!');
}); });
final GoRouter appRouter = MihGoRouter().mihRouter; final GoRouter appRouter = MihGoRouter().mihRouter;
await dotenv.load(fileName: ".env");
FlutterNativeSplash.remove(); FlutterNativeSplash.remove();
runApp(MzansiInnovationHub( runApp(MzansiInnovationHub(
router: appRouter, router: appRouter,

View File

@@ -2,6 +2,7 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:flutter_web_plugins/url_strategy.dart' import 'package:flutter_web_plugins/url_strategy.dart'
if (dart.library.html) 'package:flutter_web_plugins/url_strategy.dart'; if (dart.library.html) 'package:flutter_web_plugins/url_strategy.dart';
@@ -33,6 +34,7 @@ void main() async {
debugPrint('APP INSTALLED!'); debugPrint('APP INSTALLED!');
}); });
final GoRouter appRouter = MihGoRouter().mihRouter; final GoRouter appRouter = MihGoRouter().mihRouter;
await dotenv.load(fileName: ".env");
FlutterNativeSplash.remove(); FlutterNativeSplash.remove();
runApp(MzansiInnovationHub( runApp(MzansiInnovationHub(
router: appRouter, router: appRouter,

View File

@@ -9,7 +9,7 @@ class MihTheme {
late String loadingAssetText; late String loadingAssetText;
late TargetPlatform platform; late TargetPlatform platform;
bool kIsWeb = const bool.fromEnvironment('dart.library.js_util'); bool kIsWeb = const bool.fromEnvironment('dart.library.js_util');
String latestVersion = "1.2.5"; String latestVersion = "1.2.6";
MihTheme() { MihTheme() {
mode = "Dark"; mode = "Dark";
} }

View File

@@ -161,6 +161,7 @@ class _PackageToolOneState extends State<PackageToolOne> {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"

View File

@@ -111,6 +111,7 @@ class _PackageToolThreeState extends State<PackageToolThree> {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [

View File

@@ -24,6 +24,7 @@ class _PackageToolTwoState extends State<PackageToolTwo> {
Widget getBody() { Widget getBody() {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,

View File

@@ -25,6 +25,7 @@ class _PackageToolZeroState extends State<PackageToolZero> {
Widget getBody() { Widget getBody() {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [

View File

@@ -0,0 +1,679 @@
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_objects/bookmarked_business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart';
import 'package:mzansi_innovation_hub/mih_objects/business_review.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_add_bookmark_alert.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_delete_bookmark_alert.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_review_business_window.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_mzansi_directory_services.dart';
import 'package:provider/provider.dart';
import 'package:redacted/redacted.dart';
import 'package:supertokens_flutter/supertokens.dart';
import 'package:url_launcher/url_launcher.dart';
class MihBusinessCardV2 extends StatefulWidget {
final Business business;
final double width;
const MihBusinessCardV2({
super.key,
required this.business,
required this.width,
});
@override
State<MihBusinessCardV2> createState() => _MihBusinessCardV2State();
}
class _MihBusinessCardV2State extends State<MihBusinessCardV2> {
Future<BusinessReview?>? _businessReviewFuture;
Future<BookmarkedBusiness?>? _bookmarkedBusinessFuture;
bool _isUserSignedIn = false;
Future<void> _checkUserSession() async {
final doesSessionExist = await SuperTokens.doesSessionExist();
setState(() {
_isUserSignedIn = doesSessionExist;
});
}
RedactedConfiguration getRedactedConfiguration() {
return RedactedConfiguration(
// redactedColor: Colors.pink,
redactedColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
);
}
Future<void> _makePhoneCall(String phoneNumber) async {
String formattedNumber = phoneNumber.replaceAll("-", "");
final Uri url = Uri(scheme: 'tel', path: formattedNumber);
if (await canLaunchUrl(url)) {
await launchUrl(url);
} else {
MihAlertServices().errorBasicAlert(
"Error Making Call",
"We couldn't open your phone app to call $formattedNumber. To fix this, make sure you have a phone application installed and it's set as your default dialer.",
context,
);
}
}
String? _encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
Future<void> _launchEmail(
String recipient, String subject, String body) async {
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: recipient,
query: _encodeQueryParameters(<String, String>{
'subject': subject,
'body': body,
}),
);
if (await canLaunchUrl(emailLaunchUri)) {
await launchUrl(emailLaunchUri);
} else {
MihAlertServices().errorBasicAlert(
"Error Creating Email",
"We couldn't launch your email app to send a message to $recipient. To fix this, please confirm that you have an email application installed and that it's set as your default.",
context,
);
}
}
Future<void> _launchGoogleMapsWithUrl({
required double latitude,
required double longitude,
String? label,
}) async {
final Uri googleMapsUrl = Uri.parse(
'https://www.google.com/maps/search/?api=1&query=$latitude,$longitude${label != null ? '&query_place_id=' : ''}',
);
try {
if (await canLaunchUrl(googleMapsUrl)) {
await launchUrl(googleMapsUrl);
} else {
MihAlertServices().errorBasicAlert(
"Error Opening Maps",
"There was an issue opening maps for ${widget.business.Name}. This usually happens if you don't have a maps app installed or it's not set as your default. Please install one to proceed.",
context,
);
}
} catch (e) {
MihAlertServices().errorBasicAlert(
"Error Opening Maps",
"There was an issue opening maps for ${widget.business.Name}. This usually happens if you don't have a maps app installed or it's not set as your default. Please install one to proceed.",
context,
);
}
}
Future<void> _launchWebsite(String urlString) async {
String newUrl = urlString;
if (!newUrl.startsWith("https://")) {
newUrl = "https://$urlString";
}
final Uri url = Uri.parse(newUrl);
try {
if (await canLaunchUrl(url)) {
await launchUrl(url);
} else {
MihAlertServices().errorBasicAlert(
"Error Opening Website",
"We couldn't open the link to $newUrl. To view this website, please ensure you have a web browser installed and set as your default.",
context,
);
}
} catch (e) {
MihAlertServices().errorBasicAlert(
"Error Opening Website",
"We couldn't open the link to $newUrl. To view this website, please ensure you have a web browser installed and set as your default.",
context,
);
}
}
Future<BusinessReview?> getUserReview() async {
String user_id = await SuperTokens.getUserId();
return await MihMzansiDirectoryServices().getUserReviewOfBusiness(
user_id,
widget.business.business_id,
);
}
Future<BookmarkedBusiness?> getUserBookmark() async {
String user_id = await SuperTokens.getUserId();
return await MihMzansiDirectoryServices().getUserBookmarkOfBusiness(
user_id,
widget.business.business_id,
);
}
bool isValidGps(String coordinateString) {
final RegExp gpsRegex = RegExp(
r"^-?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*-?(1[0-7]\d(\.\d+)?|180(\.0+)?|\d{1,2}(\.\d+)?)$");
return gpsRegex.hasMatch(coordinateString);
}
@override
void initState() {
super.initState();
_checkUserSession();
_businessReviewFuture = getUserReview();
_bookmarkedBusinessFuture = getUserBookmark();
}
@override
Widget build(BuildContext context) {
// double screenWidth = MediaQuery.of(context).size.width;
return Consumer2<MzansiProfileProvider, MzansiDirectoryProvider>(
builder: (BuildContext context, MzansiProfileProvider profileProvider,
MzansiDirectoryProvider directoryProvider, Widget? child) {
double iconSize = 33.0;
return Wrap(
alignment: WrapAlignment.center,
runSpacing: 10,
spacing: 10,
children: [
Column(
children: [
SizedBox(
width: 80,
height: 80,
child: MihButton(
onPressed: () {
_makePhoneCall(widget.business.contact_no);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
child: Icon(
Icons.phone,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
size: iconSize,
),
),
),
const SizedBox(height: 2),
FittedBox(
child: Text(
"Call",
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
),
),
),
],
),
Column(
children: [
SizedBox(
width: 80,
height: 80,
child: MihButton(
onPressed: () {
_launchEmail(
widget.business.bus_email,
"Inquiery about ${widget.business.Name}",
"Dear ${widget.business.Name},\n\nI would like to inquire about your services.\n\nBest regards,\n",
);
},
buttonColor: MihColors.getPinkColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
child: Icon(
Icons.email,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
size: iconSize,
),
),
),
const SizedBox(height: 2),
FittedBox(
child: Text(
"Email",
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
),
),
),
],
),
if (isValidGps(widget.business.gps_location))
Column(
children: [
SizedBox(
width: 80,
height: 80,
child: MihButton(
onPressed: () {
final latitude = double.parse(
widget.business.gps_location.split(',')[0]);
final longitude = double.parse(
widget.business.gps_location.split(',')[1]);
_launchGoogleMapsWithUrl(
latitude: latitude,
longitude: longitude,
);
},
buttonColor: MihColors.getOrangeColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
child: Icon(
Icons.location_on,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
size: iconSize,
),
),
),
const SizedBox(height: 2),
FittedBox(
child: Text(
"Maps",
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
),
),
),
],
),
if (widget.business.website.isNotEmpty &&
widget.business.website != "")
Column(
children: [
SizedBox(
width: 80,
height: 80,
child: MihButton(
onPressed: () {
_launchWebsite(widget.business.website);
},
buttonColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
child: Icon(
Icons.language,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
size: iconSize,
),
),
),
const SizedBox(height: 2),
FittedBox(
child: Text(
"Website",
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
),
),
),
],
),
FutureBuilder(
future: _businessReviewFuture,
builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState == ConnectionState.waiting) {
return Column(
children: [
SizedBox(
width: 80,
height: 80,
child: MihButton(
onPressed: () {},
buttonColor: MihColors.getGreyColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
child: Icon(
Icons.star_rate_rounded,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
size: iconSize,
),
),
).redacted(context: context, redact: true),
const SizedBox(height: 2),
FittedBox(
child: Text(
"Rate Us",
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
),
),
).redacted(context: context, redact: true),
],
);
} else {
BusinessReview? businessReview = asyncSnapshot.data;
String ratingTitle = "";
if (businessReview == null) {
ratingTitle = "Rate Us";
} else {
ratingTitle = "Edit";
}
return Column(
children: [
SizedBox(
width: 80,
height: 80,
child: MihButton(
onPressed: () {
businessReviewRatingWindow(directoryProvider,
businessReview, true, widget.width);
},
buttonColor: MihColors.getYellowColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
child: Icon(
Icons.star_rate_rounded,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
size: iconSize,
),
),
),
const SizedBox(height: 2),
FittedBox(
child: Text(
ratingTitle,
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
),
),
),
],
);
}
},
),
FutureBuilder(
future: _bookmarkedBusinessFuture,
builder: (context, asyncSnapshot) {
if (asyncSnapshot.connectionState == ConnectionState.waiting) {
return Column(
children: [
SizedBox(
width: 80,
height: 80,
child: MihButton(
onPressed: () {},
buttonColor: MihColors.getGreyColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
child: Icon(
Icons.bookmark_add_rounded,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
size: iconSize,
),
),
).redacted(context: context, redact: true),
const SizedBox(height: 2),
FittedBox(
child: Text(
"bookmark",
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
),
),
).redacted(context: context, redact: true),
],
);
} else {
BookmarkedBusiness? bookmarkBusiness = asyncSnapshot.data;
String bookmarkDisplayTitle = "";
if (bookmarkBusiness == null) {
bookmarkDisplayTitle = "Bookmark";
} else {
bookmarkDisplayTitle = "Remove";
}
return Column(
children: [
SizedBox(
width: 80,
height: 80,
child: MihButton(
onPressed: () {
if (bookmarkBusiness == null) {
showAddBookmarkAlert();
} else {
showDeleteBookmarkAlert(bookmarkBusiness);
}
},
buttonColor: MihColors.getBluishPurpleColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
child: Icon(
bookmarkBusiness == null
? Icons.bookmark_add_rounded
: Icons.bookmark_remove_rounded,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
size: iconSize,
),
),
),
const SizedBox(height: 2),
FittedBox(
child: Text(
bookmarkDisplayTitle,
style: TextStyle(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
),
),
),
],
);
}
},
),
],
);
},
);
}
Future<void> businessReviewRatingWindow(
MzansiDirectoryProvider directoryProvider,
BusinessReview? myReview,
bool previouslyRated,
double width) async {
if (_isUserSignedIn) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) => MihReviewBusinessWindow(
business: widget.business,
businessReview: myReview,
screenWidth: width,
readOnly: false,
onSuccessDismissPressed: () async {
List<Business>? businessSearchResults = [];
businessSearchResults = await MihBusinessDetailsServices()
.searchBusinesses(directoryProvider.searchTerm,
directoryProvider.businessTypeFilter, context);
Map<String, Future<String>> busImagesUrl = {};
Future<String> businessLogoUrl;
for (var bus in businessSearchResults) {
businessLogoUrl = MihFileApi.getMinioFileUrl(bus.logo_path);
busImagesUrl[bus.business_id] = businessLogoUrl;
}
directoryProvider.setSearchedBusinesses(
searchedBusinesses: businessSearchResults,
businessesImagesUrl: busImagesUrl,
);
setState(() {
_businessReviewFuture = getUserReview();
});
},
),
);
} else {
showSignInRequiredAlert();
}
}
void showAddBookmarkAlert() {
if (_isUserSignedIn) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) => MihAddBookmarkAlert(
business: widget.business,
onSuccessDismissPressed: () async {
_bookmarkedBusinessFuture = getUserBookmark();
},
),
);
} else {
showSignInRequiredAlert();
}
}
void showDeleteBookmarkAlert(BookmarkedBusiness? bookmarkBusiness) {
if (_isUserSignedIn) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) => MihDeleteBookmarkAlert(
business: widget.business,
bookmarkBusiness: bookmarkBusiness,
onSuccessDismissPressed: () {
_bookmarkedBusinessFuture = getUserBookmark();
},
// startUpSearch: widget.startUpSearch,
));
} else {
showSignInRequiredAlert();
}
}
void showSignInRequiredAlert() {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: null,
onWindowTapClose: () {
context.pop();
},
windowBody: Column(
children: [
Icon(
MihIcons.mihLogo,
size: 125,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
const SizedBox(height: 10),
Text(
"Let's Get Started",
textAlign: TextAlign.center,
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 15),
Text(
"Ready to dive in to the world of MIH?\nSign in or create a free MIH account to unlock all the powerful features of the MIH app. It's quick and easy!",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fontSize: 15,
),
),
const SizedBox(height: 25),
Center(
child: MihButton(
onPressed: () {
context.goNamed(
'mihHome',
extra: true,
);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
elevation: 10,
width: 300,
child: Text(
"Sign In/ Create Account",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
);
},
);
}
}

View File

@@ -197,7 +197,10 @@ class _MihPackageWindowState extends State<MihPackageWindow> {
maxHeight: windowHeight * 0.85, maxHeight: windowHeight * 0.85,
maxWidth: windowWidth * 0.85, maxWidth: windowWidth * 0.85,
), ),
child: MihSingleChildScroll(child: widget.windowBody), child: MihSingleChildScroll(
scrollbarOn: true,
child: widget.windowBody,
),
), ),
), ),
), ),

View File

@@ -3,7 +3,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart'; import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tile.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@@ -26,72 +26,87 @@ class MihProfileLinks extends StatefulWidget {
class _MihProfileLinksState extends State<MihProfileLinks> { class _MihProfileLinksState extends State<MihProfileLinks> {
Widget displayLinkButton(ProfileLink link) { Widget displayLinkButton(ProfileLink link) {
IconData iconData; IconData iconData;
Color iconColor; Color btnColor;
Color iconColor = Colors.white;
switch (link.destination.toLowerCase()) { switch (link.destination.toLowerCase()) {
case "youtube": case "youtube":
iconData = FontAwesomeIcons.youtube; iconData = FontAwesomeIcons.youtube;
iconColor = const Color(0xFFFF0000); btnColor = const Color(0xFFFF0000);
break; break;
case "tiktok": case "tiktok":
iconData = FontAwesomeIcons.tiktok; iconData = FontAwesomeIcons.tiktok;
iconColor = const Color(0xFF000000); btnColor = const Color(0xFF000000);
break; break;
case "twitch": case "twitch":
iconData = FontAwesomeIcons.twitch; iconData = FontAwesomeIcons.twitch;
iconColor = const Color(0xFF6441a5); btnColor = const Color(0xFF6441a5);
break; break;
case "threads": case "threads":
iconData = FontAwesomeIcons.threads; iconData = FontAwesomeIcons.threads;
iconColor = const Color(0xFF000000); btnColor = const Color(0xFF000000);
break; break;
case "whatsapp": case "whatsapp":
iconData = FontAwesomeIcons.whatsapp; iconData = FontAwesomeIcons.whatsapp;
iconColor = const Color(0xFF25D366); btnColor = const Color(0xFF25D366);
break; break;
case "instagram": case "instagram":
iconData = FontAwesomeIcons.instagram; iconData = FontAwesomeIcons.instagram;
iconColor = const Color(0xFFF56040); btnColor = const Color(0xFFF56040);
break; break;
case "x": case "x":
iconData = FontAwesomeIcons.xTwitter; iconData = FontAwesomeIcons.xTwitter;
iconColor = const Color(0xFF000000); btnColor = const Color(0xFF000000);
break; break;
case "linkedin": case "linkedin":
iconData = FontAwesomeIcons.linkedin; iconData = FontAwesomeIcons.linkedin;
iconColor = const Color(0xFF0a66c2); btnColor = const Color(0xFF0a66c2);
break; break;
case "facebook": case "facebook":
iconData = FontAwesomeIcons.facebook; iconData = FontAwesomeIcons.facebook;
iconColor = const Color(0xFF4267B2); btnColor = const Color(0xFF4267B2);
break; break;
case "reddit": case "reddit":
iconData = FontAwesomeIcons.reddit; iconData = FontAwesomeIcons.reddit;
iconColor = const Color(0xFFFF4500); btnColor = const Color(0xFFFF4500);
break; break;
case "discord": case "discord":
iconData = FontAwesomeIcons.discord; iconData = FontAwesomeIcons.discord;
iconColor = const Color(0xFF5865F2); btnColor = const Color(0xFF5865F2);
break;
case "git":
iconData = FontAwesomeIcons.git;
btnColor = const Color(0xFF73A952);
break; break;
default: default:
iconData = FontAwesomeIcons.link; iconData = FontAwesomeIcons.link;
iconColor = MihColors.getPrimaryColor( btnColor = MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"); MzansiInnovationHub.of(context)!.theme.mode == "Dark");
} }
return MihButton(
return MihPackageTile( onPressed: () {
onTap: () {
launchSocialUrl(Uri.parse(link.web_link)); launchSocialUrl(Uri.parse(link.web_link));
}, },
appName: link.destination, buttonColor: btnColor,
appIcon: Icon( child: FaIcon(
iconData, iconData,
color: iconColor, color: iconColor,
size: 33,
), ),
iconSize: 200,
textColor: Colors.black,
// MihColors.getPrimaryColor(
// MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
); );
// return MihPackageTile(
// onTap: () {
// launchSocialUrl(Uri.parse(link.web_link));
// },
// appName: link.destination,
// appIcon: Icon(
// iconData,
// color: btnColor,
// ),
// iconSize: 200,
// textColor: Colors.black,
// // MihColors.getPrimaryColor(
// // MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// );
} }
Future<void> launchSocialUrl(Uri linkUrl) async { Future<void> launchSocialUrl(Uri linkUrl) async {
@@ -110,54 +125,37 @@ class _MihProfileLinksState extends State<MihProfileLinks> {
padding: widget.paddingOn == null || widget.paddingOn! padding: widget.paddingOn == null || widget.paddingOn!
? MzansiInnovationHub.of(context)!.theme.screenType == "desktop" ? MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2) ? EdgeInsets.symmetric(horizontal: width * 0.2)
: EdgeInsets.symmetric(horizontal: width * 0.075) : EdgeInsets.symmetric(horizontal: width * 0)
: EdgeInsetsGeometry.all(0), : EdgeInsetsGeometry.all(0),
child: Material( child: widget.links.isEmpty
color: MihColors.getSecondaryColor( ? SizedBox(
MzansiInnovationHub.of(context)!.theme.mode == "Dark") height: 35,
.withValues(alpha: 0.6), child: Text(
borderRadius: BorderRadius.circular(25), "No Profile Links",
elevation: 10, textAlign: TextAlign.center,
shadowColor: Colors.black, style: TextStyle(
child: Container( fontSize: 25,
width: 500, fontWeight: FontWeight.bold,
padding: EdgeInsets.all(10), color: MihColors.getPrimaryColor(
decoration: BoxDecoration( MzansiInnovationHub.of(context)!.theme.mode ==
color: MihColors.getSecondaryColor( "Dark"),
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
borderRadius: BorderRadius.circular(10),
),
child: widget.links.isEmpty
? SizedBox(
height: 35,
child: Text(
"No Profile Links",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
)
: Wrap(
alignment: WrapAlignment.center,
runSpacing: 15,
spacing: 15,
children: widget.links.map(
(link) {
return SizedBox(
width: widget.buttonSize ?? 80,
height: widget.buttonSize ?? 80,
child: displayLinkButton(link),
);
},
).toList(),
), ),
), ),
), )
: Wrap(
alignment: WrapAlignment.center,
runSpacing: 10,
spacing: 10,
children: widget.links.map(
(link) {
return SizedBox(
width: widget.buttonSize ?? 80,
height: widget.buttonSize ?? 80,
child: displayLinkButton(link),
);
},
).toList(),
),
); );
}, },
); );

View File

@@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
class MihSingleChildScroll extends StatefulWidget { class MihSingleChildScroll extends StatefulWidget {
final Widget child; final Widget child;
final bool? scrollbarOn;
const MihSingleChildScroll({ const MihSingleChildScroll({
super.key, super.key,
required this.child, required this.child,
this.scrollbarOn,
}); });
@override @override
@@ -18,7 +20,8 @@ class _MihSingleChildScrollState extends State<MihSingleChildScroll> {
bottom: false, bottom: false,
minimum: EdgeInsets.only(bottom: 5), minimum: EdgeInsets.only(bottom: 5),
child: ScrollConfiguration( child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), behavior: ScrollConfiguration.of(context)
.copyWith(scrollbars: widget.scrollbarOn ?? false),
child: SingleChildScrollView( child: SingleChildScrollView(
child: widget.child, child: widget.child,
), ),

View File

@@ -94,7 +94,6 @@ class _MihAttributesState extends State<MihAttributes> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MihPackageToolBody( return MihPackageToolBody(
borderOn: false, borderOn: false,
innerHorizontalPadding: 10,
bodyItem: getBody(), bodyItem: getBody(),
); );
} }
@@ -108,179 +107,184 @@ class _MihAttributesState extends State<MihAttributes> {
"As per the terms for free use for these third party providers, the following assets require attribution"; "As per the terms for free use for these third party providers, the following assets require attribution";
return MihSingleChildScroll( return MihSingleChildScroll(
child: Column( scrollbarOn: true,
children: [ child: Padding(
Icon( padding: const EdgeInsets.symmetric(horizontal: 10.0),
MihIcons.mihLogo, child: Column(
color: MihColors.getSecondaryColor( children: [
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), Icon(
size: 165, MihIcons.mihLogo,
), color: MihColors.getSecondaryColor(
const SizedBox( MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
height: 10, size: 165,
),
SelectableText(
message,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
), ),
), const SizedBox(
const SizedBox( height: 10,
height: 10,
),
SizedBox(
width: 700,
child: Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
columnWidths: const {
0: FlexColumnWidth(1),
1: FlexColumnWidth(1),
2: FlexColumnWidth(1),
},
children: [
const TableRow(
children: [
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding: const EdgeInsets.only(bottom: 15.0),
child: Center(
child: Text(
"Resources",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Padding(
padding: const EdgeInsets.only(bottom: 15.0),
child: Center(
child: Text(
"Creator",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
),
),
TableCell(
child: Padding(
padding: const EdgeInsets.only(bottom: 15.0),
child: Center(
child: Text(
"Link",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
displayIcon(MihIcons.mihRing, "Tarah Meth",
"https://www.linkedin.com/in/tarah-meth-3b6309254/"),
displayIcon(MihIcons.mihLogo, "Tarah Meth",
"https://www.linkedin.com/in/tarah-meth-3b6309254/"),
displayIcon(MihIcons.mzansiAi, "Ollama", "https://ollama.com/"),
displayIcon(MihIcons.mzansiWallet, "Freepik",
"https://www.flaticon.com/free-icon/wallet-passes-app_3884407?term=wallet&page=1&position=21&origin=search&related_id=3884407"),
displayIcon(MihIcons.patientProfile, "RaftelDesign",
"https://www.flaticon.com/free-icon/patient_2376100?term=medication&page=1&position=6&origin=search&related_id=2376100"),
displayIcon(MihIcons.patientProfile, "Srip",
"https://www.flaticon.com/free-icon/hospital_1233930?term=medical+snake&page=1&position=7&origin=search&related_id=1233930"),
displayIcon(MihIcons.calendar, "Freepik",
"https://www.flaticon.com/free-icon/calendar_2278049?term=calendar&page=1&position=5&origin=search&related_id=2278049"),
displayIcon(MihIcons.calculator, "Freepik",
"https://www.flaticon.com/free-icon/calculator_2374409?term=calculator&page=1&position=20&origin=search&related_id=2374409"),
displayIcon(MihIcons.aboutMih, "Chanut",
"https://www.flaticon.com/free-icon/info_151776?term=about&page=1&position=8&origin=search&related_id=151776"),
displayIcon(MihIcons.personalProfile, "Freepik",
"https://www.flaticon.com/free-icon/user_1077063?term=profile&page=1&position=6&origin=search&related_id=1077063"),
displayIcon(MihIcons.businessProfile, "Gravisio",
"https://www.flaticon.com/free-icon/contractor_11813336?term=company+profile&page=1&position=2&origin=search&related_id=11813336"),
displayIcon(MihIcons.patientManager, "Vector Tank",
"https://www.flaticon.com/free-icon/doctor_10215061?term=doctor&page=1&position=73&origin=search&related_id=10215061"),
displayIcon(MihIcons.profileSetup, "Freepik",
"https://www.flaticon.com/free-icon/add-user_748137?term=profile+add&page=1&position=1&origin=search&related_id=748137"),
displayIcon(MihIcons.businessSetup, "kerismaker",
"https://www.flaticon.com/free-icon/business_13569850?term=company+add&page=1&position=25&origin=search&related_id=13569850"),
displayIcon(MihIcons.calculator, "fawazahmed0",
"https://github.com/fawazahmed0/exchange-api"),
displayIcon(MihIcons.iDontKnow, "Freepik",
"https://www.flaticon.com/free-icon/i-dont-know_5359909?term=i+dont+know&page=1&position=7&origin=search&related_id=5359909"),
],
), ),
), SelectableText(
// SizedBox( message,
// width: 500, style: const TextStyle(
// child: Column( fontSize: 15,
// children: [ fontWeight: FontWeight.bold,
// const SizedBox( ),
// width: double.infinity, ),
// child: Row( const SizedBox(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly, height: 10,
// mainAxisSize: MainAxisSize.max, ),
// children: [ SizedBox(
// Flexible( width: 700,
// child: Text( child: Table(
// "Icon", defaultVerticalAlignment: TableCellVerticalAlignment.middle,
// style: TextStyle( columnWidths: const {
// fontSize: 25, 0: FlexColumnWidth(1),
// fontWeight: FontWeight.bold, 1: FlexColumnWidth(1),
// ), 2: FlexColumnWidth(1),
// ), },
// ), children: [
// Flexible( const TableRow(
// child: Text( children: [
// "Creator", TableCell(
// style: TextStyle( verticalAlignment: TableCellVerticalAlignment.middle,
// fontSize: 25, child: Padding(
// fontWeight: FontWeight.bold, padding: const EdgeInsets.only(bottom: 15.0),
// ), child: Center(
// ), child: Text(
// ), "Resources",
// Flexible( style: TextStyle(
// child: Text( fontSize: 25,
// "Link", fontWeight: FontWeight.bold,
// style: TextStyle( ),
// fontSize: 25, ),
// fontWeight: FontWeight.bold, ),
// ), ),
// ), ),
// ), TableCell(
// ], verticalAlignment: TableCellVerticalAlignment.middle,
// ), child: Padding(
// ), padding: const EdgeInsets.only(bottom: 15.0),
// const Padding( child: Center(
// padding: EdgeInsets.symmetric(vertical: 10.0), child: Text(
// child: Divider(), "Creator",
// ), style: TextStyle(
// displayIcon(MihIcons.mihLogo, "Tarah Meth", fontSize: 25,
// "https://app.mzansi-innovation-hub.co.za/"), fontWeight: FontWeight.bold,
// const SizedBox(height: 10), ),
// displayIcon(MihIcons.mihLogo, "Test", ),
// "https://www.flaticon.com/free-icons/mih"), ),
// const SizedBox(height: 10), ),
// displayIcon(MihIcons.mihLogo, "Test", ),
// "https://www.flaticon.com/free-icons/mih"), TableCell(
// const SizedBox(height: 10), child: Padding(
// displayIcon(MihIcons.mihLogo, "Test", padding: const EdgeInsets.only(bottom: 15.0),
// "https://www.flaticon.com/free-icons/mih"), child: Center(
// const SizedBox(height: 10), child: Text(
// ], "Link",
// ), style: TextStyle(
// ) fontSize: 25,
], fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
displayIcon(MihIcons.mihRing, "Tarah Meth",
"https://www.linkedin.com/in/tarah-meth-3b6309254/"),
displayIcon(MihIcons.mihLogo, "Tarah Meth",
"https://www.linkedin.com/in/tarah-meth-3b6309254/"),
displayIcon(
MihIcons.mzansiAi, "Ollama", "https://ollama.com/"),
displayIcon(MihIcons.mzansiWallet, "Freepik",
"https://www.flaticon.com/free-icon/wallet-passes-app_3884407?term=wallet&page=1&position=21&origin=search&related_id=3884407"),
displayIcon(MihIcons.patientProfile, "RaftelDesign",
"https://www.flaticon.com/free-icon/patient_2376100?term=medication&page=1&position=6&origin=search&related_id=2376100"),
displayIcon(MihIcons.patientProfile, "Srip",
"https://www.flaticon.com/free-icon/hospital_1233930?term=medical+snake&page=1&position=7&origin=search&related_id=1233930"),
displayIcon(MihIcons.calendar, "Freepik",
"https://www.flaticon.com/free-icon/calendar_2278049?term=calendar&page=1&position=5&origin=search&related_id=2278049"),
displayIcon(MihIcons.calculator, "Freepik",
"https://www.flaticon.com/free-icon/calculator_2374409?term=calculator&page=1&position=20&origin=search&related_id=2374409"),
displayIcon(MihIcons.aboutMih, "Chanut",
"https://www.flaticon.com/free-icon/info_151776?term=about&page=1&position=8&origin=search&related_id=151776"),
displayIcon(MihIcons.personalProfile, "Freepik",
"https://www.flaticon.com/free-icon/user_1077063?term=profile&page=1&position=6&origin=search&related_id=1077063"),
displayIcon(MihIcons.businessProfile, "Gravisio",
"https://www.flaticon.com/free-icon/contractor_11813336?term=company+profile&page=1&position=2&origin=search&related_id=11813336"),
displayIcon(MihIcons.patientManager, "Vector Tank",
"https://www.flaticon.com/free-icon/doctor_10215061?term=doctor&page=1&position=73&origin=search&related_id=10215061"),
displayIcon(MihIcons.profileSetup, "Freepik",
"https://www.flaticon.com/free-icon/add-user_748137?term=profile+add&page=1&position=1&origin=search&related_id=748137"),
displayIcon(MihIcons.businessSetup, "kerismaker",
"https://www.flaticon.com/free-icon/business_13569850?term=company+add&page=1&position=25&origin=search&related_id=13569850"),
displayIcon(MihIcons.calculator, "fawazahmed0",
"https://github.com/fawazahmed0/exchange-api"),
displayIcon(MihIcons.iDontKnow, "Freepik",
"https://www.flaticon.com/free-icon/i-dont-know_5359909?term=i+dont+know&page=1&position=7&origin=search&related_id=5359909"),
],
),
),
// SizedBox(
// width: 500,
// child: Column(
// children: [
// const SizedBox(
// width: double.infinity,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// mainAxisSize: MainAxisSize.max,
// children: [
// Flexible(
// child: Text(
// "Icon",
// style: TextStyle(
// fontSize: 25,
// fontWeight: FontWeight.bold,
// ),
// ),
// ),
// Flexible(
// child: Text(
// "Creator",
// style: TextStyle(
// fontSize: 25,
// fontWeight: FontWeight.bold,
// ),
// ),
// ),
// Flexible(
// child: Text(
// "Link",
// style: TextStyle(
// fontSize: 25,
// fontWeight: FontWeight.bold,
// ),
// ),
// ),
// ],
// ),
// ),
// const Padding(
// padding: EdgeInsets.symmetric(vertical: 10.0),
// child: Divider(),
// ),
// displayIcon(MihIcons.mihLogo, "Tarah Meth",
// "https://app.mzansi-innovation-hub.co.za/"),
// const SizedBox(height: 10),
// displayIcon(MihIcons.mihLogo, "Test",
// "https://www.flaticon.com/free-icons/mih"),
// const SizedBox(height: 10),
// displayIcon(MihIcons.mihLogo, "Test",
// "https://www.flaticon.com/free-icons/mih"),
// const SizedBox(height: 10),
// displayIcon(MihIcons.mihLogo, "Test",
// "https://www.flaticon.com/free-icons/mih"),
// const SizedBox(height: 10),
// ],
// ),
// )
],
),
), ),
); );
} }

View File

@@ -1,7 +1,9 @@
import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart'; import 'package:mzansi_innovation_hub/mih_objects/profile_link.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_profile_links.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_profile_links.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart';
@@ -432,7 +434,119 @@ class _MihInfoState extends State<MihInfo> {
children: [ children: [
MihButton( MihButton(
onPressed: () { onPressed: () {
MihInstallServices().installMihTrigger(context); if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Android") {
showDialog(
context: context,
builder: (context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: "Select Option",
onWindowTapClose: () {
context.pop();
},
windowBody: Column(
children: [
Text(
"Please select the platform you want to install/ Update MIH from",
style: TextStyle(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 25),
MihButton(
onPressed: () {
launchSocialUrl(
Uri.parse(
"https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih",
),
);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FaIcon(
FontAwesomeIcons.googlePlay,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
const SizedBox(width: 10),
Text(
"Play Store",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
const SizedBox(
height: 10,
),
MihButton(
onPressed: () {
launchSocialUrl(
Uri.parse(
"https://appgallery.huawei.com/app/C113315335?pkgName=za.co.mzansiinnovationhub.mih",
),
);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FaIcon(
Icons.store,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
const SizedBox(width: 10),
Text(
"App Gallery",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
);
},
);
} else {
MihInstallServices().installMihTrigger(context);
}
}, },
buttonColor: MihColors.getGreenColor( buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
@@ -736,6 +850,14 @@ class _MihInfoState extends State<MihInfo> {
destination: "Reddit", destination: "Reddit",
web_link: "https://www.reddit.com/r/Mzani_Innovation_Hub/", web_link: "https://www.reddit.com/r/Mzani_Innovation_Hub/",
), ),
ProfileLink(
idprofile_links: 1,
app_id: "1234",
business_id: "",
destination: "Git",
web_link:
"https://git.mzansi-innovation-hub.co.za/yaso_meth/mih-project",
),
]; ];
return Column( return Column(
children: [ children: [
@@ -752,7 +874,7 @@ class _MihInfoState extends State<MihInfo> {
), ),
MihProfileLinks(links: links), MihProfileLinks(links: links),
const SizedBox( const SizedBox(
height: 25, height: 75,
), ),
], ],
); );
@@ -777,6 +899,7 @@ class _MihInfoState extends State<MihInfo> {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
aboutHeadings(), aboutHeadings(),

View File

@@ -19,7 +19,6 @@ class _MihPrivacyPolicyState extends State<MihPrivacyPolicy> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MihPackageToolBody( return MihPackageToolBody(
borderOn: false, borderOn: false,
innerHorizontalPadding: 10,
bodyItem: getBody(context), bodyItem: getBody(context),
); );
} }
@@ -55,9 +54,13 @@ class _MihPrivacyPolicyState extends State<MihPrivacyPolicy> {
children children
.addAll(PolicyAndTermsText().getPrivacyPolicyText(context, englishOn)); .addAll(PolicyAndTermsText().getPrivacyPolicyText(context, englishOn));
return MihSingleChildScroll( return MihSingleChildScroll(
child: Column( scrollbarOn: true,
mainAxisSize: MainAxisSize.max, child: Padding(
children: children, padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: children,
),
), ),
); );
} }

View File

@@ -19,7 +19,6 @@ class _MIHTermsOfServiceState extends State<MIHTermsOfService> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MihPackageToolBody( return MihPackageToolBody(
borderOn: false, borderOn: false,
innerHorizontalPadding: 10,
bodyItem: getBody(context), bodyItem: getBody(context),
); );
} }
@@ -55,8 +54,12 @@ class _MIHTermsOfServiceState extends State<MIHTermsOfService> {
children children
.addAll(PolicyAndTermsText().getTermsOfServiceText(context, englishOn)); .addAll(PolicyAndTermsText().getTermsOfServiceText(context, englishOn));
return MihSingleChildScroll( return MihSingleChildScroll(
child: Column( scrollbarOn: true,
children: children, child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: children,
),
), ),
); );
} }

View File

@@ -290,6 +290,7 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
return Consumer<MihCalculatorProvider>( return Consumer<MihCalculatorProvider>(
builder: (context, calculatorProvider, child) { builder: (context, calculatorProvider, child) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"

View File

@@ -94,6 +94,7 @@ class _SimpleCalcState extends State<SimpleCalc> {
} }
} }
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,

View File

@@ -259,6 +259,7 @@ class _TipCalcState extends State<TipCalc> {
Widget getBody(double width) { Widget getBody(double width) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType == "desktop" padding: MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2) ? EdgeInsets.symmetric(horizontal: width * 0.2)

View File

@@ -5,6 +5,7 @@ import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_form.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_text_form_field.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
@@ -139,89 +140,85 @@ class _MihForgotPasswordState extends State<MihForgotPassword> {
validateInput(); validateInput();
} }
}, },
child: SafeArea( child: MihSingleChildScroll(
child: SingleChildScrollView( scrollbarOn: true,
physics: const BouncingScrollPhysics(), child: Padding(
child: Padding( padding: MzansiInnovationHub.of(context)!.theme.screenType ==
padding: MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
"desktop" ? EdgeInsets.symmetric(vertical: 25, horizontal: width * 0.2)
? EdgeInsets.symmetric(vertical: 25, horizontal: width * 0.2) : EdgeInsets.symmetric(vertical: 25, horizontal: width * 0.075),
: EdgeInsets.symmetric(vertical: 25, horizontal: width * 0.075), child: Column(
child: Column( mainAxisAlignment: MainAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.max,
mainAxisSize: MainAxisSize.max, children: [
children: [ //logo
//logo Icon(
Icon( Icons.lock,
Icons.lock, size: 100,
size: 100, color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
//spacer
const SizedBox(height: 10),
//Heading
Text(
'Forgot Password',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
), ),
//spacer ),
const SizedBox(height: 10), const SizedBox(height: 25),
//Heading MihForm(
Text( formKey: _formKey,
'Forgot Password', formFields: [
style: TextStyle( MihTextFormField(
fontSize: 25, fillColor: MihColors.getSecondaryColor(
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
controller: emailController,
multiLineInput: false,
requiredText: true,
hintText: "Email",
validator: (value) {
return MihValidationServices().validateEmail(value);
},
), ),
), //spacer
const SizedBox(height: 25), const SizedBox(height: 20),
MihForm( Align(
formKey: _formKey, alignment: Alignment.center,
formFields: [ child: MihButton(
MihTextFormField( onPressed: () {
fillColor: MihColors.getSecondaryColor( if (_formKey.currentState!.validate()) {
MzansiInnovationHub.of(context)!.theme.mode == prePassResteWarning();
"Dark"), } else {
inputColor: MihColors.getPrimaryColor( MihAlertServices().inputErrorAlert(context);
MzansiInnovationHub.of(context)!.theme.mode == }
"Dark"),
controller: emailController,
multiLineInput: false,
requiredText: true,
hintText: "Email",
validator: (value) {
return MihValidationServices().validateEmail(value);
}, },
), buttonColor: MihColors.getGreenColor(
//spacer MzansiInnovationHub.of(context)!.theme.mode ==
const SizedBox(height: 20), "Dark"),
Align( width: 300,
alignment: Alignment.center, child: Text(
child: MihButton( "Reset Password",
onPressed: () { style: TextStyle(
if (_formKey.currentState!.validate()) { color: MihColors.getPrimaryColor(
prePassResteWarning(); MzansiInnovationHub.of(context)!.theme.mode ==
} else { "Dark"),
MihAlertServices().inputErrorAlert(context); fontSize: 20,
} fontWeight: FontWeight.bold,
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Reset Password",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
), ),
), ),
), ),
], ),
), ],
], ),
), ],
), ),
), ),
), ),

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_form.dart';
@@ -107,7 +108,7 @@ class _MihRegisterState extends State<MihRegister> {
headers: { headers: {
'Content-type': 'application/json', 'Content-type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
"Authorization": "leatucczyixqwkqqdrhayiwzeofkltds" "Authorization": dotenv.env['SUPERTOKENS_API_KEY'] ?? "",
}, },
); );
//print("response 2: ${response2.statusCode}"); //print("response 2: ${response2.statusCode}");
@@ -204,6 +205,7 @@ class _MihRegisterState extends State<MihRegister> {
} }
}, },
child: MihSingleChildScroll( child: MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"

View File

@@ -5,6 +5,7 @@ import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_form.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_form.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_text_form_field.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_text_form_field.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
@@ -104,110 +105,104 @@ class _MihResetPasswordState extends State<MihResetPassword> {
} }
} }
}, },
child: SafeArea( child: MihSingleChildScroll(
child: SingleChildScrollView( scrollbarOn: true,
physics: const BouncingScrollPhysics(), child: Padding(
child: Padding( padding:
padding: MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" ? EdgeInsets.symmetric(horizontal: width * 0.2)
? EdgeInsets.symmetric(horizontal: width * 0.2) : EdgeInsets.symmetric(horizontal: width * 0.075),
: EdgeInsets.symmetric(horizontal: width * 0.075), child: Column(
child: Column( mainAxisAlignment: MainAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, children: [
children: [ // Text("Token: ${widget.token}"), // For testing purposes only
// Text("Token: ${widget.token}"), // For testing purposes only //logo
//logo Icon(
Icon( Icons.lock,
Icons.lock, size: 100,
size: 100, color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
),
//spacer
const SizedBox(height: 10),
//Heading
Text(
'Reset Password',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor( color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
), ),
//spacer ),
const SizedBox(height: 10), //spacer
//Heading const SizedBox(height: 25),
Text( MihForm(
'Reset Password', formKey: _formKey,
style: TextStyle( formFields: [
fontSize: 25, MihTextFormField(
fontWeight: FontWeight.bold, fillColor: MihColors.getSecondaryColor(
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
controller: passwordController,
multiLineInput: false,
requiredText: true,
hintText: "Password",
passwordMode: true,
autofillHints: const [AutofillHints.password],
validator: (value) {
return MihValidationServices().validatePassword(value);
},
), ),
), //spacer
//spacer const SizedBox(height: 10),
const SizedBox(height: 25), MihTextFormField(
MihForm( fillColor: MihColors.getSecondaryColor(
formKey: _formKey, MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
formFields: [ inputColor: MihColors.getPrimaryColor(
MihTextFormField( MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
fillColor: MihColors.getSecondaryColor( controller: confirmPasswordController,
MzansiInnovationHub.of(context)!.theme.mode == multiLineInput: false,
"Dark"), requiredText: true,
inputColor: MihColors.getPrimaryColor( hintText: "Confirm Password",
MzansiInnovationHub.of(context)!.theme.mode == passwordMode: true,
"Dark"), autofillHints: const [AutofillHints.password],
controller: passwordController, validator: (value) {
multiLineInput: false, return MihValidationServices().validatePassword(value);
requiredText: true, },
hintText: "Password", ),
passwordMode: true, //spacer
autofillHints: const [AutofillHints.password], const SizedBox(height: 25),
validator: (value) { // sign in button
return MihValidationServices().validatePassword(value); Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
submitFormInput();
} else {
MihAlertServices().inputErrorAlert(context);
}
}, },
), buttonColor: MihColors.getGreenColor(
//spacer
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
inputColor: MihColors.getPrimaryColor( width: 300,
MzansiInnovationHub.of(context)!.theme.mode == child: Text(
"Dark"), "Reset Password",
controller: confirmPasswordController, style: TextStyle(
multiLineInput: false, color: MihColors.getPrimaryColor(
requiredText: true, MzansiInnovationHub.of(context)!.theme.mode ==
hintText: "Confirm Password", "Dark"),
passwordMode: true, fontSize: 20,
autofillHints: const [AutofillHints.password], fontWeight: FontWeight.bold,
validator: (value) {
return MihValidationServices().validatePassword(value);
},
),
//spacer
const SizedBox(height: 25),
// sign in button
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
submitFormInput();
} else {
MihAlertServices().inputErrorAlert(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Reset Password",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
), ),
), ),
), ),
], ),
), ],
], ),
), ],
), ),
), ),
), ),

View File

@@ -202,6 +202,7 @@ class _MihSignInState extends State<MihSignIn> {
} }
}, },
child: MihSingleChildScroll( child: MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"

View File

@@ -626,6 +626,7 @@ class _MineSweeperGameState extends State<MineSweeperGame> {
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: board.isEmpty && squaresLeft < 0 child: board.isEmpty && squaresLeft < 0
// Start Up Message before setting up game // Start Up Message before setting up game
? Padding( ? Padding(

View File

@@ -845,6 +845,7 @@ class _MineSweeperQuickStartGuideState
Widget getBody(double width) { Widget getBody(double width) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20), padding: EdgeInsets.symmetric(horizontal: width / 20),
child: Column( child: Column(

View File

@@ -28,6 +28,7 @@ class _MihContactsState extends State<MihContacts> {
Widget getBody(double width) { Widget getBody(double width) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Padding( Padding(

View File

@@ -330,6 +330,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
} else if (directoryProvider.searchedBusinesses.isEmpty && } else if (directoryProvider.searchedBusinesses.isEmpty &&
directoryProvider.searchTerm.isNotEmpty) { directoryProvider.searchTerm.isNotEmpty) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 50), const SizedBox(height: 50),
@@ -357,6 +358,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
} else if (directoryProvider.searchedBusinesses.isEmpty && } else if (directoryProvider.searchedBusinesses.isEmpty &&
directoryProvider.searchTerm.isEmpty) { directoryProvider.searchTerm.isEmpty) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0), padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column( child: Column(
@@ -472,6 +474,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
} else if (directoryProvider.searchedUsers.isEmpty && } else if (directoryProvider.searchedUsers.isEmpty &&
directoryProvider.searchTerm.isEmpty) { directoryProvider.searchTerm.isEmpty) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0), padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column( child: Column(
@@ -533,6 +536,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
} else if (directoryProvider.searchedUsers.isEmpty && } else if (directoryProvider.searchedUsers.isEmpty &&
directoryProvider.searchTerm.isNotEmpty) { directoryProvider.searchTerm.isNotEmpty) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 50), const SizedBox(height: 50),

View File

@@ -316,6 +316,7 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
] ]
: null, : null,
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType == padding: MzansiInnovationHub.of(context)!.theme.screenType ==
"desktop" "desktop"

View File

@@ -251,278 +251,44 @@ class _MihUpdateBusinessDetailsWindowState
context.pop(); context.pop();
}, },
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: widget.width * 0.05) ? EdgeInsets.symmetric(horizontal: widget.width * 0.05)
: EdgeInsets.symmetric(horizontal: widget.width * 0), : EdgeInsets.symmetric(horizontal: widget.width * 0),
child: Column( child: Stack(
children: [ children: [
MihForm( Column(
formKey: _formKey, children: [
formFields: [ MihForm(
Center( formKey: _formKey,
child: MihCircleAvatar( formFields: [
imageFile: newSelectedLogoPic != null Center(
? MemoryImage(newSelectedLogoPic!.bytes!) child: MihCircleAvatar(
: mzansiProfileProvider.businessProfilePicture, imageFile: newSelectedLogoPic != null
width: 150, ? MemoryImage(newSelectedLogoPic!.bytes!)
editable: true, : mzansiProfileProvider
fileNameController: fileNameController, .businessProfilePicture,
userSelectedfile: newSelectedLogoPic, width: 150,
frameColor: MihColors.getSecondaryColor( editable: true,
MzansiInnovationHub.of(context)!.theme.mode == fileNameController: fileNameController,
"Dark"), userSelectedfile: newSelectedLogoPic,
backgroundColor: MihColors.getPrimaryColor( frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (selectedfile) {
setState(() {
newSelectedLogoPic = selectedfile;
});
},
),
),
Visibility(
visible: false,
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: fileNameController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Selected File Name",
),
),
const SizedBox(height: 20),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: nameController,
multiLineInput: false,
requiredText: true,
hintText: "Business Name",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: typeController,
multiLineInput: false,
requiredText: true,
hintText: "Business Type",
validator: (value) {
return MihValidationServices()
.validateNoSpecialChars(value);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: emailController,
multiLineInput: false,
requiredText: true,
hintText: "Business Email",
validator: (value) {
return MihValidationServices().validateEmail(value);
},
),
const SizedBox(height: 10),
Container(
width: 300,
alignment: Alignment.topLeft,
child: const Text(
"Contact Number:",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
CountryCodePicker(
padding: EdgeInsetsGeometry.all(0),
onChanged: (selectedCode) {
setState(() {
countryCodeController.text =
selectedCode.toString();
});
debugPrint(
"Selected Country Code: ${countryCodeController.text}");
},
initialSelection: countryCodeController.text,
showDropDownButton: false,
pickerStyle: PickerStyle.bottomSheet,
dialogBackgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
barrierColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
Expanded(
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
inputColor: MihColors.getPrimaryColor( backgroundColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
controller: contactController, onChange: (selectedfile) {
numberMode: true, setState(() {
multiLineInput: false, newSelectedLogoPic = selectedfile;
requiredText: true, });
hintText: null,
validator: (value) {
return MihValidationServices().isEmpty(value);
}, },
), ),
), ),
], Visibility(
), visible: false,
const SizedBox(height: 10),
MihTextFormField(
height: 250,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: missionVisionController,
multiLineInput: true,
requiredText: true,
hintText: "Business Mission & Vision",
validator: (value) {
return MihValidationServices().validateLength(
missionVisionController.text, 256);
},
),
SizedBox(
height: 15,
child: ValueListenableBuilder(
valueListenable: _counter,
builder:
(BuildContext context, int value, Widget? child) {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
"$value",
style: TextStyle(
color: getMissionVisionLimitColor(256),
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
Text(
"/256",
style: TextStyle(
color: getMissionVisionLimitColor(256),
fontWeight: FontWeight.bold,
),
),
],
);
},
),
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: websiteController,
multiLineInput: false,
requiredText: false,
hintText: "Business Website",
validator: (value) {
return MihValidationServices()
.validateWebsite(value, false);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: regController,
multiLineInput: false,
requiredText: false,
hintText: "Registration No.",
validator: (value) {
// return MihValidationServices().isEmpty(value);
return null;
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: practiceNoController,
multiLineInput: false,
requiredText: false,
hintText: "Practice Number",
validator: (validateValue) {
return null;
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: vatNoController,
multiLineInput: false,
requiredText: false,
hintText: "VAT Number",
validator: (value) {
// return MihValidationServices().isEmpty(value);
return null;
},
),
const SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(
child: MihTextFormField( child: MihTextFormField(
fillColor: MihColors.getSecondaryColor( fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
@@ -530,84 +296,374 @@ class _MihUpdateBusinessDetailsWindowState
inputColor: MihColors.getPrimaryColor( inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
controller: locationController, controller: fileNameController,
multiLineInput: false, multiLineInput: false,
requiredText: true, requiredText: true,
readOnly: true, readOnly: true,
hintText: "GPS Location", hintText: "Selected File Name",
), ),
), ),
const SizedBox(width: 10.0), const SizedBox(height: 20),
MihButton( MihTextFormField(
onPressed: () { fillColor: MihColors.getSecondaryColor(
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle(
message: "Getting your location",
);
},
);
MIHLocationAPI()
.getGPSPosition(context)
.then((position) {
if (position != null) {
setState(() {
locationController.text =
"${position.latitude}, ${position.longitude}";
});
}
//Dismiss loading indicator
context.pop();
});
},
buttonColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
width: 100, inputColor: MihColors.getPrimaryColor(
child: Text( MzansiInnovationHub.of(context)!.theme.mode ==
"Set", "Dark"),
controller: nameController,
multiLineInput: false,
requiredText: true,
hintText: "Business Name",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: typeController,
multiLineInput: false,
requiredText: true,
hintText: "Business Type",
validator: (value) {
return MihValidationServices()
.validateNoSpecialChars(value);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: emailController,
multiLineInput: false,
requiredText: true,
hintText: "Business Email",
validator: (value) {
return MihValidationServices()
.validateEmail(value);
},
),
const SizedBox(height: 10),
Container(
width: 300,
alignment: Alignment.topLeft,
child: const Text(
"Contact Number:",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( fontSize: 18,
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
), ),
], Row(
), crossAxisAlignment: CrossAxisAlignment.end,
const SizedBox(height: 25), children: [
Center( CountryCodePicker(
child: MihButton( padding: EdgeInsetsGeometry.all(0),
onPressed: () { onChanged: (selectedCode) {
if (_formKey.currentState!.validate()) { setState(() {
submitForm(mzansiProfileProvider); countryCodeController.text =
} else { selectedCode.toString();
MihAlertServices().inputErrorAlert(context); });
} debugPrint(
}, "Selected Country Code: ${countryCodeController.text}");
buttonColor: MihColors.getGreenColor( },
MzansiInnovationHub.of(context)!.theme.mode == initialSelection: countryCodeController.text,
"Dark"), showDropDownButton: false,
width: 300, pickerStyle: PickerStyle.bottomSheet,
child: Text( dialogBackgroundColor:
"Update", MihColors.getPrimaryColor(
style: TextStyle( MzansiInnovationHub.of(context)!
color: MihColors.getPrimaryColor( .theme
MzansiInnovationHub.of(context)!.theme.mode == .mode ==
"Dark"), "Dark"),
fontSize: 20, barrierColor: MihColors.getPrimaryColor(
fontWeight: FontWeight.bold, MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
Expanded(
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
controller: contactController,
numberMode: true,
multiLineInput: false,
requiredText: true,
hintText: null,
validator: (value) {
return MihValidationServices()
.isEmpty(value);
},
),
),
],
),
const SizedBox(height: 10),
MihTextFormField(
height: 250,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: missionVisionController,
multiLineInput: true,
requiredText: true,
hintText: "Business Mission & Vision",
validator: (value) {
return MihValidationServices().validateLength(
missionVisionController.text, 256);
},
),
SizedBox(
height: 15,
child: ValueListenableBuilder(
valueListenable: _counter,
builder: (BuildContext context, int value,
Widget? child) {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
"$value",
style: TextStyle(
color: getMissionVisionLimitColor(256),
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
Text(
"/256",
style: TextStyle(
color: getMissionVisionLimitColor(256),
fontWeight: FontWeight.bold,
),
),
],
);
},
), ),
), ),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: websiteController,
multiLineInput: false,
requiredText: false,
hintText: "Business Website",
validator: (value) {
return MihValidationServices()
.validateWebsite(value, false);
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: regController,
multiLineInput: false,
requiredText: false,
hintText: "Registration No.",
validator: (value) {
// return MihValidationServices().isEmpty(value);
return null;
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: practiceNoController,
multiLineInput: false,
requiredText: false,
hintText: "Practice Number",
validator: (validateValue) {
return null;
},
),
const SizedBox(height: 10),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: vatNoController,
multiLineInput: false,
requiredText: false,
hintText: "VAT Number",
validator: (value) {
// return MihValidationServices().isEmpty(value);
return null;
},
),
const SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
controller: locationController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "GPS Location",
),
),
const SizedBox(width: 10.0),
MihButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle(
message: "Getting your location",
);
},
);
MIHLocationAPI()
.getGPSPosition(context)
.then((position) {
if (position != null) {
setState(() {
locationController.text =
"${position.latitude}, ${position.longitude}";
});
}
//Dismiss loading indicator
context.pop();
});
},
buttonColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
width: 100,
child: Text(
"Set",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
const SizedBox(height: 25),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
submitForm(mzansiProfileProvider);
} else {
MihAlertServices().inputErrorAlert(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(height: 20),
],
),
],
),
Positioned(
right: 0,
top: 0,
child: MihButton(
onPressed: () {
//Add validation here
if (_formKey.currentState!.validate()) {
submitForm(mzansiProfileProvider);
} else {
MihAlertServices().inputErrorAlert(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 100,
height: 25,
child: Text(
mzansiProfileProvider.user!.username.isEmpty
? "Setup Profile"
: "Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 15,
fontWeight: FontWeight.bold,
), ),
), ),
const SizedBox(height: 20), ),
],
), ),
], ],
), ),

View File

@@ -127,6 +127,7 @@ class _MihUpdateMyBusinessUserDetailsState
builder: (BuildContext context, builder: (BuildContext context,
MzansiProfileProvider mzansiProfileProvider, Widget? child) { MzansiProfileProvider mzansiProfileProvider, Widget? child) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"

View File

@@ -1,9 +1,10 @@
import 'package:custom_rating_bar/custom_rating_bar.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_business_info_card_v2.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart'; import 'package:mzansi_innovation_hub/mih_providers/mzansi_profile_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_business_info_card.dart';
import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_update_business_details_window.dart'; import 'package:mzansi_innovation_hub/mih_packages/mzansi_profile/business_profile/components/mih_update_business_details_window.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
@@ -60,32 +61,62 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType == padding: MzansiInnovationHub.of(context)!.theme.screenType ==
"desktop" "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2) ? EdgeInsets.symmetric(horizontal: width * 0.2)
: EdgeInsets.symmetric(horizontal: width * 0.075), : EdgeInsets.symmetric(horizontal: width * 0),
child: Column( child: Column(
children: [ children: [
Center( Center(
child: MihCircleAvatar( child: Stack(
key: UniqueKey(), children: [
imageFile: mzansiProfileProvider.businessProfilePicture, MihCircleAvatar(
width: 150, key: UniqueKey(),
editable: false, imageFile:
fileNameController: fileNameController, mzansiProfileProvider.businessProfilePicture,
userSelectedfile: newSelectedLogoPic, width: 150,
frameColor: MihColors.getSecondaryColor( editable: false,
MzansiInnovationHub.of(context)!.theme.mode == fileNameController: fileNameController,
"Dark"), userSelectedfile: newSelectedLogoPic,
backgroundColor: MihColors.getPrimaryColor( frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
onChange: (selectedfile) { backgroundColor: MihColors.getPrimaryColor(
setState(() { MzansiInnovationHub.of(context)!.theme.mode ==
newSelectedLogoPic = selectedfile; "Dark"),
}); onChange: (selectedfile) {
}, setState(() {
newSelectedLogoPic = selectedfile;
});
},
),
Positioned(
bottom: 5,
right: 5,
child: MihButton(
onPressed: () {
// editProfileWindow(width);
editBizProfileWindow(
mzansiProfileProvider, width);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 35,
height: 35,
child: Icon(
Icons.edit,
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
),
),
),
],
), ),
), ),
FittedBox( FittedBox(
@@ -112,6 +143,30 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
), ),
), ),
), ),
RatingBar.readOnly(
size: 50,
alignment: Alignment.center,
filledIcon: Icons.star,
emptyIcon: Icons.star_border,
halfFilledIcon: Icons.star_half,
filledColor: MihColors.getYellowColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
// MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
emptyColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
halfFilledColor: MihColors.getYellowColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
// MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
isHalfAllowed: true,
initialRating: mzansiProfileProvider
.business!.rating.isNotEmpty
? double.parse(mzansiProfileProvider.business!.rating)
: 0,
maxRating: 5,
),
const SizedBox(height: 5), const SizedBox(height: 5),
Center( Center(
child: SizedBox( child: SizedBox(
@@ -133,68 +188,16 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
), ),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
SizedBox( MihBusinessCardV2(
width: 700, business: mzansiProfileProvider.business!,
child: MihBusinessCard( // startUpSearch: null,
business: mzansiProfileProvider.business!, width: width,
// startUpSearch: null,
width: width,
),
), ),
const SizedBox(height: 30.0), const SizedBox(height: 30.0),
Center(
child: MihButton(
onPressed: () {
// Connect with the user
editBizProfileWindow(mzansiProfileProvider, width);
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
"Edit Profile",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
], ],
), ),
), ),
), ),
// Positioned(
// right: 5,
// bottom: 10,
// child: MihFloatingMenu(
// animatedIcon: AnimatedIcons.menu_close,
// children: [
// SpeedDialChild(
// child: Icon(
// Icons.edit,
// color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// ),
// label: "Edit Profile",
// labelBackgroundColor:
// MihColors.getGreenColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// labelStyle: TextStyle(
// color: MihColors.getPrimaryColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// fontWeight: FontWeight.bold,
// ),
// backgroundColor:
// MihColors.getGreenColor(MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
// onTap: () {
// editBizProfileWindow(width);
// },
// )
// ],
// ),
// ),
], ],
); );
}, },

View File

@@ -765,7 +765,7 @@ class _MihBusinessDetailsSetUpState extends State<MihBusinessDetailsSetUp> {
"Dark"), "Dark"),
width: 300, width: 300,
child: Text( child: Text(
"Add", "Set Up Buasiness",
style: TextStyle( style: TextStyle(
color: MihColors.getPrimaryColor( color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==

View File

@@ -3,10 +3,10 @@ import 'package:custom_rating_bar/custom_rating_bar.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_business_info_card_v2.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_providers/mzansi_directory_provider.dart'; import 'package:mzansi_innovation_hub/mih_providers/mzansi_directory_provider.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_business_info_card.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart'; import 'package:mzansi_innovation_hub/mih_services/mih_file_services.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tool_body.dart';
@@ -58,11 +58,12 @@ class _MihBusinessDetailsViewState extends State<MihBusinessDetailsView> {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType == padding: MzansiInnovationHub.of(context)!.theme.screenType ==
"desktop" "desktop"
? EdgeInsets.symmetric(horizontal: width * 0.2) ? EdgeInsets.symmetric(horizontal: width * 0.2)
: EdgeInsets.symmetric(horizontal: width * 0.075), : EdgeInsets.symmetric(horizontal: width * 0),
child: Column( child: Column(
children: [ children: [
FutureBuilder( FutureBuilder(
@@ -154,40 +155,6 @@ class _MihBusinessDetailsViewState extends State<MihBusinessDetailsView> {
), ),
), ),
), ),
const SizedBox(height: 5),
// FittedBox(
// child: Text(
// "Mission & Vision",
// style: TextStyle(
// fontSize: 15,
// fontWeight: FontWeight.bold,
// color: MzansiInnovationHub.of(context)!
// .theme
// .secondaryColor(),
// ),
// ),
// ),
Center(
child: SizedBox(
width: 700,
child: Text(
directoryProvider
.selectedBusiness!.mission_vision.isNotEmpty
? directoryProvider
.selectedBusiness!.mission_vision
: "No Mission & Vision added yet",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
),
),
const SizedBox(height: 10),
RatingBar.readOnly( RatingBar.readOnly(
size: 50, size: 50,
alignment: Alignment.center, alignment: Alignment.center,
@@ -213,14 +180,32 @@ class _MihBusinessDetailsViewState extends State<MihBusinessDetailsView> {
: 0, : 0,
maxRating: 5, maxRating: 5,
), ),
const SizedBox(height: 20), const SizedBox(height: 5),
SizedBox( Center(
width: 700, child: SizedBox(
child: MihBusinessCard( width: 700,
business: directoryProvider.selectedBusiness!, child: Text(
width: width, directoryProvider
.selectedBusiness!.mission_vision.isNotEmpty
? directoryProvider
.selectedBusiness!.mission_vision
: "No Mission & Vision added yet",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
), ),
), ),
const SizedBox(height: 20),
MihBusinessCardV2(
business: directoryProvider.selectedBusiness!,
width: width,
),
], ],
), ),
), ),

View File

@@ -367,6 +367,7 @@ class _MihBusinessQrCodeState extends State<MihBusinessQrCode> {
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0), padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Padding( child: Padding(

View File

@@ -175,6 +175,7 @@ class _MihMyBusinessUserState extends State<MihMyBusinessUser> {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: MzansiInnovationHub.of(context)!.theme.screenType == padding: MzansiInnovationHub.of(context)!.theme.screenType ==
"desktop" "desktop"

View File

@@ -329,195 +329,232 @@ class _MihEditPersonalProfileWindowState
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
? EdgeInsets.symmetric(horizontal: screenWidth * 0.05) ? EdgeInsets.symmetric(horizontal: screenWidth * 0.05)
: EdgeInsets.symmetric(horizontal: screenWidth * 0), : EdgeInsets.symmetric(horizontal: screenWidth * 0),
child: Column( child: Stack(
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
MihForm( Column(
formKey: _formKey, mainAxisAlignment: MainAxisAlignment.start,
formFields: [ children: [
Center( MihForm(
child: MihCircleAvatar( formKey: _formKey,
imageFile: newSelectedProPic != null formFields: [
? MemoryImage(newSelectedProPic!.bytes!) Center(
: mzansiProfileProvider.userProfilePicture, child: MihCircleAvatar(
width: 150, imageFile: newSelectedProPic != null
editable: true, ? MemoryImage(newSelectedProPic!.bytes!)
fileNameController: proPicController, : mzansiProfileProvider.userProfilePicture,
userSelectedfile: newSelectedProPic, width: 150,
frameColor: MihColors.getSecondaryColor( editable: true,
MzansiInnovationHub.of(context)!.theme.mode == fileNameController: proPicController,
"Dark"), userSelectedfile: newSelectedProPic,
backgroundColor: MihColors.getPrimaryColor( frameColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (selectedImage) {
setState(() {
newSelectedProPic = selectedImage;
});
},
),
),
// const SizedBox(height: 25.0),
Visibility(
visible: false,
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: proPicController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Selected File Name",
),
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: usernameController,
multiLineInput: false,
requiredText: true,
hintText: "Username",
validator: (value) {
return MihValidationServices().validateUsername(value);
},
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: fnameController,
multiLineInput: false,
requiredText: true,
hintText: "First Name",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: lnameController,
multiLineInput: false,
requiredText: true,
hintText: "Last Name",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10.0),
MihTextFormField(
height: 250,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: purposeController,
multiLineInput: true,
requiredText: true,
hintText: "Your Personal Mission",
validator: (value) {
return MihValidationServices()
.validateLength(purposeController.text, 256);
},
),
SizedBox(
height: 15,
child: ValueListenableBuilder(
valueListenable: _counter,
builder:
(BuildContext context, int value, Widget? child) {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
"$value",
style: TextStyle(
color: getPurposeLimitColor(256),
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
Text(
"/256",
style: TextStyle(
color: getPurposeLimitColor(256),
fontWeight: FontWeight.bold,
),
),
],
);
},
),
),
const SizedBox(height: 10.0),
MihToggle(
hintText: "Activate Business Account",
initialPostion: businessUser,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
secondaryFillColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (value) {
setState(() {
businessUser = value;
});
KenLogger.success("Business User: $businessUser");
},
),
const SizedBox(height: 30.0),
Center(
child: MihButton(
onPressed: () {
//Add validation here
if (_formKey.currentState!.validate()) {
submitForm(mzansiProfileProvider);
} else {
MihAlertServices().inputErrorAlert(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
mzansiProfileProvider.user!.username.isEmpty
? "Setup Profile"
: "Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode == MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"), "Dark"),
fontSize: 20, backgroundColor: MihColors.getPrimaryColor(
fontWeight: FontWeight.bold, MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (selectedImage) {
setState(() {
newSelectedProPic = selectedImage;
});
},
), ),
), ),
), // const SizedBox(height: 25.0),
Visibility(
visible: false,
child: MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: proPicController,
multiLineInput: false,
requiredText: true,
readOnly: true,
hintText: "Selected File Name",
),
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: usernameController,
multiLineInput: false,
requiredText: true,
hintText: "Username",
validator: (value) {
return MihValidationServices()
.validateUsername(value);
},
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: fnameController,
multiLineInput: false,
requiredText: true,
hintText: "First Name",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10.0),
MihTextFormField(
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: lnameController,
multiLineInput: false,
requiredText: true,
hintText: "Last Name",
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10.0),
MihTextFormField(
height: 250,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
inputColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
controller: purposeController,
multiLineInput: true,
requiredText: true,
hintText: "Your Personal Mission",
validator: (value) {
return MihValidationServices()
.validateLength(purposeController.text, 256);
},
),
SizedBox(
height: 15,
child: ValueListenableBuilder(
valueListenable: _counter,
builder: (BuildContext context, int value,
Widget? child) {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
"$value",
style: TextStyle(
color: getPurposeLimitColor(256),
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 5),
Text(
"/256",
style: TextStyle(
color: getPurposeLimitColor(256),
fontWeight: FontWeight.bold,
),
),
],
);
},
),
),
const SizedBox(height: 10.0),
MihToggle(
hintText: "Activate Business Account",
initialPostion: businessUser,
fillColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
secondaryFillColor: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
onChange: (value) {
setState(() {
businessUser = value;
});
KenLogger.success("Business User: $businessUser");
},
),
const SizedBox(height: 30.0),
Center(
child: MihButton(
onPressed: () {
//Add validation here
if (_formKey.currentState!.validate()) {
submitForm(mzansiProfileProvider);
} else {
MihAlertServices().inputErrorAlert(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
width: 300,
child: Text(
mzansiProfileProvider.user!.username.isEmpty
? "Setup Profile"
: "Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!
.theme
.mode ==
"Dark"),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
), ),
], ],
), ),
Positioned(
right: 0,
top: 0,
child: MihButton(
onPressed: () {
//Add validation here
if (_formKey.currentState!.validate()) {
submitForm(mzansiProfileProvider);
} else {
MihAlertServices().inputErrorAlert(context);
}
},
buttonColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
width: 100,
height: 25,
child: Text(
mzansiProfileProvider.user!.username.isEmpty
? "Setup Profile"
: "Update",
style: TextStyle(
color: MihColors.getPrimaryColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
),
),
], ],
), ),
), ),

View File

@@ -146,6 +146,7 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
); );
} else { } else {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"

View File

@@ -54,6 +54,7 @@ class _MihPersonalProfileViewState extends State<MihPersonalProfileView> {
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider, builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
Widget? child) { Widget? child) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Padding( child: Padding(
padding: padding:
MzansiInnovationHub.of(context)!.theme.screenType == "desktop" MzansiInnovationHub.of(context)!.theme.screenType == "desktop"

View File

@@ -81,6 +81,7 @@ class _MihPersonalSettingsState extends State<MihPersonalSettings> {
Widget getBody(MzansiProfileProvider mzansiProfileProvider) { Widget getBody(MzansiProfileProvider mzansiProfileProvider) {
return MihSingleChildScroll( return MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Center( Center(

View File

@@ -306,6 +306,7 @@ class _PatientInfoState extends State<PatientInfo> {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [

View File

@@ -20,7 +20,7 @@ class MzansiAiProvider extends ChangeNotifier {
ollamaProvider = OllamaProvider( ollamaProvider = OllamaProvider(
baseUrl: "${AppEnviroment.baseAiUrl}/api", baseUrl: "${AppEnviroment.baseAiUrl}/api",
model: AppEnviroment.getEnv() == "Prod" model: AppEnviroment.getEnv() == "Prod"
? 'qwen3-vl:8b' ? 'qwen3-vl:8b-instruct'
: "qwen3-vl:2b-instruct", : "qwen3-vl:2b-instruct",
think: false, think: false,
systemPrompt: "---INSTRUCTION START---\n" systemPrompt: "---INSTRUCTION START---\n"

View File

@@ -32,6 +32,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -109,6 +110,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -186,6 +188,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -298,6 +301,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -416,6 +420,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -493,6 +498,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -594,6 +600,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -671,6 +678,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -748,6 +756,7 @@ class MihAlertServices {
backgroundColor: MihColors.getSecondaryColor( backgroundColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -830,6 +839,7 @@ class MihAlertServices {
backgroundColor: MihColors.getSecondaryColor( backgroundColor: MihColors.getSecondaryColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -900,6 +910,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -1007,6 +1018,7 @@ class MihAlertServices {
backgroundColor: MihColors.getGreenColor( backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -1089,6 +1101,7 @@ class MihAlertServices {
backgroundColor: MihColors.getGreenColor( backgroundColor: MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -1159,6 +1172,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(
@@ -1244,6 +1258,7 @@ class MihAlertServices {
backgroundColor: MihColors.getRedColor( backgroundColor: MihColors.getRedColor(
MzansiInnovationHub.of(context)!.theme.mode != "Dark"), MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
windowBody: MihSingleChildScroll( windowBody: MihSingleChildScroll(
scrollbarOn: true,
child: Column( child: Column(
children: [ children: [
Icon( Icon(

View File

@@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
@@ -32,7 +33,7 @@ class MihAuthenticationServices {
headers: { headers: {
'Content-type': 'application/json', 'Content-type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
"Authorization": "leatucczyixqwkqqdrhayiwzeofkltds" "Authorization": dotenv.env['SUPERTOKENS_API_KEY'] ?? "",
}, },
); );
if (response.statusCode == 200) { if (response.statusCode == 200) {

View File

@@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) {
if (use_header_bar) { if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar)); gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "patient_manager"); gtk_header_bar_set_title(header_bar, "MIH App - Mzansi Innovation Hub");
gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else { } else {
gtk_window_set_title(window, "patient_manager"); gtk_window_set_title(window, "MIH App - Mzansi Innovation Hub");
} }
gtk_window_set_default_size(window, 1280, 720); gtk_window_set_default_size(window, 1280, 720);

View File

@@ -670,6 +670,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.0" version: "0.3.0"
flutter_dotenv:
dependency: "direct main"
description:
name: flutter_dotenv
sha256: d4130c4a43e0b13fefc593bc3961f2cb46e30cb79e253d4a526b1b5d24ae1ce4
url: "https://pub.dev"
source: hosted
version: "6.0.0"
flutter_launcher_icons: flutter_launcher_icons:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -1,7 +1,7 @@
name: mzansi_innovation_hub name: mzansi_innovation_hub
description: "" description: ""
publish_to: 'none' # Remove this line if you wish to publish to pub.dev publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.2.5+126 version: 1.2.6+127
# version: 1.1.1+97 #--- Updated version for upgrader package testing # version: 1.1.1+97 #--- Updated version for upgrader package testing
environment: environment:
@@ -12,6 +12,7 @@ dependencies:
sdk: flutter sdk: flutter
flutter_web_plugins: flutter_web_plugins:
sdk: flutter sdk: flutter
flutter_dotenv: ^6.0.0
cupertino_icons: ^1.0.8 cupertino_icons: ^1.0.8
font_awesome_flutter: ^10.7.0 font_awesome_flutter: ^10.7.0
@@ -76,6 +77,7 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
assets: assets:
- .env
- lib/mih_package_components/assets/images/ - lib/mih_package_components/assets/images/
- lib/mih_package_components/assets/fonts/ - lib/mih_package_components/assets/fonts/
- lib/mih_package_components/assets/images/loyalty_cards/ - lib/mih_package_components/assets/images/loyalty_cards/

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env python
# Inspired by https://gist.github.com/jtangelder/e445e9a7f5e31c220be6
# Python3 http.server for Single Page Application
import urllib.parse
import http.server
import socketserver
import re
from pathlib import Path
port = 83
HOST = ('', port)
pattern = re.compile('.png|.jpg|.jpeg|.js|.css|.ico|.gif|.svg|.ico', re.IGNORECASE)
class Handler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
url_parts = urllib.parse.urlparse(self.path)
request_file_path = Path(url_parts.path.strip("/"))
ext = request_file_path.suffix
if not request_file_path.is_file() and not pattern.match(ext):
self.path = 'index.html'
return http.server.SimpleHTTPRequestHandler.do_GET(self)
httpd = socketserver.TCPServer(HOST, Handler)
print(f"Starting Web App Server on pot: {port}")
httpd.serve_forever()

View File

@@ -1,18 +0,0 @@
#!/bin/bash
# Define the port
PORT=83
# Check if the port is in use and release it if necessary.
# echo "Checking if port $PORT is in use..."
# if [ "$(lsof -t -i :$PORT)" ]; then
# echo "Port $PORT is in use. Stopping the process on that port..."
# fuser -k -n tcp $PORT
# fi
# Switch to the web construction directory
cd /app/build/web/
# Start the web server on the specified port
#python3 -m http.server 83
python3 -u ../../server/MIH_web_server.py