Compare commits
60 Commits
tester-bra
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 971623af77 | |||
| 84cb6b2e83 | |||
| 6e07a55885 | |||
| 8fb31695a8 | |||
| 4fafa35888 | |||
| 0cf9634c5d | |||
| 787a8057b2 | |||
| 5f911d51f9 | |||
| 8da29792b4 | |||
| fd4c34c59d | |||
| 5e003a4d71 | |||
| dca595bf60 | |||
| fcf1bbbb15 | |||
| 8a0c0d7dba | |||
| ff7f363983 | |||
| a54f1c61ae | |||
| 843997e58c | |||
| cbe70e2e44 | |||
| 3778ebb261 | |||
| c911e88453 | |||
| b1487839a7 | |||
| 518dd1300e | |||
| 221030eff3 | |||
| 707b49c088 | |||
| 5135629b33 | |||
| bb64be077f | |||
| 281ea863e8 | |||
| 64af64f28b | |||
| 1c0dd6d328 | |||
| 07d4ba4afa | |||
| 6ad6b6ccbd | |||
| ce2575035f | |||
| baea2c9fdb | |||
| 27639cb964 | |||
| 1143d11054 | |||
| 213f3d418d | |||
| e33a62b909 | |||
| ebab9bae52 | |||
| 82c25c5406 | |||
| 3f0fc08a5c | |||
| f137ea41ac | |||
| a7effa3576 | |||
| 74341a9cc6 | |||
| c5267c0540 | |||
| d4ba3aaa03 | |||
| 103ccdc022 | |||
| f8a722eb50 | |||
| fdb28080e3 | |||
| 8a384921c5 | |||
| 4b47bf5288 | |||
| 141611b84d | |||
| a29d0afeb8 | |||
| eb93714022 | |||
| 071612a521 | |||
| 726a60ad25 | |||
| b897986c1f | |||
| 7d4d7fc713 | |||
| 91075255f4 | |||
| 5c2f19dcc4 | |||
| 58aebbeabe |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,3 +11,4 @@ Mzansi_Mail/
|
||||
google-chrome-stable_current_amd64.deb
|
||||
.env
|
||||
Frontend/android/app/.cxx/
|
||||
.DS_Store
|
||||
11
.vscode/launch.json
vendored
11
.vscode/launch.json
vendored
@@ -11,6 +11,17 @@
|
||||
"type": "dart",
|
||||
"program": "lib/main_dev.dart"
|
||||
},
|
||||
{
|
||||
"name": "Debug (web)",
|
||||
"cwd": "mih_ui",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"program": "lib/main_dev.dart",
|
||||
"args": [
|
||||
"--web-port",
|
||||
"1995"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Profile",
|
||||
"cwd": "mih_ui",
|
||||
|
||||
@@ -4,37 +4,6 @@ networks:
|
||||
driver: bridge
|
||||
#============== MIH Containers ====================================================================
|
||||
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 ====================================================================
|
||||
mih-nginx:
|
||||
container_name: mih-nginx
|
||||
@@ -43,7 +12,7 @@ services:
|
||||
ports:
|
||||
- '80:80' # Public HTTP
|
||||
- '443:443' # Public HTTPS
|
||||
- '81:81' # Admin Web Port
|
||||
- '127.0.0.1:81:81' # Admin Web Port
|
||||
volumes:
|
||||
- ./mih_nginx/data:/data
|
||||
- ./mih_nginx/letsencrypt:/etc/letsencrypt
|
||||
@@ -69,8 +38,8 @@ services:
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "222:22"
|
||||
- "127.0.0.1:3000:3000"
|
||||
- "127.0.0.1:222:22"
|
||||
depends_on:
|
||||
mih-gitea-db:
|
||||
condition: service_healthy
|
||||
@@ -99,7 +68,7 @@ services:
|
||||
depends_on:
|
||||
- mih-db
|
||||
ports:
|
||||
- 3567:3567
|
||||
- '127.0.0.1:3567:3567'
|
||||
environment:
|
||||
REFRESH_TOKEN_VALIDITY: '604800'
|
||||
ACCESS_TOKEN_VALIDITY: '86400'
|
||||
@@ -125,7 +94,7 @@ services:
|
||||
image: wordpress
|
||||
restart: always
|
||||
ports:
|
||||
- 8081:80
|
||||
- '127.0.0.1:8081:80'
|
||||
environment:
|
||||
WORDPRESS_DB_HOST: mih-wp-db
|
||||
WORDPRESS_DB_USER: ${WP_SQL_USER}
|
||||
@@ -154,7 +123,7 @@ services:
|
||||
build:
|
||||
context: ./mih_ui
|
||||
ports:
|
||||
- "83:83"
|
||||
- "127.0.0.1:83:83"
|
||||
networks:
|
||||
- mih-network
|
||||
depends_on:
|
||||
@@ -166,7 +135,7 @@ services:
|
||||
target: builder
|
||||
container_name: mih-api-hub
|
||||
ports:
|
||||
- 8080:80
|
||||
- "127.0.0.1:8080:80"
|
||||
volumes:
|
||||
- ./mih_api_hub:/app
|
||||
networks:
|
||||
@@ -187,7 +156,7 @@ services:
|
||||
networks:
|
||||
- mih-network
|
||||
ports:
|
||||
- '3306:3306'
|
||||
- '127.0.0.1:3306:3306'
|
||||
volumes:
|
||||
- ./mih_db:/var/lib/mysql
|
||||
#============== PHP My Admin ====================================================================
|
||||
@@ -213,8 +182,8 @@ services:
|
||||
hostname: mih-minio
|
||||
image: minio/minio
|
||||
ports:
|
||||
- '9000:9000'
|
||||
- '9001:9001'
|
||||
- '127.0.0.1:9000:9000'
|
||||
- '127.0.0.1:9001:9001'
|
||||
volumes:
|
||||
- './mih_minio:/data'
|
||||
environment:
|
||||
@@ -228,7 +197,7 @@ services:
|
||||
container_name: mih-monitor
|
||||
image: portainer/portainer-ce:2.20.3
|
||||
ports:
|
||||
- 9444:9443
|
||||
- '127.0.0.1:9444:9443'
|
||||
volumes:
|
||||
- ./mih_monitor/data:/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
@@ -240,7 +209,7 @@ services:
|
||||
container_name: mih-ai
|
||||
image: ollama/ollama:latest
|
||||
ports:
|
||||
- 11434:11434
|
||||
- '127.0.0.1:11434:11434'
|
||||
volumes:
|
||||
- ./mih_ai/ollama/ollama:/root/.ollama
|
||||
pull_policy: always
|
||||
|
||||
1
mih_api_hub/.gitignore
vendored
1
mih_api_hub/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
.env
|
||||
__pycache__/
|
||||
temp*.pdf
|
||||
.DS_Store
|
||||
@@ -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
|
||||
# )
|
||||
@@ -34,28 +34,36 @@ from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||
from supertokens_python.recipe.emailverification import EmailVerificationClaim
|
||||
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 = [
|
||||
"http://localhost",
|
||||
"http://localhost:80",
|
||||
"http://localhost:1995",
|
||||
"http://localhost:8080",
|
||||
"http://MIH-API-Hub:80",
|
||||
"http://MIH-API-Hub",
|
||||
"http://api.mzansi-innovation-hub.co.za",
|
||||
"*",
|
||||
"http://app.mzansi-innovation-hub.co.za",
|
||||
"https://api.mzansi-innovation-hub.co.za",
|
||||
"https://app.mzansi-innovation-hub.co.za",
|
||||
]
|
||||
|
||||
init(
|
||||
app_info=InputAppInfo(
|
||||
app_name="Mzansi Innovation Hub",
|
||||
api_domain="http://localhost:8080/",
|
||||
website_domain="http://app.mzansi-innovation-hub.co.za",
|
||||
website_domain="https://app.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="http://mih-supertokens:3567/",
|
||||
api_key="leatucczyixqwkqqdrhayiwzeofkltds"
|
||||
api_key=st_api_key
|
||||
),
|
||||
framework='fastapi',
|
||||
recipe_list=[
|
||||
|
||||
@@ -9,5 +9,5 @@ watchfiles
|
||||
python-multipart
|
||||
python-dotenv
|
||||
xlrd
|
||||
supertokens-python
|
||||
supertokens-python==0.24.0
|
||||
sniffio
|
||||
2
mih_ui/.gitignore
vendored
2
mih_ui/.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
.env
|
||||
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
|
||||
@@ -1,48 +1,36 @@
|
||||
# Install Operating system and dependencies
|
||||
#FROM ubuntu:22.04
|
||||
# --- STAGE 1: The Builder ---
|
||||
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
|
||||
|
||||
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
|
||||
# Clone Flutter SDK
|
||||
RUN git clone -b flutter-3.32-candidate.0 https://github.com/flutter/flutter.git /usr/local/flutter
|
||||
# RUN git clone -b stable https://github.com/flutter/flutter.git /usr/local/flutter
|
||||
|
||||
# Set flutter environment path
|
||||
ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}"
|
||||
#ENV PATH "$PATH:/home/developer/flutter/bin"
|
||||
|
||||
RUN flutter doctor -v
|
||||
|
||||
# Enable flutter web
|
||||
RUN flutter channel flutter-3.32-candidate.0
|
||||
# RUN flutter channel stable
|
||||
RUN flutter config --enable-web
|
||||
|
||||
# Copy files to container and build
|
||||
RUN mkdir /app/
|
||||
COPY . /app/
|
||||
|
||||
# Build the Flutter web 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 --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
|
||||
|
||||
RUN ["chmod", "+x", "/app/server/server.sh"]
|
||||
|
||||
ENTRYPOINT [ "/app/server/server.sh"]
|
||||
|
||||
# RUN ["python3", "-u", "/app/server/MIH_web_server.py"]
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
File diff suppressed because one or more lines are too long
@@ -5,5 +5,6 @@
|
||||
<item>@drawable/mzansi_wallet_sc</item>
|
||||
<item>@drawable/mzansi_ai_sc</item>
|
||||
<item>@drawable/mih_calculator_sc</item>
|
||||
<item>@drawable/mzansi_directory_sc</item>
|
||||
</array>
|
||||
</resources>
|
||||
@@ -2,6 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.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_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!');
|
||||
});
|
||||
final GoRouter appRouter = MihGoRouter().mihRouter;
|
||||
await dotenv.load(fileName: ".env");
|
||||
FlutterNativeSplash.remove();
|
||||
runApp(MzansiInnovationHub(
|
||||
router: appRouter,
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.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_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!');
|
||||
});
|
||||
final GoRouter appRouter = MihGoRouter().mihRouter;
|
||||
await dotenv.load(fileName: ".env");
|
||||
FlutterNativeSplash.remove();
|
||||
runApp(MzansiInnovationHub(
|
||||
router: appRouter,
|
||||
|
||||
@@ -26,7 +26,15 @@ abstract class AppEnviroment {
|
||||
baseApiUrl = "http://localhost:8080";
|
||||
baseFileUrl = "http://localhost:9000";
|
||||
baseAiUrl = "http://localhost:11434";
|
||||
bannerAdUnitId = 'ca-app-pub-3940256099942544/2435281174';
|
||||
bannerAdUnitId = 'ca-app-pub-3940256099942544/2435281174'; // IOS ID
|
||||
break;
|
||||
} else if (Platform.isIOS || Platform.isLinux) {
|
||||
//================= Web Dev Urls =================
|
||||
baseAppUrl = "http://localhost:80";
|
||||
baseApiUrl = "http://localhost:8080";
|
||||
baseFileUrl = "http://localhost:9000";
|
||||
baseAiUrl = "http://localhost:11434";
|
||||
bannerAdUnitId = 'ca-app-pub-3940256099942544/2435281174'; // IOS ID
|
||||
break;
|
||||
} else if (Platform.isAndroid) {
|
||||
//================= Android Dev Urls =================
|
||||
@@ -35,14 +43,6 @@ abstract class AppEnviroment {
|
||||
baseFileUrl = "http://10.0.2.2:9000";
|
||||
baseAiUrl = "http://10.0.2.2:11434";
|
||||
bannerAdUnitId = 'ca-app-pub-3940256099942544/9214589741';
|
||||
} else {
|
||||
//================= Web & iOS Dev Urls =================
|
||||
baseAppUrl = "http://localhost:80";
|
||||
baseApiUrl = "http://localhost:8080";
|
||||
baseFileUrl = "http://localhost:9000";
|
||||
baseAiUrl = "http://localhost:11434";
|
||||
bannerAdUnitId = 'ca-app-pub-3940256099942544/2435281174';
|
||||
break;
|
||||
}
|
||||
}
|
||||
case Enviroment.prod:
|
||||
|
||||
@@ -9,7 +9,7 @@ class MihTheme {
|
||||
late String loadingAssetText;
|
||||
late TargetPlatform platform;
|
||||
bool kIsWeb = const bool.fromEnvironment('dart.library.js_util');
|
||||
String latestVersion = "1.2.5";
|
||||
String latestVersion = "1.2.6";
|
||||
MihTheme() {
|
||||
mode = "Dark";
|
||||
}
|
||||
@@ -98,6 +98,12 @@ class MihTheme {
|
||||
return "Android";
|
||||
} else if (platform == TargetPlatform.iOS) {
|
||||
return "iOS";
|
||||
} else if (platform == TargetPlatform.linux) {
|
||||
return "Linux";
|
||||
} else if (platform == TargetPlatform.macOS) {
|
||||
return "macOS";
|
||||
} else if (platform == TargetPlatform.windows) {
|
||||
return "Windows";
|
||||
}
|
||||
}
|
||||
return "Other";
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:country_code_picker/country_code_picker.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
@@ -161,6 +164,7 @@ class _PackageToolOneState extends State<PackageToolOne> {
|
||||
return Stack(
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
@@ -450,6 +454,7 @@ class _PackageToolOneState extends State<PackageToolOne> {
|
||||
),
|
||||
],
|
||||
),
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS))
|
||||
MihBannerAd(),
|
||||
const SizedBox(height: 10),
|
||||
Divider(
|
||||
@@ -773,6 +778,7 @@ class _PackageToolOneState extends State<PackageToolOne> {
|
||||
MihCircleAvatar(
|
||||
imageFile: imagePreview,
|
||||
width: 50,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: _fileNameController,
|
||||
userSelectedfile: file,
|
||||
|
||||
@@ -111,6 +111,7 @@ class _PackageToolThreeState extends State<PackageToolThree> {
|
||||
return Stack(
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
@@ -24,6 +24,7 @@ class _PackageToolTwoState extends State<PackageToolTwo> {
|
||||
|
||||
Widget getBody() {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
|
||||
@@ -25,6 +25,7 @@ class _PackageToolZeroState extends State<PackageToolZero> {
|
||||
|
||||
Widget getBody() {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
659
mih_ui/lib/mih_package_components/mih_business_info_card_v2.dart
Normal file
659
mih_ui/lib/mih_package_components/mih_business_info_card_v2.dart
Normal file
@@ -0,0 +1,659 @@
|
||||
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 = 50.0;
|
||||
return Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
runSpacing: 10,
|
||||
spacing: 10,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
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: [
|
||||
MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
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: [
|
||||
MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
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: [
|
||||
MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
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: [
|
||||
MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
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: [
|
||||
MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
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: [
|
||||
MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
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: [
|
||||
MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,7 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
|
||||
: MihCircleAvatar(
|
||||
imageFile: widget.imageFile,
|
||||
width: profilePictureWidth,
|
||||
expandable: false,
|
||||
editable: false,
|
||||
fileNameController: TextEditingController(),
|
||||
userSelectedfile: null,
|
||||
|
||||
@@ -2,13 +2,17 @@ import 'dart:io';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:ken_logger/ken_logger.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_icons.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_window.dart';
|
||||
|
||||
class MihCircleAvatar extends StatefulWidget {
|
||||
final ImageProvider<Object>? imageFile;
|
||||
final double width;
|
||||
final bool expandable;
|
||||
final bool editable;
|
||||
final TextEditingController? fileNameController;
|
||||
final onChange;
|
||||
@@ -19,6 +23,7 @@ class MihCircleAvatar extends StatefulWidget {
|
||||
super.key,
|
||||
required this.imageFile,
|
||||
required this.width,
|
||||
required this.expandable,
|
||||
required this.editable,
|
||||
required this.fileNameController,
|
||||
required this.userSelectedfile,
|
||||
@@ -35,23 +40,33 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
|
||||
late ImageProvider<Object>? imagePreview;
|
||||
|
||||
ImageProvider<Object>? getAvatar() {
|
||||
// Color dark = const Color(0XFF3A4454);
|
||||
if (widget.imageFile == null) {
|
||||
return null;
|
||||
// if (widget.backgroundColor == dark) {
|
||||
// print("here in light icon");
|
||||
// return const AssetImage(
|
||||
// 'lib/mih_package_components/assets/images/i-dont-know-light.png');
|
||||
// } else {
|
||||
// print("here in dark icon");
|
||||
// return const AssetImage(
|
||||
// 'lib/mih_package_components/assets/images/i-dont-know-dark.png');
|
||||
// }
|
||||
} else {
|
||||
return widget.imageFile;
|
||||
}
|
||||
}
|
||||
|
||||
void expandAvatar() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MihPackageWindow(
|
||||
fullscreen: true,
|
||||
windowTitle: "",
|
||||
scrollbarOn: false,
|
||||
onWindowTapClose: () {
|
||||
context.pop();
|
||||
},
|
||||
windowBody: SizedBox.expand(
|
||||
child: InteractiveViewer(
|
||||
child: Image(image: imagePreview!),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -62,8 +77,14 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
// color: Colors.white,
|
||||
return GestureDetector(
|
||||
onTap: widget.expandable
|
||||
? () {
|
||||
KenLogger.success("Avatar tapped");
|
||||
expandAvatar();
|
||||
}
|
||||
: null,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
width: widget.width,
|
||||
height: widget.width,
|
||||
@@ -106,7 +127,8 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all<Color>(
|
||||
MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
@@ -116,7 +138,9 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
|
||||
type: FileType.image,
|
||||
);
|
||||
// print("Here 1");
|
||||
if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
|
||||
if (MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.getPlatform() ==
|
||||
"Web") {
|
||||
// print("Here 2");
|
||||
if (result == null) return;
|
||||
@@ -168,6 +192,7 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,18 @@ class _MihDropdownFieldState extends State<MihDropdownField> {
|
||||
Expanded(
|
||||
child: Theme(
|
||||
data: Theme.of(context).copyWith(
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
thumbColor: WidgetStatePropertyAll(
|
||||
MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark")),
|
||||
thickness: const WidgetStatePropertyAll(6),
|
||||
radius: const Radius.circular(10),
|
||||
thumbVisibility: const WidgetStatePropertyAll(
|
||||
true), // Always show when scrolling
|
||||
),
|
||||
textSelectionTheme: TextSelectionThemeData(
|
||||
cursorColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
|
||||
@@ -19,9 +19,6 @@ class _MihloadingcircleState extends State<Mihloadingcircle>
|
||||
late AnimationController _controller;
|
||||
late Animation<double> _animation;
|
||||
|
||||
late double width;
|
||||
late double height;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -82,16 +79,15 @@ class _MihloadingcircleState extends State<Mihloadingcircle>
|
||||
},
|
||||
),
|
||||
),
|
||||
widget.message != null
|
||||
? Text(
|
||||
if (widget.message != null)
|
||||
Text(
|
||||
widget.message!,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:ken_logger/ken_logger.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_scack_bar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mih_home/components/mih_app_drawer.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_tools.dart';
|
||||
@@ -100,7 +102,7 @@ class _MihPackageState extends State<MihPackage>
|
||||
// _peakAnimation();
|
||||
// });
|
||||
// }
|
||||
if (!MzansiInnovationHub.of(context)!.theme.kIsWeb) {
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||
// Trigger the peak animation only AFTER the route transition is complete
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final ModalRoute? currentRoute = ModalRoute.of(context);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:app_settings/app_settings.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:local_auth/local_auth.dart';
|
||||
@@ -155,7 +157,8 @@ class _MihPackageTileState extends State<MihPackageTile> {
|
||||
Future<void> authenticateUser() async {
|
||||
if (widget.authenticateUser != null &&
|
||||
widget.authenticateUser! &&
|
||||
!kIsWeb) {
|
||||
!kIsWeb &&
|
||||
!Platform.isLinux) {
|
||||
if (await isUserAuthenticated()) {
|
||||
widget.onTap();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class MihPackageWindow extends StatefulWidget {
|
||||
final Color? foregroundColor;
|
||||
final bool? borderOn;
|
||||
final bool fullscreen;
|
||||
final bool? scrollbarOn;
|
||||
const MihPackageWindow({
|
||||
super.key,
|
||||
required this.fullscreen,
|
||||
@@ -23,6 +24,7 @@ class MihPackageWindow extends StatefulWidget {
|
||||
required this.onWindowTapClose,
|
||||
required this.windowBody,
|
||||
this.borderOn,
|
||||
this.scrollbarOn,
|
||||
this.backgroundColor,
|
||||
this.foregroundColor,
|
||||
});
|
||||
@@ -177,7 +179,13 @@ class _MihPackageWindowState extends State<MihPackageWindow> {
|
||||
getHeader(),
|
||||
const SizedBox(height: 5),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(child: widget.windowBody)),
|
||||
child: widget.scrollbarOn != null || !widget.scrollbarOn!
|
||||
? widget.windowBody
|
||||
: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: widget.windowBody,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
@@ -197,7 +205,10 @@ class _MihPackageWindowState extends State<MihPackageWindow> {
|
||||
maxHeight: windowHeight * 0.85,
|
||||
maxWidth: windowWidth * 0.85,
|
||||
),
|
||||
child: MihSingleChildScroll(child: widget.windowBody),
|
||||
child: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: widget.windowBody,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -49,6 +49,7 @@ class _MihPersonalProfilePreviewState extends State<MihPersonalProfilePreview> {
|
||||
: MihCircleAvatar(
|
||||
imageFile: widget.imageFile,
|
||||
width: profilePictureWidth,
|
||||
expandable: false,
|
||||
editable: false,
|
||||
fileNameController: TextEditingController(),
|
||||
userSelectedfile: null,
|
||||
|
||||
@@ -3,19 +3,17 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:mzansi_innovation_hub/main.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_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:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class MihProfileLinks extends StatefulWidget {
|
||||
final List<ProfileLink> links;
|
||||
final double? buttonSize;
|
||||
final bool? paddingOn;
|
||||
const MihProfileLinks({
|
||||
super.key,
|
||||
required this.links,
|
||||
this.buttonSize,
|
||||
this.paddingOn,
|
||||
});
|
||||
|
||||
@@ -26,72 +24,89 @@ class MihProfileLinks extends StatefulWidget {
|
||||
class _MihProfileLinksState extends State<MihProfileLinks> {
|
||||
Widget displayLinkButton(ProfileLink link) {
|
||||
IconData iconData;
|
||||
Color iconColor;
|
||||
Color btnColor;
|
||||
Color iconColor = Colors.white;
|
||||
switch (link.destination.toLowerCase()) {
|
||||
case "youtube":
|
||||
iconData = FontAwesomeIcons.youtube;
|
||||
iconColor = const Color(0xFFFF0000);
|
||||
btnColor = const Color(0xFFFF0000);
|
||||
break;
|
||||
case "tiktok":
|
||||
iconData = FontAwesomeIcons.tiktok;
|
||||
iconColor = const Color(0xFF000000);
|
||||
btnColor = const Color(0xFF000000);
|
||||
break;
|
||||
case "twitch":
|
||||
iconData = FontAwesomeIcons.twitch;
|
||||
iconColor = const Color(0xFF6441a5);
|
||||
btnColor = const Color(0xFF6441a5);
|
||||
break;
|
||||
case "threads":
|
||||
iconData = FontAwesomeIcons.threads;
|
||||
iconColor = const Color(0xFF000000);
|
||||
btnColor = const Color(0xFF000000);
|
||||
break;
|
||||
case "whatsapp":
|
||||
iconData = FontAwesomeIcons.whatsapp;
|
||||
iconColor = const Color(0xFF25D366);
|
||||
btnColor = const Color(0xFF25D366);
|
||||
break;
|
||||
case "instagram":
|
||||
iconData = FontAwesomeIcons.instagram;
|
||||
iconColor = const Color(0xFFF56040);
|
||||
btnColor = const Color(0xFFF56040);
|
||||
break;
|
||||
case "x":
|
||||
iconData = FontAwesomeIcons.xTwitter;
|
||||
iconColor = const Color(0xFF000000);
|
||||
btnColor = const Color(0xFF000000);
|
||||
break;
|
||||
case "linkedin":
|
||||
iconData = FontAwesomeIcons.linkedin;
|
||||
iconColor = const Color(0xFF0a66c2);
|
||||
btnColor = const Color(0xFF0a66c2);
|
||||
break;
|
||||
case "facebook":
|
||||
iconData = FontAwesomeIcons.facebook;
|
||||
iconColor = const Color(0xFF4267B2);
|
||||
btnColor = const Color(0xFF4267B2);
|
||||
break;
|
||||
case "reddit":
|
||||
iconData = FontAwesomeIcons.reddit;
|
||||
iconColor = const Color(0xFFFF4500);
|
||||
btnColor = const Color(0xFFFF4500);
|
||||
break;
|
||||
case "discord":
|
||||
iconData = FontAwesomeIcons.discord;
|
||||
iconColor = const Color(0xFF5865F2);
|
||||
btnColor = const Color(0xFF5865F2);
|
||||
break;
|
||||
case "git":
|
||||
iconData = FontAwesomeIcons.git;
|
||||
btnColor = const Color(0xFF73A952);
|
||||
break;
|
||||
default:
|
||||
iconData = FontAwesomeIcons.link;
|
||||
iconColor = MihColors.getPrimaryColor(
|
||||
btnColor = MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark");
|
||||
}
|
||||
|
||||
return MihPackageTile(
|
||||
onTap: () {
|
||||
return MihButton(
|
||||
width: 80,
|
||||
height: 80,
|
||||
onPressed: () {
|
||||
launchSocialUrl(Uri.parse(link.web_link));
|
||||
},
|
||||
appName: link.destination,
|
||||
appIcon: Icon(
|
||||
buttonColor: btnColor,
|
||||
child: FaIcon(
|
||||
iconData,
|
||||
color: iconColor,
|
||||
size: 40,
|
||||
),
|
||||
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 {
|
||||
@@ -110,23 +125,8 @@ class _MihProfileLinksState extends State<MihProfileLinks> {
|
||||
padding: widget.paddingOn == null || widget.paddingOn!
|
||||
? MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
? EdgeInsets.symmetric(horizontal: width * 0.2)
|
||||
: EdgeInsets.symmetric(horizontal: width * 0.075)
|
||||
: EdgeInsets.symmetric(horizontal: width * 0)
|
||||
: EdgeInsetsGeometry.all(0),
|
||||
child: Material(
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark")
|
||||
.withValues(alpha: 0.6),
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
elevation: 10,
|
||||
shadowColor: Colors.black,
|
||||
child: Container(
|
||||
width: 500,
|
||||
padding: EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: widget.links.isEmpty
|
||||
? SizedBox(
|
||||
height: 35,
|
||||
@@ -144,20 +144,14 @@ class _MihProfileLinksState extends State<MihProfileLinks> {
|
||||
)
|
||||
: Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
runSpacing: 15,
|
||||
spacing: 15,
|
||||
runSpacing: 10,
|
||||
spacing: 10,
|
||||
children: widget.links.map(
|
||||
(link) {
|
||||
return SizedBox(
|
||||
width: widget.buttonSize ?? 80,
|
||||
height: widget.buttonSize ?? 80,
|
||||
child: displayLinkButton(link),
|
||||
);
|
||||
return displayLinkButton(link);
|
||||
},
|
||||
).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class MihSingleChildScroll extends StatefulWidget {
|
||||
final Widget child;
|
||||
final bool? scrollbarOn;
|
||||
const MihSingleChildScroll({
|
||||
super.key,
|
||||
required this.child,
|
||||
this.scrollbarOn,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -18,7 +20,8 @@ class _MihSingleChildScrollState extends State<MihSingleChildScroll> {
|
||||
bottom: false,
|
||||
minimum: EdgeInsets.only(bottom: 5),
|
||||
child: ScrollConfiguration(
|
||||
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
|
||||
behavior: ScrollConfiguration.of(context)
|
||||
.copyWith(scrollbars: widget.scrollbarOn ?? false),
|
||||
child: SingleChildScrollView(
|
||||
child: widget.child,
|
||||
),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/main.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_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_icons.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
||||
@@ -21,72 +20,30 @@ class _MihAttributesState extends State<MihAttributes> {
|
||||
}
|
||||
}
|
||||
|
||||
TableRow displayIcon(IconData icon, String creator, String link) {
|
||||
return TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: SizedBox(
|
||||
height: 150,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 15.0),
|
||||
child: FittedBox(
|
||||
child: Center(
|
||||
child: Icon(
|
||||
icon,
|
||||
// size: 125,
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
child: Center(
|
||||
child: Text(
|
||||
creator,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 15.0),
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
Widget displayAttribution(IconData resource, String creator, String link) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
launchUrlLink(
|
||||
Uri.parse(
|
||||
link,
|
||||
),
|
||||
);
|
||||
},
|
||||
buttonColor: MihColors.getGreenColor(
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
resource,
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
width: 100,
|
||||
child: Text(
|
||||
"Visit",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
size: 100,
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
creator,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -94,7 +51,6 @@ class _MihAttributesState extends State<MihAttributes> {
|
||||
Widget build(BuildContext context) {
|
||||
return MihPackageToolBody(
|
||||
borderOn: false,
|
||||
innerHorizontalPadding: 10,
|
||||
bodyItem: getBody(),
|
||||
);
|
||||
}
|
||||
@@ -108,6 +64,9 @@ class _MihAttributesState extends State<MihAttributes> {
|
||||
"As per the terms for free use for these third party providers, the following assets require attribution";
|
||||
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -130,158 +89,53 @@ class _MihAttributesState extends State<MihAttributes> {
|
||||
height: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: 700,
|
||||
child: Table(
|
||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
columnWidths: const {
|
||||
0: FlexColumnWidth(1),
|
||||
1: FlexColumnWidth(1),
|
||||
2: FlexColumnWidth(1),
|
||||
},
|
||||
width: 900,
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
runSpacing: 10,
|
||||
spacing: 10,
|
||||
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",
|
||||
displayAttribution(MihIcons.mihRing, "Tarah Meth",
|
||||
"https://www.linkedin.com/in/tarah-meth-3b6309254/"),
|
||||
displayIcon(MihIcons.mihLogo, "Tarah Meth",
|
||||
displayAttribution(MihIcons.mihLogo, "Tarah Meth",
|
||||
"https://www.linkedin.com/in/tarah-meth-3b6309254/"),
|
||||
displayIcon(MihIcons.mzansiAi, "Ollama", "https://ollama.com/"),
|
||||
displayIcon(MihIcons.mzansiWallet, "Freepik",
|
||||
displayAttribution(
|
||||
MihIcons.mzansiAi, "Ollama", "https://ollama.com/"),
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(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",
|
||||
displayAttribution(MihIcons.calculator, "fawazahmed0",
|
||||
"https://github.com/fawazahmed0/exchange-api"),
|
||||
displayIcon(MihIcons.iDontKnow, "Freepik",
|
||||
displayAttribution(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),
|
||||
// ],
|
||||
// ),
|
||||
// )
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
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/mih_objects/profile_link.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_services/mih_business_details_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart';
|
||||
@@ -432,7 +434,119 @@ class _MihInfoState extends State<MihInfo> {
|
||||
children: [
|
||||
MihButton(
|
||||
onPressed: () {
|
||||
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(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
@@ -736,6 +850,14 @@ class _MihInfoState extends State<MihInfo> {
|
||||
destination: "Reddit",
|
||||
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(
|
||||
children: [
|
||||
@@ -752,7 +874,7 @@ class _MihInfoState extends State<MihInfo> {
|
||||
),
|
||||
MihProfileLinks(links: links),
|
||||
const SizedBox(
|
||||
height: 25,
|
||||
height: 75,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -777,6 +899,7 @@ class _MihInfoState extends State<MihInfo> {
|
||||
return Stack(
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
aboutHeadings(),
|
||||
|
||||
@@ -19,7 +19,6 @@ class _MihPrivacyPolicyState extends State<MihPrivacyPolicy> {
|
||||
Widget build(BuildContext context) {
|
||||
return MihPackageToolBody(
|
||||
borderOn: false,
|
||||
innerHorizontalPadding: 10,
|
||||
bodyItem: getBody(context),
|
||||
);
|
||||
}
|
||||
@@ -55,10 +54,14 @@ class _MihPrivacyPolicyState extends State<MihPrivacyPolicy> {
|
||||
children
|
||||
.addAll(PolicyAndTermsText().getPrivacyPolicyText(context, englishOn));
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ class _MIHTermsOfServiceState extends State<MIHTermsOfService> {
|
||||
Widget build(BuildContext context) {
|
||||
return MihPackageToolBody(
|
||||
borderOn: false,
|
||||
innerHorizontalPadding: 10,
|
||||
bodyItem: getBody(context),
|
||||
);
|
||||
}
|
||||
@@ -55,9 +54,13 @@ class _MIHTermsOfServiceState extends State<MIHTermsOfService> {
|
||||
children
|
||||
.addAll(PolicyAndTermsText().getTermsOfServiceText(context, englishOn));
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Column(
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
@@ -157,7 +160,11 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Consumer(builder: (context, bannerAdDisplay, child) {
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||
return MihBannerAd();
|
||||
} else {
|
||||
return const SizedBox(height: 0);
|
||||
}
|
||||
}),
|
||||
],
|
||||
),
|
||||
@@ -290,6 +297,7 @@ class _CurrencyExchangeRateState extends State<CurrencyExchangeRate> {
|
||||
return Consumer<MihCalculatorProvider>(
|
||||
builder: (context, calculatorProvider, child) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
|
||||
@@ -94,6 +94,7 @@ class _SimpleCalcState extends State<SimpleCalc> {
|
||||
}
|
||||
}
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_banner_ad.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
||||
@@ -229,7 +232,11 @@ class _TipCalcState extends State<TipCalc> {
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Consumer(builder: (context, bannerAdDisplay, child) {
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||
return MihBannerAd();
|
||||
} else {
|
||||
return const SizedBox(height: 0);
|
||||
}
|
||||
}),
|
||||
// if (splitBillController.text == "Yes") const Divider(),
|
||||
],
|
||||
@@ -259,6 +266,7 @@ class _TipCalcState extends State<TipCalc> {
|
||||
|
||||
Widget getBody(double width) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
? EdgeInsets.symmetric(horizontal: width * 0.2)
|
||||
|
||||
@@ -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_form.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_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
||||
@@ -139,9 +140,8 @@ class _MihForgotPasswordState extends State<MihForgotPassword> {
|
||||
validateInput();
|
||||
}
|
||||
},
|
||||
child: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
child: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
|
||||
"desktop"
|
||||
@@ -177,11 +177,9 @@ class _MihForgotPasswordState extends State<MihForgotPassword> {
|
||||
formFields: [
|
||||
MihTextFormField(
|
||||
fillColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
inputColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
controller: emailController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
@@ -224,7 +222,6 @@ class _MihForgotPasswordState extends State<MihForgotPassword> {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.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/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_form.dart';
|
||||
@@ -107,7 +108,7 @@ class _MihRegisterState extends State<MihRegister> {
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
"Authorization": "leatucczyixqwkqqdrhayiwzeofkltds"
|
||||
"Authorization": dotenv.env['SUPERTOKENS_API_KEY'] ?? "",
|
||||
},
|
||||
);
|
||||
//print("response 2: ${response2.statusCode}");
|
||||
@@ -204,6 +205,7 @@ class _MihRegisterState extends State<MihRegister> {
|
||||
}
|
||||
},
|
||||
child: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
|
||||
@@ -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_form.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_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
||||
@@ -104,9 +105,8 @@ class _MihResetPasswordState extends State<MihResetPassword> {
|
||||
}
|
||||
}
|
||||
},
|
||||
child: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
child: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
@@ -142,11 +142,9 @@ class _MihResetPasswordState extends State<MihResetPassword> {
|
||||
formFields: [
|
||||
MihTextFormField(
|
||||
fillColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
inputColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
controller: passwordController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
@@ -161,11 +159,9 @@ class _MihResetPasswordState extends State<MihResetPassword> {
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
fillColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
inputColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
controller: confirmPasswordController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
@@ -210,7 +206,6 @@ class _MihResetPasswordState extends State<MihResetPassword> {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ class _MihSignInState extends State<MihSignIn> {
|
||||
}
|
||||
},
|
||||
child: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
|
||||
@@ -78,6 +78,7 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
|
||||
? mzansiProfileProvider.userProfilePicture
|
||||
: mzansiProfileProvider.businessProfilePicture,
|
||||
width: 60,
|
||||
expandable: false,
|
||||
editable: false,
|
||||
fileNameController: proPicController,
|
||||
onChange: (_) {},
|
||||
|
||||
@@ -353,6 +353,7 @@ class _MihHomeState extends State<MihHome> {
|
||||
key: Key(imageKey),
|
||||
imageFile: currentImage,
|
||||
width: 50,
|
||||
expandable: false,
|
||||
editable: false,
|
||||
fileNameController: null,
|
||||
userSelectedfile: null,
|
||||
|
||||
@@ -104,6 +104,7 @@ class _BuildMinesweeperLeaderboardListState
|
||||
key: UniqueKey(),
|
||||
imageFile: imageFile,
|
||||
width: 80,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: null,
|
||||
userSelectedfile: null,
|
||||
|
||||
@@ -50,6 +50,7 @@ class LeaderboardUserRanking extends StatelessWidget {
|
||||
.toString()), // Use ValueKey for stable identity
|
||||
imageFile: asyncSnapshot.data,
|
||||
width: 60,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: null,
|
||||
userSelectedfile: null,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
@@ -626,6 +628,7 @@ class _MineSweeperGameState extends State<MineSweeperGame> {
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: board.isEmpty && squaresLeft < 0
|
||||
// Start Up Message before setting up game
|
||||
? Padding(
|
||||
@@ -850,7 +853,9 @@ class _MineSweeperGameState extends State<MineSweeperGame> {
|
||||
],
|
||||
),
|
||||
),
|
||||
_timer != null ? MihBannerAd() : SizedBox(),
|
||||
_timer != null && !kIsWeb && (Platform.isAndroid || Platform.isIOS)
|
||||
? MihBannerAd()
|
||||
: SizedBox(),
|
||||
SizedBox(height: 15),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -845,6 +845,7 @@ class _MineSweeperQuickStartGuideState
|
||||
|
||||
Widget getBody(double width) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: width / 20),
|
||||
child: Column(
|
||||
|
||||
@@ -87,6 +87,7 @@ class _MihMineSweeperLeaderBoardState extends State<MyScoreBoard> {
|
||||
child: MihCircleAvatar(
|
||||
imageFile: profileProvider.userProfilePicture,
|
||||
width: 150,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: null,
|
||||
userSelectedfile: null,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -112,16 +113,36 @@ class _MihAiChatState extends State<MihAiChat> with WidgetsBindingObserver {
|
||||
|
||||
void speakLastMessage(MzansiAiProvider aiProvider) {
|
||||
final history = aiProvider.ollamaProvider.history;
|
||||
if (history.isNotEmpty) {
|
||||
if (history.isEmpty) return;
|
||||
|
||||
final historyList = history.toList();
|
||||
String? textToSpeak;
|
||||
|
||||
// Find the last LLM message
|
||||
for (int i = historyList.length - 1; i >= 0; i--) {
|
||||
if (historyList[i].origin == MessageOrigin.llm &&
|
||||
historyList[i].text != null &&
|
||||
historyList[i].text!.isNotEmpty) {
|
||||
_flutterTts.speak(historyList[i].text!);
|
||||
return;
|
||||
textToSpeak = historyList[i].text!;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (textToSpeak != null) {
|
||||
if (!kIsWeb && Platform.isLinux) {
|
||||
// Linux Workaround: Use Speech Dispatcher (standard on most distros)
|
||||
// '-t female1' is optional for voice variety
|
||||
Process.run('spd-say', [textToSpeak]);
|
||||
|
||||
// Since spd-say doesn't have an easy "completion handler" via CLI,
|
||||
// we manually toggle the UI state or just leave it off.
|
||||
aiProvider.setTTSstate(true);
|
||||
Future.delayed(
|
||||
Duration(seconds: 5), () => aiProvider.setTTSstate(false));
|
||||
} else {
|
||||
// Your existing mobile/web logic
|
||||
_flutterTts.speak(textToSpeak);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,11 +204,16 @@ class _MihAiChatState extends State<MihAiChat> with WidgetsBindingObserver {
|
||||
// }
|
||||
|
||||
void stopTTS(MzansiAiProvider aiProvider) {
|
||||
if (!kIsWeb && Platform.isLinux) {
|
||||
Process.run('spd-say', ['-S']); // The -S flag stops current speech
|
||||
} else {
|
||||
_flutterTts.stop();
|
||||
}
|
||||
aiProvider.setTTSstate(false);
|
||||
}
|
||||
|
||||
Future<void> initTts(MzansiAiProvider aiProvider) async {
|
||||
if (!kIsWeb && Platform.isLinux) return;
|
||||
try {
|
||||
await _flutterTts.setSpeechRate(!kIsWeb ? 0.55 : 1);
|
||||
// await _flutterTts.setLanguage("en-US");
|
||||
@@ -258,7 +284,9 @@ class _MihAiChatState extends State<MihAiChat> with WidgetsBindingObserver {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (!kIsWeb && !Platform.isLinux) {
|
||||
_flutterTts.stop();
|
||||
}
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ class _MihContactsState extends State<MihContacts> {
|
||||
|
||||
Widget getBody(double width) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
|
||||
@@ -330,6 +330,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
||||
} else if (directoryProvider.searchedBusinesses.isEmpty &&
|
||||
directoryProvider.searchTerm.isNotEmpty) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 50),
|
||||
@@ -357,6 +358,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
||||
} else if (directoryProvider.searchedBusinesses.isEmpty &&
|
||||
directoryProvider.searchTerm.isEmpty) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Column(
|
||||
@@ -472,6 +474,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
||||
} else if (directoryProvider.searchedUsers.isEmpty &&
|
||||
directoryProvider.searchTerm.isEmpty) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Column(
|
||||
@@ -533,6 +536,7 @@ class _MihSearchMzansiState extends State<MihSearchMzansi> {
|
||||
} else if (directoryProvider.searchedUsers.isEmpty &&
|
||||
directoryProvider.searchTerm.isNotEmpty) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 50),
|
||||
|
||||
@@ -316,6 +316,7 @@ class _MihReviewBusinessWindowState extends State<MihReviewBusinessWindow> {
|
||||
]
|
||||
: null,
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
|
||||
"desktop"
|
||||
|
||||
@@ -251,12 +251,15 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
context.pop();
|
||||
},
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
? EdgeInsets.symmetric(horizontal: widget.width * 0.05)
|
||||
: EdgeInsets.symmetric(horizontal: widget.width * 0),
|
||||
child: Column(
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
MihForm(
|
||||
formKey: _formKey,
|
||||
@@ -265,8 +268,10 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
child: MihCircleAvatar(
|
||||
imageFile: newSelectedLogoPic != null
|
||||
? MemoryImage(newSelectedLogoPic!.bytes!)
|
||||
: mzansiProfileProvider.businessProfilePicture,
|
||||
: mzansiProfileProvider
|
||||
.businessProfilePicture,
|
||||
width: 150,
|
||||
expandable: false,
|
||||
editable: true,
|
||||
fileNameController: fileNameController,
|
||||
userSelectedfile: newSelectedLogoPic,
|
||||
@@ -345,7 +350,8 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
requiredText: true,
|
||||
hintText: "Business Email",
|
||||
validator: (value) {
|
||||
return MihValidationServices().validateEmail(value);
|
||||
return MihValidationServices()
|
||||
.validateEmail(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
@@ -376,20 +382,29 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
initialSelection: countryCodeController.text,
|
||||
showDropDownButton: false,
|
||||
pickerStyle: PickerStyle.bottomSheet,
|
||||
dialogBackgroundColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
dialogBackgroundColor:
|
||||
MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
barrierColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
),
|
||||
Expanded(
|
||||
child: MihTextFormField(
|
||||
fillColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
inputColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
controller: contactController,
|
||||
numberMode: true,
|
||||
@@ -397,7 +412,8 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
requiredText: true,
|
||||
hintText: null,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
return MihValidationServices()
|
||||
.isEmpty(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -425,8 +441,8 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
height: 15,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: _counter,
|
||||
builder:
|
||||
(BuildContext context, int value, Widget? child) {
|
||||
builder: (BuildContext context, int value,
|
||||
Widget? child) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
@@ -525,10 +541,14 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
Flexible(
|
||||
child: MihTextFormField(
|
||||
fillColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
inputColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
controller: locationController,
|
||||
multiLineInput: false,
|
||||
@@ -562,7 +582,9 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
});
|
||||
},
|
||||
buttonColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
width: 100,
|
||||
child: Text(
|
||||
@@ -598,7 +620,9 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
"Update",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -611,6 +635,39 @@ class _MihUpdateBusinessDetailsWindowState
|
||||
),
|
||||
],
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -5,7 +5,6 @@ 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_env.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_circle_avatar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_image_display.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_window.dart';
|
||||
@@ -127,32 +126,35 @@ class _MihUpdateMyBusinessUserDetailsState
|
||||
builder: (BuildContext context,
|
||||
MzansiProfileProvider mzansiProfileProvider, Widget? child) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
? EdgeInsets.symmetric(horizontal: width * 0.2)
|
||||
: EdgeInsets.symmetric(horizontal: width * 0.075),
|
||||
child: Column(
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
MihForm(
|
||||
formKey: _formKey,
|
||||
formFields: [
|
||||
Center(
|
||||
child: MihCircleAvatar(
|
||||
imageFile: mzansiProfileProvider.userProfilePicture,
|
||||
width: 150,
|
||||
editable: false,
|
||||
fileNameController: fileNameController,
|
||||
userSelectedfile: userPicFile,
|
||||
frameColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
backgroundColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
onChange: (_) {},
|
||||
),
|
||||
),
|
||||
// Center(
|
||||
// child: MihCircleAvatar(
|
||||
// imageFile: mzansiProfileProvider.userProfilePicture,
|
||||
// width: 150,
|
||||
// editable: false,
|
||||
// fileNameController: fileNameController,
|
||||
// userSelectedfile: userPicFile,
|
||||
// frameColor: MihColors.getSecondaryColor(
|
||||
// MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
// "Dark"),
|
||||
// backgroundColor: MihColors.getPrimaryColor(
|
||||
// MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
// "Dark"),
|
||||
// onChange: (_) {},
|
||||
// ),
|
||||
// ),
|
||||
Visibility(
|
||||
visible: false,
|
||||
child: MihTextFormField(
|
||||
@@ -301,7 +303,9 @@ class _MihUpdateMyBusinessUserDetailsState
|
||||
"Update",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -314,6 +318,35 @@ class _MihUpdateMyBusinessUserDetailsState
|
||||
),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
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(
|
||||
"Update",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import 'package:custom_rating_bar/custom_rating_bar.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_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_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_package_components/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
|
||||
@@ -60,18 +61,23 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
|
||||
return Stack(
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
|
||||
"desktop"
|
||||
? EdgeInsets.symmetric(horizontal: width * 0.2)
|
||||
: EdgeInsets.symmetric(horizontal: width * 0.075),
|
||||
: EdgeInsets.symmetric(horizontal: width * 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Center(
|
||||
child: MihCircleAvatar(
|
||||
child: Stack(
|
||||
children: [
|
||||
MihCircleAvatar(
|
||||
key: UniqueKey(),
|
||||
imageFile: mzansiProfileProvider.businessProfilePicture,
|
||||
imageFile:
|
||||
mzansiProfileProvider.businessProfilePicture,
|
||||
width: 150,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: fileNameController,
|
||||
userSelectedfile: newSelectedLogoPic,
|
||||
@@ -87,6 +93,32 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
|
||||
});
|
||||
},
|
||||
),
|
||||
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(
|
||||
child: Text(
|
||||
@@ -112,6 +144,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),
|
||||
Center(
|
||||
child: SizedBox(
|
||||
@@ -133,68 +189,16 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SizedBox(
|
||||
width: 700,
|
||||
child: MihBusinessCard(
|
||||
MihBusinessCardV2(
|
||||
business: mzansiProfileProvider.business!,
|
||||
// startUpSearch: null,
|
||||
width: width,
|
||||
),
|
||||
),
|
||||
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);
|
||||
// },
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
||||
@@ -330,6 +330,7 @@ class _MihBusinessDetailsSetUpState extends State<MihBusinessDetailsSetUp> {
|
||||
? MemoryImage(newSelectedLogoPic!.bytes!)
|
||||
: mzansiProfileProvider.businessProfilePicture,
|
||||
width: 150,
|
||||
expandable: false,
|
||||
editable: true,
|
||||
fileNameController: logoFileNameController,
|
||||
userSelectedfile: newSelectedLogoPic,
|
||||
@@ -765,7 +766,7 @@ class _MihBusinessDetailsSetUpState extends State<MihBusinessDetailsSetUp> {
|
||||
"Dark"),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Add",
|
||||
"Set Up Buasiness",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
|
||||
@@ -3,10 +3,10 @@ import 'package:custom_rating_bar/custom_rating_bar.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_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_providers/mzansi_directory_provider.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_package_components/mih_single_child_scroll.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(
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
|
||||
"desktop"
|
||||
? EdgeInsets.symmetric(horizontal: width * 0.2)
|
||||
: EdgeInsets.symmetric(horizontal: width * 0.075),
|
||||
: EdgeInsets.symmetric(horizontal: width * 0),
|
||||
child: Column(
|
||||
children: [
|
||||
FutureBuilder(
|
||||
@@ -76,6 +77,7 @@ class _MihBusinessDetailsViewState extends State<MihBusinessDetailsView> {
|
||||
imageFile: CachedNetworkImageProvider(
|
||||
asyncSnapshot.requireData),
|
||||
width: profilePictureWidth,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: TextEditingController(),
|
||||
userSelectedfile: file,
|
||||
@@ -154,40 +156,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(
|
||||
size: 50,
|
||||
alignment: Alignment.center,
|
||||
@@ -213,14 +181,32 @@ class _MihBusinessDetailsViewState extends State<MihBusinessDetailsView> {
|
||||
: 0,
|
||||
maxRating: 5,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SizedBox(
|
||||
const SizedBox(height: 5),
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: 700,
|
||||
child: MihBusinessCard(
|
||||
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: 20),
|
||||
MihBusinessCardV2(
|
||||
business: directoryProvider.selectedBusiness!,
|
||||
width: width,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:file_saver/file_saver.dart';
|
||||
@@ -82,6 +84,19 @@ class _MihBusinessQrCodeState extends State<MihBusinessQrCode> {
|
||||
fileExtension: "png",
|
||||
mimeType: MimeType.png,
|
||||
);
|
||||
} else if (defaultTargetPlatform == TargetPlatform.linux ||
|
||||
defaultTargetPlatform == TargetPlatform.windows) {
|
||||
// Use File Picker to get a save path on Desktop
|
||||
String? outputFile = await FilePicker.platform.saveFile(
|
||||
dialogTitle: 'Please select where to save your QR Code:',
|
||||
fileName: filename,
|
||||
);
|
||||
|
||||
if (outputFile != null) {
|
||||
final file = File(outputFile);
|
||||
await file.writeAsBytes(imageBytes);
|
||||
KenLogger.success("Saved to $outputFile");
|
||||
}
|
||||
} else {
|
||||
await FileSaver.instance.saveAs(
|
||||
name: filename,
|
||||
@@ -95,14 +110,14 @@ class _MihBusinessQrCodeState extends State<MihBusinessQrCode> {
|
||||
Future<void> downloadQrCode() async {
|
||||
if (_isUserSignedIn) {
|
||||
await screenshotController.capture().then((image) {
|
||||
KenLogger.success("Image Captured: $image");
|
||||
// KenLogger.success("Image Captured: $image");
|
||||
setState(() {
|
||||
businessQRImageFile = image;
|
||||
});
|
||||
}).catchError((onError) {
|
||||
KenLogger.error(onError);
|
||||
});
|
||||
KenLogger.success("QR Code Image Captured : $businessQRImageFile");
|
||||
// KenLogger.success("QR Code Image Captured : $businessQRImageFile");
|
||||
saveImage(businessQRImageFile!);
|
||||
} else {
|
||||
showSignInRequiredAlert();
|
||||
@@ -211,6 +226,7 @@ class _MihBusinessQrCodeState extends State<MihBusinessQrCode> {
|
||||
imageFile: CachedNetworkImageProvider(
|
||||
asyncSnapshot.requireData),
|
||||
width: profilePictureWidth,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: TextEditingController(),
|
||||
userSelectedfile: file,
|
||||
@@ -298,7 +314,9 @@ class _MihBusinessQrCodeState extends State<MihBusinessQrCode> {
|
||||
height: 300,
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: getQrCodeData(qrSize.toInt()),
|
||||
placeholder: (context, url) => const Mihloadingcircle(),
|
||||
placeholder: (context, url) => FittedBox(
|
||||
child: const Mihloadingcircle(),
|
||||
),
|
||||
errorWidget: (context, url, error) =>
|
||||
const Icon(Icons.error),
|
||||
),
|
||||
@@ -367,6 +385,7 @@ class _MihBusinessQrCodeState extends State<MihBusinessQrCode> {
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15.0),
|
||||
child: Padding(
|
||||
|
||||
@@ -175,6 +175,7 @@ class _MihMyBusinessUserState extends State<MihMyBusinessUser> {
|
||||
return Stack(
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
|
||||
"desktop"
|
||||
@@ -183,9 +184,12 @@ class _MihMyBusinessUserState extends State<MihMyBusinessUser> {
|
||||
child: Column(
|
||||
children: [
|
||||
Center(
|
||||
child: MihCircleAvatar(
|
||||
child: Stack(
|
||||
children: [
|
||||
MihCircleAvatar(
|
||||
imageFile: mzansiProfileProvider.userProfilePicture,
|
||||
width: 150,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: fileNameController,
|
||||
userSelectedfile: userPicFile,
|
||||
@@ -197,6 +201,31 @@ class _MihMyBusinessUserState extends State<MihMyBusinessUser> {
|
||||
"Dark"),
|
||||
onChange: (_) {},
|
||||
),
|
||||
Positioned(
|
||||
bottom: 5,
|
||||
right: 5,
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
editBizUserProfileWindow(
|
||||
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"),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
buildEmployeeInfoCard(mzansiProfileProvider),
|
||||
@@ -245,28 +274,6 @@ class _MihMyBusinessUserState extends State<MihMyBusinessUser> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
editBizUserProfileWindow(
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -329,7 +329,9 @@ class _MihEditPersonalProfileWindowState
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
? EdgeInsets.symmetric(horizontal: screenWidth * 0.05)
|
||||
: EdgeInsets.symmetric(horizontal: screenWidth * 0),
|
||||
child: Column(
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
MihForm(
|
||||
@@ -341,6 +343,7 @@ class _MihEditPersonalProfileWindowState
|
||||
? MemoryImage(newSelectedProPic!.bytes!)
|
||||
: mzansiProfileProvider.userProfilePicture,
|
||||
width: 150,
|
||||
expandable: false,
|
||||
editable: true,
|
||||
fileNameController: proPicController,
|
||||
userSelectedfile: newSelectedProPic,
|
||||
@@ -387,7 +390,8 @@ class _MihEditPersonalProfileWindowState
|
||||
requiredText: true,
|
||||
hintText: "Username",
|
||||
validator: (value) {
|
||||
return MihValidationServices().validateUsername(value);
|
||||
return MihValidationServices()
|
||||
.validateUsername(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
@@ -444,8 +448,8 @@ class _MihEditPersonalProfileWindowState
|
||||
height: 15,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: _counter,
|
||||
builder:
|
||||
(BuildContext context, int value, Widget? child) {
|
||||
builder: (BuildContext context, int value,
|
||||
Widget? child) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
@@ -508,7 +512,9 @@ class _MihEditPersonalProfileWindowState
|
||||
: "Update",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
MzansiInnovationHub.of(context)!
|
||||
.theme
|
||||
.mode ==
|
||||
"Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -520,6 +526,38 @@ class _MihEditPersonalProfileWindowState
|
||||
),
|
||||
],
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -146,6 +146,7 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
|
||||
);
|
||||
} else {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
@@ -159,6 +160,7 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
|
||||
MihCircleAvatar(
|
||||
imageFile: mzansiProfileProvider.userProfilePicture,
|
||||
width: 150,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: proPicController,
|
||||
userSelectedfile: newSelectedProPic,
|
||||
|
||||
@@ -54,6 +54,7 @@ class _MihPersonalProfileViewState extends State<MihPersonalProfileView> {
|
||||
builder: (BuildContext context, MzansiDirectoryProvider directoryProvider,
|
||||
Widget? child) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
@@ -73,6 +74,7 @@ class _MihPersonalProfileViewState extends State<MihPersonalProfileView> {
|
||||
imageFile: CachedNetworkImageProvider(
|
||||
asyncSnapshot.requireData),
|
||||
width: profilePictureWidth,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: TextEditingController(),
|
||||
userSelectedfile: file,
|
||||
|
||||
@@ -81,6 +81,7 @@ class _MihPersonalSettingsState extends State<MihPersonalSettings> {
|
||||
|
||||
Widget getBody(MzansiProfileProvider mzansiProfileProvider) {
|
||||
return MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Center(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@@ -545,7 +547,7 @@ class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
MihBannerAd()
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) MihBannerAd()
|
||||
// MihBannerAd(),
|
||||
],
|
||||
),
|
||||
@@ -572,7 +574,7 @@ class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
|
||||
}
|
||||
|
||||
Future<void> setScreenBrightness(double newBrightness) async {
|
||||
if (!kIsWeb) {
|
||||
if (!kIsWeb && !Platform.isLinux) {
|
||||
bool canChange =
|
||||
await ScreenBrightness.instance.canChangeSystemBrightness;
|
||||
|
||||
|
||||
@@ -306,6 +306,7 @@ class _PatientInfoState extends State<PatientInfo> {
|
||||
return Stack(
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
@@ -313,6 +314,7 @@ class _PatientInfoState extends State<PatientInfo> {
|
||||
imageFile:
|
||||
patientManagerProvider.selectedPatientProfilePicture,
|
||||
width: 160,
|
||||
expandable: true,
|
||||
editable: false,
|
||||
fileNameController: null,
|
||||
userSelectedfile: null,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:google_mobile_ads/google_mobile_ads.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
|
||||
@@ -28,6 +30,7 @@ class MihBannerAdProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void loadBannerAd() {
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||
if (bannerAd != null) {
|
||||
bannerAd!.dispose();
|
||||
bannerAd = null;
|
||||
@@ -60,3 +63,4 @@ class MihBannerAdProvider extends ChangeNotifier {
|
||||
bannerAd!.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class MzansiAiProvider extends ChangeNotifier {
|
||||
ollamaProvider = OllamaProvider(
|
||||
baseUrl: "${AppEnviroment.baseAiUrl}/api",
|
||||
model: AppEnviroment.getEnv() == "Prod"
|
||||
? 'qwen3-vl:8b'
|
||||
? 'qwen3-vl:8b-instruct'
|
||||
: "qwen3-vl:2b-instruct",
|
||||
think: false,
|
||||
systemPrompt: "---INSTRUCTION START---\n"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
@@ -32,6 +35,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -109,6 +113,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -132,7 +137,9 @@ class MihAlertServices {
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Text(
|
||||
"To get the most out of MIH, we need your location. Please go to the site settings of the app and enable location services. Once you do that, we can start showing you relevant information based on your location.",
|
||||
!kIsWeb && Platform.isLinux
|
||||
? "To get the most out of MIH, we need your location. Please go to your System Settings and enable location services. Once you do that, we can start showing you relevant information based on your location."
|
||||
: "To get the most out of MIH, we need your location. Please go to the site settings of the app and enable location services. Once you do that, we can start showing you relevant information based on your location.",
|
||||
style: TextStyle(
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
@@ -186,6 +193,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -298,6 +306,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -416,6 +425,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -493,6 +503,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -594,6 +605,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -671,6 +683,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -748,6 +761,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -830,6 +844,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -900,6 +915,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -1007,6 +1023,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -1089,6 +1106,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -1159,6 +1177,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -1244,6 +1263,7 @@ class MihAlertServices {
|
||||
backgroundColor: MihColors.getRedColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode != "Dark"),
|
||||
windowBody: MihSingleChildScroll(
|
||||
scrollbarOn: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_button.dart';
|
||||
@@ -32,7 +33,7 @@ class MihAuthenticationServices {
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
"Authorization": "leatucczyixqwkqqdrhayiwzeofkltds"
|
||||
"Authorization": dotenv.env['SUPERTOKENS_API_KEY'] ?? "",
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:ken_logger/ken_logger.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_package_components/mih_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_env.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -51,6 +54,15 @@ class MihFileApi {
|
||||
} finally {
|
||||
// Navigator.of(context).pop(); // Always pop loading dialog
|
||||
}
|
||||
KenLogger.success("File URL: $fileUrl");
|
||||
if (AppEnviroment.getEnv() == "Dev" && kIsWeb) {
|
||||
fileUrl = fileUrl.replaceAll("10.0.2.2", "127.0.0.1");
|
||||
} else if (AppEnviroment.getEnv() == "Dev" && Platform.isIOS) {
|
||||
fileUrl = fileUrl.replaceAll("10.0.2.2", "127.0.0.1");
|
||||
} else if (AppEnviroment.getEnv() == "Dev" && Platform.isLinux) {
|
||||
fileUrl = fileUrl.replaceAll("10.0.2.2", "127.0.0.1");
|
||||
}
|
||||
KenLogger.success("File URL: $fileUrl");
|
||||
return fileUrl;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
|
||||
@@ -13,6 +16,12 @@ class MIHLocationAPI {
|
||||
///if user has blocked permission (denied or denied forver), user will get error pop up.
|
||||
///if user has granted permission (while in use), function will return Position object.
|
||||
Future<Position?> getGPSPosition(BuildContext context) async {
|
||||
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
if (!serviceEnabled && !kIsWeb && Platform.isLinux) {
|
||||
// Direct the user to their System Settings
|
||||
MihAlertServices().locationPermissionAlert(context);
|
||||
return null;
|
||||
}
|
||||
print("Before checkPermission"); // Debug
|
||||
LocationPermission permission = await Geolocator.checkPermission();
|
||||
print("After checkPermission: $permission"); // Debug
|
||||
|
||||
@@ -4,10 +4,10 @@ project(runner LANGUAGES CXX)
|
||||
|
||||
# The name of the executable created for the application. Change this to change
|
||||
# the on-disk name of your application.
|
||||
set(BINARY_NAME "patient_manager")
|
||||
set(BINARY_NAME "mzansi_innovation_hub")
|
||||
# The unique GTK application identifier for this application. See:
|
||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
||||
set(APPLICATION_ID "com.example.patient_manager")
|
||||
set(APPLICATION_ID "za.co.mzansiinnovationhub.mih")
|
||||
|
||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||
# versions of CMake.
|
||||
|
||||
@@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) {
|
||||
if (use_header_bar) {
|
||||
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
|
||||
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_window_set_titlebar(window, GTK_WIDGET(header_bar));
|
||||
} 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);
|
||||
|
||||
BIN
mih_ui/mih_app_flatpak/main.png
Normal file
BIN
mih_ui/mih_app_flatpak/main.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
12
mih_ui/mih_app_flatpak/za.co.mzansiinnovationhub.mih.desktop
Normal file
12
mih_ui/mih_app_flatpak/za.co.mzansiinnovationhub.mih.desktop
Normal file
@@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=MIH
|
||||
GenericName=Mzansi Innovation Hub
|
||||
Comment=Mzansi Innovation Hub official application
|
||||
Exec=mzansi_innovation_hub
|
||||
Icon=za.co.mzansiinnovationhub.mih
|
||||
Terminal=false
|
||||
Categories=Utility;
|
||||
Keywords=MIH;Mzansi;Innovation;Hub;
|
||||
StartupWMClass=mzansi_innovation_hub
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
|
||||
<id>za.co.mzansiinnovationhub.mih</id>
|
||||
|
||||
<name>MIH</name>
|
||||
<summary>Innovation tools and services for the Mzansi ecosystem</summary>
|
||||
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0</project_license>
|
||||
<developer_name>Mzansi Innovation Hub</developer_name>
|
||||
|
||||
<description>
|
||||
<p>
|
||||
MIH (Mzansi Innovation Hub) is a modern desktop application designed to provide
|
||||
innovation tools and services for users. Built with Flutter, it offers a
|
||||
high-performance, responsive interface tailored for the Linux desktop.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Access professional innovation resources</li>
|
||||
<li>Streamlined user interface for efficiency</li>
|
||||
<li>Native integration with Linux desktop environments</li>
|
||||
</ul>
|
||||
</description>
|
||||
|
||||
<launchable type="desktop-id">za.co.mzansiinnovationhub.mih.desktop</launchable>
|
||||
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>The main dashboard of the MIH application.</caption>
|
||||
<image>https://git.mzansi-innovation-hub.co.za/yaso_meth/mih-project/raw/main/screenshots/main.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<url type="homepage">https://mzansi-innovation-hub.co.za/</url>
|
||||
<url type="bugtracker">https://git.mzansi-innovation-hub.co.za/yaso_meth/mih-project/issues</url>
|
||||
|
||||
<provides>
|
||||
<binary>mzansi_innovation_hub</binary>
|
||||
</provides>
|
||||
|
||||
<releases>
|
||||
<release version="1.0.0" date="2026-02-26"/>
|
||||
</releases>
|
||||
|
||||
<content_rating type="oars-1.1"/>
|
||||
|
||||
<categories>
|
||||
<category>Utility</category>
|
||||
</categories>
|
||||
|
||||
</component>
|
||||
BIN
mih_ui/mih_app_flatpak/za.co.mzansiinnovationhub.mih.png
Normal file
BIN
mih_ui/mih_app_flatpak/za.co.mzansiinnovationhub.mih.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
55
mih_ui/mih_app_flatpak/za.co.mzansiinnovationhub.mih.yml
Normal file
55
mih_ui/mih_app_flatpak/za.co.mzansiinnovationhub.mih.yml
Normal file
@@ -0,0 +1,55 @@
|
||||
id: za.co.mzansiinnovationhub.mih
|
||||
runtime: org.freedesktop.Platform
|
||||
runtime-version: '24.08'
|
||||
sdk: org.freedesktop.Sdk
|
||||
command: mzansi_innovation_hub
|
||||
|
||||
finish-args:
|
||||
- --share=ipc
|
||||
- --share=network # Added for Internet access
|
||||
- --socket=fallback-x11
|
||||
- --socket=wayland
|
||||
- --device=dri
|
||||
# Removed --filesystem=home for better security; add back only if strictly needed.
|
||||
|
||||
modules:
|
||||
- name: mzansi-innovation-hub
|
||||
buildsystem: simple
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://git.mzansi-innovation-hub.co.za/yaso_meth/mih-project/releases/download/linux/mzansi_innovation_hub.tar.gz
|
||||
sha256: b8c383f4d43e2de36b4e6520c9745e3f8e8618bdb9ef6024ad0bf260061137a9
|
||||
# If the tarball contains a top-level folder (like 'bundle'),
|
||||
# flatpak-builder enters it automatically.
|
||||
# If it doesn't, we use the commands below to find them.
|
||||
|
||||
- type: file
|
||||
path: za.co.mzansiinnovationhub.mih.desktop
|
||||
- type: file
|
||||
path: za.co.mzansiinnovationhub.mih.metainfo.xml
|
||||
- type: file
|
||||
path: za.co.mzansiinnovationhub.mih.png
|
||||
|
||||
build-commands:
|
||||
# 1. Create the necessary directories
|
||||
- mkdir -p /app/bin /app/share/applications /app/share/icons/hicolor/256x256/apps /app/share/metainfo
|
||||
|
||||
# 2. Move EVERYTHING from your archive into /app/bin/
|
||||
# We use 'find' to move only the app-related files and avoid the metadata files
|
||||
- |
|
||||
find . -mindepth 1 -maxdepth 2 \
|
||||
! -name "*.desktop" \
|
||||
! -name "*.xml" \
|
||||
! -name "*.png" \
|
||||
! -name "*.yml" \
|
||||
-exec cp -R -t /app/bin/ {} +
|
||||
|
||||
# 3. Ensure the binary is in the right place and executable
|
||||
# If the binary ended up in a subfolder, this moves it to the top of /app/bin
|
||||
- find /app/bin -name "mzansi_innovation_hub" -type f -exec mv {} /app/bin/ \;
|
||||
- chmod +x /app/bin/mzansi_innovation_hub
|
||||
|
||||
# 4. Install Metadata (using the exact local files)
|
||||
- install -Dm644 za.co.mzansiinnovationhub.mih.desktop /app/share/applications/za.co.mzansiinnovationhub.mih.desktop
|
||||
- install -Dm644 za.co.mzansiinnovationhub.mih.png /app/share/icons/hicolor/256x256/apps/za.co.mzansiinnovationhub.mih.png
|
||||
- install -Dm644 za.co.mzansiinnovationhub.mih.metainfo.xml /app/share/metainfo/za.co.mzansiinnovationhub.mih.metainfo.xml
|
||||
@@ -369,6 +369,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.12"
|
||||
device_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -670,6 +678,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -800,6 +816,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
geoclue:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geoclue
|
||||
sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.1"
|
||||
geolocator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -824,6 +848,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.13"
|
||||
geolocator_linux:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: geolocator_linux
|
||||
sha256: d64112a205931926f4363bb6bd48f14cb38e7326833041d170615586cd143797
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.4"
|
||||
geolocator_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -896,6 +928,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
gsettings:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: gsettings
|
||||
sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.8"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: mzansi_innovation_hub
|
||||
description: ""
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
version: 1.2.5+126
|
||||
version: 1.2.6+130
|
||||
# version: 1.1.1+97 #--- Updated version for upgrader package testing
|
||||
|
||||
environment:
|
||||
@@ -12,6 +12,7 @@ dependencies:
|
||||
sdk: flutter
|
||||
flutter_web_plugins:
|
||||
sdk: flutter
|
||||
flutter_dotenv: ^6.0.0
|
||||
|
||||
cupertino_icons: ^1.0.8
|
||||
font_awesome_flutter: ^10.7.0
|
||||
@@ -28,6 +29,7 @@ dependencies:
|
||||
flutter_native_splash: ^2.4.6
|
||||
printing: ^5.13.3
|
||||
geolocator: ^14.0.1
|
||||
geolocator_linux: ^0.2.4
|
||||
table_calendar: ^3.1.2
|
||||
youtube_player_iframe: ^5.2.0
|
||||
mobile_scanner: ^7.0.1
|
||||
@@ -76,6 +78,7 @@ dev_dependencies:
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
assets:
|
||||
- .env
|
||||
- lib/mih_package_components/assets/images/
|
||||
- lib/mih_package_components/assets/fonts/
|
||||
- lib/mih_package_components/assets/images/loyalty_cards/
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user