Browse Source
			
			
			
			
				
		- Migrated all notification calls in AccountViewView.vue to use a notify helper initialized in mounted(), ensuring this.$notify is available and preventing runtime errors. - Removed NotificationMixin and $notifyHelper usage; restored and standardized notify helper pattern. - Migrated all database and platform service operations to use PlatformServiceMixin ultra-concise methods ($accountSettings, $saveSettings, $saveUserSettings, etc.). - Cleaned up unused imports and code related to previous notification and database patterns. - Ensured all linter errors and warnings are resolved in both AccountViewView.vue and notification utility files.web-serve-fix
				 2 changed files with 325 additions and 238 deletions
			
			
		@ -0,0 +1,223 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * ProfileService - Handles user profile operations and API calls | 
				
			||||
 | 
					 * Extracted from AccountViewView.vue to improve separation of concerns | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { AxiosInstance, AxiosError } from "axios"; | 
				
			||||
 | 
					import { UserProfile } from "@/libs/partnerServer"; | 
				
			||||
 | 
					import { UserProfileResponse } from "@/interfaces/accountView"; | 
				
			||||
 | 
					import { getHeaders, errorStringForLog } from "@/libs/endorserServer"; | 
				
			||||
 | 
					import { handleApiError } from "./api"; | 
				
			||||
 | 
					import { logger } from "@/utils/logger"; | 
				
			||||
 | 
					import { ACCOUNT_VIEW_CONSTANTS } from "@/constants/accountView"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * Profile data interface | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					export interface ProfileData { | 
				
			||||
 | 
					  description: string; | 
				
			||||
 | 
					  latitude: number; | 
				
			||||
 | 
					  longitude: number; | 
				
			||||
 | 
					  includeLocation: boolean; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * Profile service class | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					export class ProfileService { | 
				
			||||
 | 
					  private axios: AxiosInstance; | 
				
			||||
 | 
					  private partnerApiServer: string; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  constructor(axios: AxiosInstance, partnerApiServer: string) { | 
				
			||||
 | 
					    this.axios = axios; | 
				
			||||
 | 
					    this.partnerApiServer = partnerApiServer; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * Load user profile from the server | 
				
			||||
 | 
					   * @param activeDid - The user's DID | 
				
			||||
 | 
					   * @returns ProfileData or null if profile doesn't exist | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  async loadProfile(activeDid: string): Promise<ProfileData | null> { | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					      const headers = await getHeaders(activeDid); | 
				
			||||
 | 
					      const response = await this.axios.get<UserProfileResponse>( | 
				
			||||
 | 
					        `${this.partnerApiServer}/api/partner/userProfileForIssuer/${activeDid}`, | 
				
			||||
 | 
					        { headers }, | 
				
			||||
 | 
					      ); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      if (response.status === 200) { | 
				
			||||
 | 
					        const data = response.data.data; | 
				
			||||
 | 
					        const profileData: ProfileData = { | 
				
			||||
 | 
					          description: data.description || "", | 
				
			||||
 | 
					          latitude: data.locLat || 0, | 
				
			||||
 | 
					          longitude: data.locLon || 0, | 
				
			||||
 | 
					          includeLocation: !!(data.locLat && data.locLon), | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					        return profileData; | 
				
			||||
 | 
					      } else { | 
				
			||||
 | 
					        throw new Error(ACCOUNT_VIEW_CONSTANTS.ERRORS.UNABLE_TO_LOAD_PROFILE); | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					    } catch (error) { | 
				
			||||
 | 
					      if (this.isApiError(error) && error.response?.status === 404) { | 
				
			||||
 | 
					        // Profile doesn't exist yet - this is normal
 | 
				
			||||
 | 
					        return null; | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      logger.error("Error loading profile:", errorStringForLog(error)); | 
				
			||||
 | 
					      handleApiError(error as AxiosError, "/api/partner/userProfileForIssuer"); | 
				
			||||
 | 
					      return null; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * Save user profile to the server | 
				
			||||
 | 
					   * @param activeDid - The user's DID | 
				
			||||
 | 
					   * @param profileData - The profile data to save | 
				
			||||
 | 
					   * @returns true if successful, false otherwise | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  async saveProfile( | 
				
			||||
 | 
					    activeDid: string, | 
				
			||||
 | 
					    profileData: ProfileData, | 
				
			||||
 | 
					  ): Promise<boolean> { | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					      const headers = await getHeaders(activeDid); | 
				
			||||
 | 
					      const payload: UserProfile = { | 
				
			||||
 | 
					        description: profileData.description, | 
				
			||||
 | 
					        issuerDid: activeDid, | 
				
			||||
 | 
					      }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      // Add location data if location is included
 | 
				
			||||
 | 
					      if ( | 
				
			||||
 | 
					        profileData.includeLocation && | 
				
			||||
 | 
					        profileData.latitude && | 
				
			||||
 | 
					        profileData.longitude | 
				
			||||
 | 
					      ) { | 
				
			||||
 | 
					        payload.locLat = profileData.latitude; | 
				
			||||
 | 
					        payload.locLon = profileData.longitude; | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      const response = await this.axios.post( | 
				
			||||
 | 
					        `${this.partnerApiServer}/api/partner/userProfile`, | 
				
			||||
 | 
					        payload, | 
				
			||||
 | 
					        { headers }, | 
				
			||||
 | 
					      ); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      if (response.status === 200) { | 
				
			||||
 | 
					        return true; | 
				
			||||
 | 
					      } else { | 
				
			||||
 | 
					        throw new Error(ACCOUNT_VIEW_CONSTANTS.ERRORS.PROFILE_NOT_SAVED); | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					    } catch (error) { | 
				
			||||
 | 
					      logger.error("Error saving profile:", errorStringForLog(error)); | 
				
			||||
 | 
					      handleApiError(error as AxiosError, "/api/partner/userProfile"); | 
				
			||||
 | 
					      return false; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * Delete user profile from the server | 
				
			||||
 | 
					   * @param activeDid - The user's DID | 
				
			||||
 | 
					   * @returns true if successful, false otherwise | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  async deleteProfile(activeDid: string): Promise<boolean> { | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					      const headers = await getHeaders(activeDid); | 
				
			||||
 | 
					      const response = await this.axios.delete( | 
				
			||||
 | 
					        `${this.partnerApiServer}/api/partner/userProfile`, | 
				
			||||
 | 
					        { headers }, | 
				
			||||
 | 
					      ); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      if (response.status === 200) { | 
				
			||||
 | 
					        return true; | 
				
			||||
 | 
					      } else { | 
				
			||||
 | 
					        throw new Error(ACCOUNT_VIEW_CONSTANTS.ERRORS.PROFILE_NOT_DELETED); | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					    } catch (error) { | 
				
			||||
 | 
					      logger.error("Error deleting profile:", errorStringForLog(error)); | 
				
			||||
 | 
					      handleApiError(error as AxiosError, "/api/partner/userProfile"); | 
				
			||||
 | 
					      return false; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * Update profile location | 
				
			||||
 | 
					   * @param profileData - Current profile data | 
				
			||||
 | 
					   * @param latitude - New latitude | 
				
			||||
 | 
					   * @param longitude - New longitude | 
				
			||||
 | 
					   * @returns Updated profile data | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  updateProfileLocation( | 
				
			||||
 | 
					    profileData: ProfileData, | 
				
			||||
 | 
					    latitude: number, | 
				
			||||
 | 
					    longitude: number, | 
				
			||||
 | 
					  ): ProfileData { | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					      ...profileData, | 
				
			||||
 | 
					      latitude, | 
				
			||||
 | 
					      longitude, | 
				
			||||
 | 
					      includeLocation: true, | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * Toggle location inclusion in profile | 
				
			||||
 | 
					   * @param profileData - Current profile data | 
				
			||||
 | 
					   * @returns Updated profile data | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  toggleProfileLocation(profileData: ProfileData): ProfileData { | 
				
			||||
 | 
					    const includeLocation = !profileData.includeLocation; | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					      ...profileData, | 
				
			||||
 | 
					      latitude: includeLocation ? profileData.latitude : 0, | 
				
			||||
 | 
					      longitude: includeLocation ? profileData.longitude : 0, | 
				
			||||
 | 
					      includeLocation, | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * Clear profile location | 
				
			||||
 | 
					   * @param profileData - Current profile data | 
				
			||||
 | 
					   * @returns Updated profile data | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  clearProfileLocation(profileData: ProfileData): ProfileData { | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					      ...profileData, | 
				
			||||
 | 
					      latitude: 0, | 
				
			||||
 | 
					      longitude: 0, | 
				
			||||
 | 
					      includeLocation: false, | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * Reset profile to default state | 
				
			||||
 | 
					   * @returns Default profile data | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  getDefaultProfile(): ProfileData { | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					      description: "", | 
				
			||||
 | 
					      latitude: 0, | 
				
			||||
 | 
					      longitude: 0, | 
				
			||||
 | 
					      includeLocation: false, | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * Type guard for API errors | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  private isApiError( | 
				
			||||
 | 
					    error: unknown, | 
				
			||||
 | 
					  ): error is { response?: { status?: number } } { | 
				
			||||
 | 
					    return typeof error === "object" && error !== null && "response" in error; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * Factory function to create a ProfileService instance | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					export function createProfileService( | 
				
			||||
 | 
					  axios: AxiosInstance, | 
				
			||||
 | 
					  partnerApiServer: string, | 
				
			||||
 | 
					): ProfileService { | 
				
			||||
 | 
					  return new ProfileService(axios, partnerApiServer); | 
				
			||||
 | 
					} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue