import { ref } from 'vue' import { fetchQueueByProfileId, updateQueueByProfileId, fetchMembershipsByProfileId, fetchResponsesByProfileId, fetchProfileByProfileId, Chatter, StonkAlert, loginUser, } from '../services/index.js' import { surveyFactory } from '../utils/index.js' /** * Logged in profile state manager * Sort of a util and service hybrid */ class Login { constructor() { this._loading = ref(true) // Profile entity instance for self this._profile = null // Make reactive with vue observer this.id = ref(null) this.groupings = [] this.queue = [] this.responses = [] this.tags = [] this.toaster = null this.chatter = null } get isLoading() { return this._loading.value } /** * Track login separate from complete-ess * so a user can login but attached profile * can forward to survey * @returns {boolean} */ get isLoggedIn() { return this.id.value != null && this.isLoading == false } /** * Combine questions retrieved from the database and * questions defined in out lang file and * copare to responses stored * @returns {boolean} */ get isComplete() { return ( this.responses.length == surveyFactory.questionsFromDb.length && surveyFactory.questionsFromDb.length > 0 ) } /** * Check that some responses are set * @returns {boolean} */ get hasResponses() { return this.responses.length && this.responses.length > 0 } /** * Groupings pending pair */ get pendingGroupings() { return this.groupings.filter(grouping => grouping.is_paired == false) } get pairedGroupings() { return this.groupings.filter(grouping => grouping.is_paired == true) } /** * Login a profile by id number * @param {number} profileId * @returns {number} stored reactive id */ async login(email, password) { // First check if profile exists console.warn('[Login Service warn]: Logging in:', email) const res = await loginUser({ email, password }) if (res) { console.warn(`[Login Service warn] Logging in: Succeeded!`) } return res } async setup(profileId, cb) { // TODO: You can probably use this call to get responses, groupings and tags this._loading.value = true this._profile = await fetchProfileByProfileId(profileId) this.id.value = this._profile.profile_id if (!this.id.value) { console.error( `[Login Service error]: No profile found for profile_id: ${profileId}`, ) } // Then grab groupings and queue for display await this.getGroupings() await this.getQueue() // Then hook into chat services try { await this.setupChatter() console.warn( `[Login Service warn]: ${profileId} subscribed to:`, this.chatter.subscriptions, ) } catch (err) { console.error(err) } // Finally setup notifications and sse handling this.setupToaster(cb) console.warn('[Login Service warn]: Login SUCCESSFUL') this._loading.value = false return this.id.value } logout() { console.warn('[Login Service warn]: Logging out:', this.id.value) this.id.value = null if (this.toaster) { this.toaster.stop() } if (this.chatter) { this.chatter.stop() } } async getTags() { try { const tags = [] this.setTags(tags) } catch (err) { console.error(`[Login Service]: ${err}`) } } setTags(tags) { this.tags = tags } async getResponses() { try { const responseList = await fetchResponsesByProfileId(this.id.value) this.setResponses(responseList) } catch (err) { console.error(`[Login Service]: ${err}`) } } setResponses(responses) { this.responses = responses } async getGroupings() { try { this.groupings = await fetchMembershipsByProfileId(this.id.value) } catch (err) { console.error(`[Login Service]: ${err}`) } } async getQueue() { this.queue = await fetchQueueByProfileId(this.id.value) } async updateQueue(profileId, targetId, reinsert) { this.queue = await updateQueueByProfileId(profileId, targetId, reinsert) } /** * For push notifications and chat */ setupToaster(waveCb) { this.toaster = new StonkAlert(this.id.value, waveCb) } async setupChatter() { this.chatter = new Chatter() // Use the reactive id object await this.chatter.setup(this.id.value, this.groupings) } } const currentProfile = new Login() export { currentProfile, Login }