Commit cb5bcaa8 authored by saad's avatar saad
parents 1f5a8eb6 14287cc4
using System; using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using OneOf; using OneOf;
using Supabase.Gotrue.Exceptions; using Supabase.Gotrue.Exceptions;
...@@ -148,4 +149,65 @@ public class SupabaseAuthentication ...@@ -148,4 +149,65 @@ public class SupabaseAuthentication
IsLoading = false; IsLoading = false;
} }
} }
public async UniTask<OneOf<Success, string>> DeleteAccount()
{
try
{
IsLoading = true;
var client = SupabaseManager.Instance.Supabase();
if (client == null) return "Supabase not initialized";
// 1. Ensure we have a valid session
if (client.Auth.CurrentSession == null)
return "No active session found. Please log in again.";
// 2. Refresh the session to ensure the JWT isn't expired
// This is the most common cause of 401 errors
try
{
await client.Auth.RefreshSession();
}
catch (Exception)
{
return "Session expired. Please log in again.";
}
// 3. Explicitly create the Authorization header
var headers = new Dictionary<string, string>
{
{ "Authorization", $"Bearer {client.Auth.CurrentSession.AccessToken}" }
};
var options = new Supabase.Functions.Client.InvokeFunctionOptions();
options.Headers = headers;
// 4. Call the Edge Function with explicit headers
// Pass 'null' for the body if you don't need to send extra data
await client.Functions.Invoke("delete-self", client.Auth.CurrentSession.AccessToken, options);
Debug.Log("[Auth] Account deleted successfully.");
// 5. Cleanup local state
AppRouter.Logout();
return new Success();
}
catch (GotrueException ex)
{
Debug.LogError($"[Auth Delete] {ex.Message}");
return ex.Message;
}
catch (Exception ex)
{
// If the function returns a 400 or 500, it often lands here
Debug.LogError($"[Auth Delete] {ex.Message}");
return "Server error during deletion. Please try again later.";
}
finally
{
IsLoading = false;
}
}
} }
\ No newline at end of file
...@@ -70,7 +70,7 @@ public class AppRouter : MonoBehaviour ...@@ -70,7 +70,7 @@ public class AppRouter : MonoBehaviour
private async UniTask Boot() private async UniTask Boot()
{ {
var cached = UserService.Instance.LoadFromCache(); // var cached = UserService.Instance.LoadFromCache();
TransitionManager.Instance().onTransitionCutPointReached += HideSplash; TransitionManager.Instance().onTransitionCutPointReached += HideSplash;
// --- STEP 1: Network Connection Loop --- // --- STEP 1: Network Connection Loop ---
...@@ -83,12 +83,12 @@ public class AppRouter : MonoBehaviour ...@@ -83,12 +83,12 @@ public class AppRouter : MonoBehaviour
if (authResult.IsT1) // No valid session found if (authResult.IsT1) // No valid session found
{ {
if (cached != null) // if (cached != null)
{ // {
Debug.Log("[Boot] Offline/No session, using cache."); // Debug.Log("[Boot] Offline/No session, using cache.");
GoToHome(); // GoToHome();
return; // return;
} // }
GoToLogin(); GoToLogin();
return; return;
} }
...@@ -107,16 +107,16 @@ public class AppRouter : MonoBehaviour ...@@ -107,16 +107,16 @@ public class AppRouter : MonoBehaviour
error => error =>
{ {
// If profile fetch fails but we have a cache, let them in // If profile fetch fails but we have a cache, let them in
if (cached != null) // if (cached != null)
{ // {
Debug.LogWarning($"[Boot] Profile fetch failed, falling back to cache."); // Debug.LogWarning($"[Boot] Profile fetch failed, falling back to cache.");
GoToHome(); // GoToHome();
} // }
else // else
{ // {
Debug.LogError($"[Boot] Critical load error: {error}"); Debug.LogError($"[Boot] Critical load error: {error}");
GoToLogin(); GoToLogin();
} // }
} }
); );
} }
......
...@@ -192,7 +192,8 @@ public class UserService ...@@ -192,7 +192,8 @@ public class UserService
public async UniTask<OneOf<UserResult, ErrorResult>> UpdateProfile( public async UniTask<OneOf<UserResult, ErrorResult>> UpdateProfile(
string username, string username,
int grade, int grade,
int term) int term,
int curriculum)
{ {
try try
{ {
...@@ -205,6 +206,7 @@ public class UserService ...@@ -205,6 +206,7 @@ public class UserService
if (username != null) update.Username = username; if (username != null) update.Username = username;
update.Grade = grade; update.Grade = grade;
update.Term = term; update.Term = term;
update.Curriculum = curriculum;
await client await client
.From<User>() .From<User>()
......
...@@ -3,18 +3,9 @@ using UnityEngine; ...@@ -3,18 +3,9 @@ using UnityEngine;
public class SupabaseTester : MonoBehaviour public class SupabaseTester : MonoBehaviour
{ {
[SerializeField] private SupabaseAuthentication supabaseAuthentication; [ContextMenu("Delete account")]
public void DeleteAccount()
[ContextMenu("Sign In")]
public void SignIn()
{ {
supabaseAuthentication.LogIn("test@gmail.com", "test098"); SupabaseAuthentication.Instance.DeleteAccount();
} }
[ContextMenu("Finish Game")]
public void FinishGame()
{
GameHistoryService.Instance.AddGame("CS", 3200, DateTime.Now, DateTime.Today);
}
} }
...@@ -95,7 +95,7 @@ public class HomeController : MonoBehaviour ...@@ -95,7 +95,7 @@ public class HomeController : MonoBehaviour
SetPlayButtonsEnabled(enough); SetPlayButtonsEnabled(enough);
}, },
_ => SetPlayButtonsEnabled(false), _ => SetPlayButtonsEnabled(false),
curriculumId: 1, curriculumId: user.Curriculum,
gradeId: user.Grade, gradeId: user.Grade,
termId: user.Term termId: user.Term
)); ));
......
...@@ -12,6 +12,7 @@ public class ProfileController : MonoBehaviour ...@@ -12,6 +12,7 @@ public class ProfileController : MonoBehaviour
private TextField UsernameLabel; private TextField UsernameLabel;
private DropdownField Grade; private DropdownField Grade;
private DropdownField Term; private DropdownField Term;
private DropdownField Curriculum;
private CustomSwitch musicSwitch; private CustomSwitch musicSwitch;
private CustomSwitch sfxSwitch; private CustomSwitch sfxSwitch;
...@@ -29,6 +30,7 @@ public class ProfileController : MonoBehaviour ...@@ -29,6 +30,7 @@ public class ProfileController : MonoBehaviour
UsernameLabel = root.Q<TextField>("Name"); UsernameLabel = root.Q<TextField>("Name");
Grade = root.Q<DropdownField>("Grade"); Grade = root.Q<DropdownField>("Grade");
Term = root.Q<DropdownField>("TermDrop"); Term = root.Q<DropdownField>("TermDrop");
Curriculum = root.Q<DropdownField>("Curriculum");
musicSwitch = root.Q<CustomSwitch>("MusicSwitch"); musicSwitch = root.Q<CustomSwitch>("MusicSwitch");
sfxSwitch = root.Q<CustomSwitch>("SFXSwitch"); sfxSwitch = root.Q<CustomSwitch>("SFXSwitch");
...@@ -51,17 +53,19 @@ public class ProfileController : MonoBehaviour ...@@ -51,17 +53,19 @@ public class ProfileController : MonoBehaviour
UsernameLabel.value = user.Username; UsernameLabel.value = user.Username;
Grade.value = EducationManager.GetGradeName(user.Grade); Grade.value = EducationManager.GetGradeName(user.Grade);
Term.value = EducationManager.GetTermName(user.Term); Term.value = EducationManager.GetTermName(user.Term);
Curriculum.value = EducationManager.GetCurriculumName(user.Curriculum);
} }
private async void UpdateProfile() private async void UpdateProfile()
{ {
int gradeId = EducationManager.GetGradeId(Grade.value); int gradeId = EducationManager.GetGradeId(Grade.value);
int termId = EducationManager.GetTermId(Term.value); int termId = EducationManager.GetTermId(Term.value);
int curriculumId = EducationManager.GetCurriculumId(Curriculum.value);
print("Updating profile with: " + UsernameLabel.value + ", Grade: " + gradeId + ", Term: " + termId); print("Updating profile with: " + UsernameLabel.value + ", Grade: " + gradeId + ", Term: " + termId);
if (gradeId < 0 || termId < 0) if (gradeId < 0 || termId < 0 || curriculumId < 0)
{ {
Debug.LogWarning("[Profile] Invalid grade or term selection"); Debug.LogWarning("[Profile] Invalid grade or term selection");
return; return;
...@@ -70,7 +74,8 @@ public class ProfileController : MonoBehaviour ...@@ -70,7 +74,8 @@ public class ProfileController : MonoBehaviour
await UserService.Instance.UpdateProfile( await UserService.Instance.UpdateProfile(
username: UsernameLabel.value, username: UsernameLabel.value,
grade: gradeId, grade: gradeId,
term: termId term: termId,
curriculum: curriculumId
); );
} }
......
...@@ -25,8 +25,15 @@ ...@@ -25,8 +25,15 @@
</ui:VisualElement> </ui:VisualElement>
<ui:TextField label="" placeholder-text="" name="Name" hide-placeholder-on-focus="true" value="يوسف" class="text-bold" style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; width: auto; flex-grow: 1; -unity-text-align: upper-right; font-size: 40px; color: rgb(0, 0, 0); border-top-width: 0; border-right-width: 0; border-bottom-width: 0; border-left-width: 0; height: 100%; border-top-left-radius: 25px; border-top-right-radius: 25px; border-bottom-right-radius: 25px; border-bottom-left-radius: 25px; flex-direction: column-reverse; display: flex;"/> <ui:TextField label="" placeholder-text="" name="Name" hide-placeholder-on-focus="true" value="يوسف" class="text-bold" style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; width: auto; flex-grow: 1; -unity-text-align: upper-right; font-size: 40px; color: rgb(0, 0, 0); border-top-width: 0; border-right-width: 0; border-bottom-width: 0; border-left-width: 0; height: 100%; border-top-left-radius: 25px; border-top-right-radius: 25px; border-bottom-right-radius: 25px; border-bottom-left-radius: 25px; flex-direction: column-reverse; display: flex;"/>
</ui:VisualElement> </ui:VisualElement>
<ui:Button text="" name="Button" class="row-btn" style="display: flex;">
<ui:VisualElement style="flex-grow: 0; height: 100px; width: 100px; background-color: rgba(0, 137, 107, 0.15); align-items: center; justify-content: center; margin-right: 0; margin-left: 30px; border-top-left-radius: 25px; border-top-right-radius: 25px; border-bottom-right-radius: 25px; border-bottom-left-radius: 25px;">
<ui:Label text="🎓" name="icon" class="emoji" style="padding-left: 0; padding-top: 0; padding-right: 0; padding-bottom: 0; font-size: 50px;"/>
</ui:VisualElement>
<ui:Label text="النظام التعليمي" name="" class="text-bold-black" style="color: rgb(66, 66, 66);"/>
<ui:DropdownField label="" choices="مصري عربي,مصري لغات" name="Curriculum" style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; position: absolute; flex-grow: 0; height: 100%; width: 100%; font-size: 26px; -unity-font-definition: url(&quot;project://database/Assets/ALArcade/Hakwaty%20Font/TSHakwaty-DemiBold.otf?fileID=12800000&amp;guid=566b773a07b3d064aa1f4c6ef7b6f6fa&amp;type=3#TSHakwaty-DemiBold&quot;); -unity-text-generator: advanced; color: rgb(48, 48, 208); display: flex; opacity: 1;"/>
</ui:Button>
<ui:VisualElement name="Line" style="flex-grow: 0; width: 100%; background-color: rgba(0, 0, 0, 0.1); height: 2px; margin-top: 25px; margin-bottom: 25px;"/> <ui:VisualElement name="Line" style="flex-grow: 0; width: 100%; background-color: rgba(0, 0, 0, 0.1); height: 2px; margin-top: 25px; margin-bottom: 25px;"/>
<ui:Button text="" name="" class="row-btn" style="display: flex;"> <ui:Button text="" name="Button" class="row-btn" style="display: flex;">
<ui:VisualElement style="flex-grow: 0; height: 100px; width: 100px; background-color: rgba(0, 137, 107, 0.15); align-items: center; justify-content: center; margin-right: 0; margin-left: 30px; border-top-left-radius: 25px; border-top-right-radius: 25px; border-bottom-right-radius: 25px; border-bottom-left-radius: 25px;"> <ui:VisualElement style="flex-grow: 0; height: 100px; width: 100px; background-color: rgba(0, 137, 107, 0.15); align-items: center; justify-content: center; margin-right: 0; margin-left: 30px; border-top-left-radius: 25px; border-top-right-radius: 25px; border-bottom-right-radius: 25px; border-bottom-left-radius: 25px;">
<ui:Label text="🎓" name="icon" class="emoji" style="padding-left: 0; padding-top: 0; padding-right: 0; padding-bottom: 0; font-size: 50px;"/> <ui:Label text="🎓" name="icon" class="emoji" style="padding-left: 0; padding-top: 0; padding-right: 0; padding-bottom: 0; font-size: 50px;"/>
</ui:VisualElement> </ui:VisualElement>
......
...@@ -232,6 +232,50 @@ MonoBehaviour: ...@@ -232,6 +232,50 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: Assembly-CSharp::LeaderboardController m_EditorClassIdentifier: Assembly-CSharp::LeaderboardController
leaderboardDocument: {fileID: 1455761156} leaderboardDocument: {fileID: 1455761156}
--- !u!1 &806296025
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 806296027}
- component: {fileID: 806296026}
m_Layer: 0
m_Name: SupabaseTester
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &806296026
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 806296025}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 87e81a7f39f4c68ea8e8ab8d8462bd14, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::SupabaseTester
--- !u!4 &806296027
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 806296025}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 540, y: 1199.9999, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &918718235 --- !u!1 &918718235
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -669,6 +713,7 @@ MonoBehaviour: ...@@ -669,6 +713,7 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::HomeController m_EditorClassIdentifier: Assembly-CSharp::HomeController
mainMenuDocument: {fileID: 1455761156} mainMenuDocument: {fileID: 1455761156}
challengePrefab: {fileID: 6263250232599778082, guid: adacfd07019fd8f4bbd5a9347da9f201, type: 3} challengePrefab: {fileID: 6263250232599778082, guid: adacfd07019fd8f4bbd5a9347da9f201, type: 3}
minQuestionsPerType: 5
--- !u!4 &1841206267 --- !u!4 &1841206267
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -724,3 +769,4 @@ SceneRoots: ...@@ -724,3 +769,4 @@ SceneRoots:
m_Roots: m_Roots:
- {fileID: 2035341440} - {fileID: 2035341440}
- {fileID: 1450206974} - {fileID: 1450206974}
- {fileID: 806296027}
...@@ -8,7 +8,7 @@ PlayerSettings: ...@@ -8,7 +8,7 @@ PlayerSettings:
AndroidProfiler: 0 AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0 AndroidFilterTouchesWhenObscured: 0
AndroidEnableSustainedPerformanceMode: 0 AndroidEnableSustainedPerformanceMode: 0
defaultScreenOrientation: 4 defaultScreenOrientation: 0
targetDevice: 2 targetDevice: 2
useOnDemandResources: 0 useOnDemandResources: 0
accelerometerFrequency: 60 accelerometerFrequency: 60
...@@ -70,7 +70,7 @@ PlayerSettings: ...@@ -70,7 +70,7 @@ PlayerSettings:
preserveFramebufferAlpha: 0 preserveFramebufferAlpha: 0
disableDepthAndStencilBuffers: 0 disableDepthAndStencilBuffers: 0
androidStartInFullscreen: 1 androidStartInFullscreen: 1
androidRenderOutsideSafeArea: 1 androidRenderOutsideSafeArea: 0
androidUseSwappy: 0 androidUseSwappy: 0
androidDisplayOptions: 1 androidDisplayOptions: 1
androidBlitType: 0 androidBlitType: 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment