From 69d4c73360cf9374a06de55df6cf80520520c19f Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 21 May 2025 11:03:59 +0200 Subject: [PATCH 1/3] validate username api --- backend/routers/users.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/backend/routers/users.py b/backend/routers/users.py index 5a2b2927..bb3c1311 100644 --- a/backend/routers/users.py +++ b/backend/routers/users.py @@ -66,10 +66,6 @@ async def read_all_users(search: str, session: SessionContainer = Depends(verify query = "SELECT * FROM users WHERE LOWER(email) LIKE %s OR LOWER(username) LIKE %s" search_term = f"%{search.lower()}%" # Add wildcards and lowercase cursor.execute(query, (search_term, search_term)) - # query = "SELECT * FROM users " - # query += "where email like lower('%%%s%%') " % search - # query += "or username like lower('%%%s%%')" % search - # cursor.execute(query) items = [ { "idUser": item[0], @@ -87,6 +83,19 @@ async def read_all_users(search: str, session: SessionContainer = Depends(verify db.close() return items +# Get List of all files +@router.get("/users/validate/username/{username}", tags=["MIH Users"]) +async def read_all_users(username: str, session: SessionContainer = Depends(verify_session()) ): #, session: SessionContainer = Depends(verify_session()) + db = database.dbConnection.dbAppDataConnect() + cursor = db.cursor() + query = "SELECT * FROM users WHERE LOWER(username) = %s" + # search_term = f"%{username.lower()}%" # Add wildcards and lowercase + cursor.execute(query, (username.lower(),)) + available = cursor.fetchone() is None + cursor.close() + db.close() + return {"available": available} + # Get List of all files @router.get("/user/{app_id}", tags=["MIH Users"]) async def read_users_by_app_id(app_id: str, session: SessionContainer = Depends(verify_session())): From 0b38c8e7573a7be15780555add056cbac4ccdef2 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 21 May 2025 11:57:17 +0200 Subject: [PATCH 2/3] API service added --- Frontend/lib/mih_apis/mih_user_apis.dart | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Frontend/lib/mih_apis/mih_user_apis.dart b/Frontend/lib/mih_apis/mih_user_apis.dart index 85bb12ce..5dfdeb09 100644 --- a/Frontend/lib/mih_apis/mih_user_apis.dart +++ b/Frontend/lib/mih_apis/mih_user_apis.dart @@ -12,6 +12,23 @@ import 'package:supertokens_flutter/supertokens.dart'; class MihUserApis { final baseAPI = AppEnviroment.baseApiUrl; + static Future isUsernameUnique( + String username, + BuildContext context, + ) async { + var response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/users/validate/username/$username")); + if (response.statusCode == 200) { + String body = response.body; + var jsonBody = jsonDecode(body); + + return jsonBody["available"]; + } else { + throw Exception( + "Error: isUsernameUnique status code ${response.statusCode}"); + } + } + static Future deleteAccount( String app_id, BuildContext context, From 3bc66040e1c7f739d36e301f9bd59fd9b7ce07e9 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 21 May 2025 11:57:32 +0200 Subject: [PATCH 3/3] logic to test for unique username --- .../package_tools/mih_personal_profile.dart | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart index dc3da268..464ac7d8 100644 --- a/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart +++ b/Frontend/lib/mih_packages/mzansi_profile/personal_profile/package_tools/mih_personal_profile.dart @@ -2,11 +2,13 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_user_apis.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_button.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_file_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih-app_tool_body.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_app_alert.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart'; @@ -38,13 +40,42 @@ class _MihPersonalProfileState extends State { late String oldProPicName; late String env; + void notUniqueAlert() { + showDialog( + context: context, + builder: (context) { + return MihAppAlert( + alertIcon: Icon( + Icons.warning_amber_rounded, + size: 100, + color: MzanziInnovationHub.of(context)!.theme.errorColor(), + ), + alertTitle: "Too Slow, That Username is Taken", + alertBody: const Text( + "The username you have entered is already taken by another member of Mzansi. Please choose a different username and try again.", + style: TextStyle( + fontSize: 15, + ), + ), + alertColour: MzanziInnovationHub.of(context)!.theme.errorColor(), + ); + }, + ); + } + Future submitForm() async { // print("============\nsubmiit form\n================="); if (isFieldsFilled()) { + if (widget.arguments.signedInUser.username != usernameController.text) { + bool isUsernameUnique = await MihUserApis.isUsernameUnique( + usernameController.text, context); + print("isUsernameUnique: $isUsernameUnique"); + if (isUsernameUnique == false) { + notUniqueAlert(); + return; + } + } if (oldProPicName != proPicController.text) { - // print("here 1"); - // print("Pro File Name: ${proPic!.name}"); - // print("Pro File Bytes: ${proPic!.bytes}"); await uploadSelectedFile(proPic); } await updateUserApiCall(); @@ -134,8 +165,7 @@ class _MihPersonalProfileState extends State { false, ), ); - String message = - "${widget.arguments.signedInUser.email}'s information has been updated successfully!"; + String message = "Your information has been updated successfully!"; successPopUp(message); } else { internetConnectionPopUp();