import { ResultAsync, errAsync, okAsync } from "neverthrow"; import type { User } from "@pkg/logic/domains/user/data"; import { user as userStore } from "$lib/global.stores"; import { rotatePasswordSC } from "./account.remote"; import { authClient } from "$lib/auth.client"; import type { Err } from "@pkg/result"; import { toast } from "svelte-sonner"; import { get } from "svelte/store"; class AccountViewModel { loading = $state(false); passwordLoading = $state(false); errorMessage = $state(null); async updateProfilePicture(imagePath: string): Promise { const result = await ResultAsync.fromPromise( authClient.updateUser({ image: imagePath }), (error): Err => ({ code: "NETWORK_ERROR", message: "Failed to update profile picture", description: "Network request failed", detail: error instanceof Error ? error.message : String(error), }), ).andThen((response) => { if (response.error) { return errAsync({ code: "API_ERROR", message: response.error.message ?? "Failed to update profile picture", description: response.error.statusText ?? "Please try again later", detail: response.error.statusText ?? "Unknown error", }); } return okAsync(response.data); }); return result.match( () => { toast.success("Profile picture updated"); return true; }, (error) => { this.errorMessage = error.message ?? "Failed to update profile picture"; toast.error(this.errorMessage, { description: error.description, }); return false; }, ); } async updateProfile(userData: { name: string; username: string; }): Promise { this.loading = true; this.errorMessage = null; const result = await ResultAsync.fromPromise( authClient.updateUser({ displayUsername: userData.username, username: userData.username, name: userData.name, }), (error): Err => ({ code: "NETWORK_ERROR", message: "Failed to update profile", description: "Network request failed", detail: error instanceof Error ? error.message : String(error), }), ).andThen((response) => { if (response.error) { return errAsync({ code: "API_ERROR", message: response.error.message ?? "Failed to update profile", description: response.error.statusText ?? "Please try again later", detail: response.error.statusText ?? "Unknown error", }); } return okAsync(response.data); }); const user = result.match( (data) => { toast.success("Profile updated successfully"); window.location.reload(); return (data as any)?.user as User | null; }, (error) => { this.errorMessage = error.message ?? "Failed to update profile"; toast.error(this.errorMessage, { description: error.description, }); return null; }, ); this.loading = false; return user; } async changePassword(password: string): Promise { this.passwordLoading = true; this.errorMessage = null; const currentUser = get(userStore); if (!currentUser?.id) { this.passwordLoading = false; this.errorMessage = "User not found"; toast.error(this.errorMessage); return false; } const result = await ResultAsync.fromPromise( rotatePasswordSC({ userId: currentUser.id, password }), (error): Err => ({ code: "NETWORK_ERROR", message: "Failed to change password", description: "Network request failed", detail: error instanceof Error ? error.message : String(error), }), ).andThen((apiResult: any) => { if (apiResult?.error) { return errAsync(apiResult.error); } return okAsync(apiResult?.data); }); const success = result.match( () => { toast.success("Password updated successfully"); return true; }, (error) => { this.errorMessage = (error.message as string) ?? "Failed to change password"; toast.error(this.errorMessage, { description: error.description, }); return false; }, ); this.passwordLoading = false; return success; } } export const accountVM = new AccountViewModel();