Commit cb5bcaa8 authored by saad's avatar saad
parents 1f5a8eb6 14287cc4
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using OneOf;
using Supabase.Gotrue.Exceptions;
......@@ -148,4 +149,65 @@ public class SupabaseAuthentication
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
private async UniTask Boot()
{
var cached = UserService.Instance.LoadFromCache();
// var cached = UserService.Instance.LoadFromCache();
TransitionManager.Instance().onTransitionCutPointReached += HideSplash;
// --- STEP 1: Network Connection Loop ---
......@@ -83,12 +83,12 @@ public class AppRouter : MonoBehaviour
if (authResult.IsT1) // No valid session found
{
if (cached != null)
{
Debug.Log("[Boot] Offline/No session, using cache.");
GoToHome();
return;
}
// if (cached != null)
// {
// Debug.Log("[Boot] Offline/No session, using cache.");
// GoToHome();
// return;
// }
GoToLogin();
return;
}
......@@ -107,16 +107,16 @@ public class AppRouter : MonoBehaviour
error =>
{
// If profile fetch fails but we have a cache, let them in
if (cached != null)
{
Debug.LogWarning($"[Boot] Profile fetch failed, falling back to cache.");
GoToHome();
}
else
{
// if (cached != null)
// {
// Debug.LogWarning($"[Boot] Profile fetch failed, falling back to cache.");
// GoToHome();
// }
// else
// {
Debug.LogError($"[Boot] Critical load error: {error}");
GoToLogin();
}
// }
}
);
}
......
......@@ -192,7 +192,8 @@ public class UserService
public async UniTask<OneOf<UserResult, ErrorResult>> UpdateProfile(
string username,
int grade,
int term)
int term,
int curriculum)
{
try
{
......@@ -205,6 +206,7 @@ public class UserService
if (username != null) update.Username = username;
update.Grade = grade;
update.Term = term;
update.Curriculum = curriculum;
await client
.From<User>()
......
......@@ -3,18 +3,9 @@ using UnityEngine;
public class SupabaseTester : MonoBehaviour
{
[SerializeField] private SupabaseAuthentication supabaseAuthentication;
[ContextMenu("Sign In")]
public void SignIn()
[ContextMenu("Delete account")]
public void DeleteAccount()
{
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
SetPlayButtonsEnabled(enough);
},
_ => SetPlayButtonsEnabled(false),
curriculumId: 1,
curriculumId: user.Curriculum,
gradeId: user.Grade,
termId: user.Term
));
......
......@@ -12,6 +12,7 @@ public class ProfileController : MonoBehaviour
private TextField UsernameLabel;
private DropdownField Grade;
private DropdownField Term;
private DropdownField Curriculum;
private CustomSwitch musicSwitch;
private CustomSwitch sfxSwitch;
......@@ -29,6 +30,7 @@ public class ProfileController : MonoBehaviour
UsernameLabel = root.Q<TextField>("Name");
Grade = root.Q<DropdownField>("Grade");
Term = root.Q<DropdownField>("TermDrop");
Curriculum = root.Q<DropdownField>("Curriculum");
musicSwitch = root.Q<CustomSwitch>("MusicSwitch");
sfxSwitch = root.Q<CustomSwitch>("SFXSwitch");
......@@ -51,17 +53,19 @@ public class ProfileController : MonoBehaviour
UsernameLabel.value = user.Username;
Grade.value = EducationManager.GetGradeName(user.Grade);
Term.value = EducationManager.GetTermName(user.Term);
Curriculum.value = EducationManager.GetCurriculumName(user.Curriculum);
}
private async void UpdateProfile()
{
int gradeId = EducationManager.GetGradeId(Grade.value);
int termId = EducationManager.GetTermId(Term.value);
int curriculumId = EducationManager.GetCurriculumId(Curriculum.value);
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");
return;
......@@ -70,7 +74,8 @@ public class ProfileController : MonoBehaviour
await UserService.Instance.UpdateProfile(
username: UsernameLabel.value,
grade: gradeId,
term: termId
term: termId,
curriculum: curriculumId
);
}
......
......@@ -25,8 +25,15 @@
</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: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: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:Label text="🎓" name="icon" class="emoji" style="padding-left: 0; padding-top: 0; padding-right: 0; padding-bottom: 0; font-size: 50px;"/>
</ui:VisualElement>
......
......@@ -232,6 +232,50 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::LeaderboardController
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
GameObject:
m_ObjectHideFlags: 0
......@@ -669,6 +713,7 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::HomeController
mainMenuDocument: {fileID: 1455761156}
challengePrefab: {fileID: 6263250232599778082, guid: adacfd07019fd8f4bbd5a9347da9f201, type: 3}
minQuestionsPerType: 5
--- !u!4 &1841206267
Transform:
m_ObjectHideFlags: 0
......@@ -724,3 +769,4 @@ SceneRoots:
m_Roots:
- {fileID: 2035341440}
- {fileID: 1450206974}
- {fileID: 806296027}
......@@ -8,7 +8,7 @@ PlayerSettings:
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
AndroidEnableSustainedPerformanceMode: 0
defaultScreenOrientation: 4
defaultScreenOrientation: 0
targetDevice: 2
useOnDemandResources: 0
accelerometerFrequency: 60
......@@ -70,7 +70,7 @@ PlayerSettings:
preserveFramebufferAlpha: 0
disableDepthAndStencilBuffers: 0
androidStartInFullscreen: 1
androidRenderOutsideSafeArea: 1
androidRenderOutsideSafeArea: 0
androidUseSwappy: 0
androidDisplayOptions: 1
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