NEW: Add user and business count to about MIH
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||||
import 'package:mzansi_innovation_hub/main.dart';
|
import 'package:mzansi_innovation_hub/main.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_services/mih_business_details_services.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart';
|
import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_single_child_scroll.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_tile.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_tile.dart';
|
||||||
@@ -11,7 +12,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
|
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
|
||||||
|
import 'package:mzansi_innovation_hub/mih_services/mih_user_services.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import 'package:redacted/redacted.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
class MihInfo extends StatefulWidget {
|
class MihInfo extends StatefulWidget {
|
||||||
@@ -22,6 +25,8 @@ class MihInfo extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MihInfoState extends State<MihInfo> {
|
class _MihInfoState extends State<MihInfo> {
|
||||||
|
late Future<int> _futureUserCount;
|
||||||
|
late Future<int> _futureBusinessCount;
|
||||||
final Uri _tiktokUrl =
|
final Uri _tiktokUrl =
|
||||||
Uri.parse('https://www.tiktok.com/@mzansi.innovation.hub');
|
Uri.parse('https://www.tiktok.com/@mzansi.innovation.hub');
|
||||||
final Uri _whatsappUrl =
|
final Uri _whatsappUrl =
|
||||||
@@ -144,7 +149,7 @@ class _MihInfoState extends State<MihInfo> {
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
//fontWeight: FontWeight.bold,
|
//fontWeight: FontWeight.bold,
|
||||||
fontSize: 15,
|
fontSize: 17,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -178,7 +183,7 @@ class _MihInfoState extends State<MihInfo> {
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
//fontWeight: FontWeight.bold,
|
//fontWeight: FontWeight.bold,
|
||||||
fontSize: 15,
|
fontSize: 17,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -506,6 +511,121 @@ class _MihInfoState extends State<MihInfo> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget displayBusinessCount() {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
FutureBuilder<int>(
|
||||||
|
future: _futureBusinessCount,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
bool isLoading = true;
|
||||||
|
String userCount = "⚠️";
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
isLoading = true;
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||||
|
snapshot.hasError) {
|
||||||
|
isLoading = false;
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||||
|
snapshot.hasData) {
|
||||||
|
isLoading = false;
|
||||||
|
userCount = snapshot.data.toString();
|
||||||
|
} else {
|
||||||
|
isLoading = true;
|
||||||
|
}
|
||||||
|
return SizedBox(
|
||||||
|
child: Text(
|
||||||
|
userCount,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 23,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
).redacted(
|
||||||
|
context: context,
|
||||||
|
redact: isLoading,
|
||||||
|
configuration: RedactedConfiguration(
|
||||||
|
defaultBorderRadius: BorderRadius.circular(5),
|
||||||
|
redactedColor: MihColors.getSecondaryColor(
|
||||||
|
MzansiInnovationHub.of(context)!.theme.mode == "Dark",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Businesses",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget displayUserCount() {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
FutureBuilder<int>(
|
||||||
|
future: _futureUserCount,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
bool isLoading = true;
|
||||||
|
String userCount = "⚠️";
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
isLoading = true;
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||||
|
snapshot.hasError) {
|
||||||
|
isLoading = false;
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||||
|
snapshot.hasData) {
|
||||||
|
isLoading = false;
|
||||||
|
userCount = snapshot.data.toString();
|
||||||
|
} else {
|
||||||
|
isLoading = true;
|
||||||
|
}
|
||||||
|
return SizedBox(
|
||||||
|
child: Text(
|
||||||
|
userCount,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 23,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
).redacted(
|
||||||
|
context: context,
|
||||||
|
redact: isLoading,
|
||||||
|
configuration: RedactedConfiguration(
|
||||||
|
defaultBorderRadius: BorderRadius.circular(5),
|
||||||
|
redactedColor: MihColors.getSecondaryColor(
|
||||||
|
MzansiInnovationHub.of(context)!.theme.mode == "Dark",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Users",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_futureUserCount = MihUserServices().fetchUserCount();
|
||||||
|
_futureBusinessCount = MihBusinessDetailsServices().fetchBusinessCount();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MihPackageToolBody(
|
return MihPackageToolBody(
|
||||||
@@ -555,6 +675,30 @@ class _MihInfoState extends State<MihInfo> {
|
|||||||
// const SizedBox(
|
// const SizedBox(
|
||||||
// height: 10,
|
// height: 10,
|
||||||
// ),
|
// ),
|
||||||
|
Text(
|
||||||
|
"The MIH Family",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Wrap(
|
||||||
|
alignment: WrapAlignment.spaceEvenly,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
spacing: 25,
|
||||||
|
runSpacing: 10,
|
||||||
|
children: [
|
||||||
|
displayUserCount(),
|
||||||
|
displayBusinessCount(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.0),
|
||||||
|
child: Divider(),
|
||||||
|
),
|
||||||
|
// const SizedBox(
|
||||||
|
// height: 10,
|
||||||
|
// ),
|
||||||
Wrap(
|
Wrap(
|
||||||
alignment: WrapAlignment.start,
|
alignment: WrapAlignment.start,
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
|
|||||||
@@ -9,6 +9,21 @@ import '../mih_components/mih_pop_up_messages/mih_error_message.dart';
|
|||||||
import 'package:supertokens_flutter/http.dart' as http;
|
import 'package:supertokens_flutter/http.dart' as http;
|
||||||
|
|
||||||
class MihBusinessDetailsServices {
|
class MihBusinessDetailsServices {
|
||||||
|
Future<int> fetchBusinessCount() async {
|
||||||
|
var response = await http.get(
|
||||||
|
Uri.parse("${AppEnviroment.baseApiUrl}/business/count/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
var jsonBody = jsonDecode(response.body);
|
||||||
|
return jsonBody['count'];
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<String>> fetchAllBusinessTypes() async {
|
Future<List<String>> fetchAllBusinessTypes() async {
|
||||||
var response = await http.get(
|
var response = await http.get(
|
||||||
Uri.parse("${AppEnviroment.baseApiUrl}/business/types/"),
|
Uri.parse("${AppEnviroment.baseApiUrl}/business/types/"),
|
||||||
|
|||||||
@@ -33,6 +33,21 @@ class MihUserServices {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<int> fetchUserCount() async {
|
||||||
|
var response = await http.get(
|
||||||
|
Uri.parse("${AppEnviroment.baseApiUrl}/users/count/"),
|
||||||
|
headers: <String, String>{
|
||||||
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
var jsonBody = jsonDecode(response.body);
|
||||||
|
return jsonBody['count'];
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> createUser(
|
Future<void> createUser(
|
||||||
String email,
|
String email,
|
||||||
String app_id,
|
String app_id,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import mih_database.mihDbConnections
|
|||||||
from mih_database.mihDbObjects import User, Business, BusinessRating, BookmarkedBusiness
|
from mih_database.mihDbObjects import User, Business, BusinessRating, BookmarkedBusiness
|
||||||
from sqlalchemy import desc, or_
|
from sqlalchemy import desc, or_
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy.sql import func
|
||||||
#SuperToken Auth from front end
|
#SuperToken Auth from front end
|
||||||
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||||
from supertokens_python.recipe.session import SessionContainer
|
from supertokens_python.recipe.session import SessionContainer
|
||||||
@@ -62,6 +63,24 @@ class businessUpdateRequestV2(BaseModel):
|
|||||||
rating: str
|
rating: str
|
||||||
mission_vision: str
|
mission_vision: str
|
||||||
|
|
||||||
|
@router.get("/business/count/", tags=["MIH Business"])
|
||||||
|
async def read_business_by_business_id(): #, session: SessionContainer = Depends(verify_session())
|
||||||
|
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||||
|
dbSession = Session(dbEngine)
|
||||||
|
try:
|
||||||
|
queryResults = dbSession.query(func.count(Business.business_id)).scalar()
|
||||||
|
response_data = {"count": queryResults}
|
||||||
|
return response_data
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An error occurred during the ORM query: {e}")
|
||||||
|
if dbSession.is_active:
|
||||||
|
dbSession.rollback()
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail="Failed to retrieve records due to an internal server error."
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
dbSession.close()
|
||||||
|
|
||||||
# Get List of all files
|
# Get List of all files
|
||||||
@router.get("/business/types/", tags=["MIH Business"])
|
@router.get("/business/types/", tags=["MIH Business"])
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException, status
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
#from ..mih_database import dbConnection
|
#from ..mih_database import dbConnection
|
||||||
import mih_database
|
import mih_database
|
||||||
|
import mih_database.mihDbConnections
|
||||||
|
from mih_database.mihDbObjects import User, Business, BusinessRating, BookmarkedBusiness
|
||||||
|
from sqlalchemy import desc, or_
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy.sql import func
|
||||||
#SuperToken Auth from front end
|
#SuperToken Auth from front end
|
||||||
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||||
from supertokens_python.recipe.session import SessionContainer
|
from supertokens_python.recipe.session import SessionContainer
|
||||||
@@ -67,6 +72,26 @@ class userDeleteRequest(BaseModel):
|
|||||||
# return items[0]
|
# return items[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/users/count/", tags=["MIH Users"])
|
||||||
|
async def read_users_by_app_id(): #, session: SessionContainer = Depends(verify_session())
|
||||||
|
dbEngine = mih_database.mihDbConnections.dbAllConnect()
|
||||||
|
dbSession = Session(dbEngine)
|
||||||
|
try:
|
||||||
|
queryResults = dbSession.query(func.count(User.app_id)).scalar()
|
||||||
|
response_data = {"count": queryResults}
|
||||||
|
return response_data
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An error occurred during the ORM query: {e}")
|
||||||
|
if dbSession.is_active:
|
||||||
|
dbSession.rollback()
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail="Failed to retrieve records due to an internal server error."
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
dbSession.close()
|
||||||
|
|
||||||
# Get List of all files
|
# Get List of all files
|
||||||
@router.get("/users/search/{search}", tags=["MIH Users"])
|
@router.get("/users/search/{search}", tags=["MIH Users"])
|
||||||
async def read_all_users(search: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
async def read_all_users(search: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||||
|
|||||||
Reference in New Issue
Block a user